Skip to content

Commit 3ed9bbe

Browse files
authoredJun 1, 2022
Rollup merge of #95594 - the8472:raw_slice_methods, r=yaahc
Additional `*mut [T]` methods Split out from #94247 This adds the following methods to raw slices that already exist on regular slices * `*mut [T]::is_empty` * `*mut [T]::split_at_mut` * `*mut [T]::split_at_mut_unchecked` These methods reduce the amount of unsafe code needed to migrate `ChunksMut` and related iterators to raw slices (#94247) r? `@m-ou-se`
2 parents b5a2d27 + b0ca46e commit 3ed9bbe

File tree

1 file changed

+118
-1
lines changed

1 file changed

+118
-1
lines changed
 

‎library/core/src/ptr/mut_ptr.rs

+118-1
Original file line numberDiff line numberDiff line change
@@ -1622,6 +1622,122 @@ impl<T> *mut [T] {
16221622
metadata(self)
16231623
}
16241624

1625+
/// Returns `true` if the raw slice has a length of 0.
1626+
///
1627+
/// # Examples
1628+
///
1629+
/// ```
1630+
/// #![feature(slice_ptr_len)]
1631+
///
1632+
/// let mut a = [1, 2, 3];
1633+
/// let ptr = &mut a as *mut [_];
1634+
/// assert!(!ptr.is_empty());
1635+
/// ```
1636+
#[inline(always)]
1637+
#[unstable(feature = "slice_ptr_len", issue = "71146")]
1638+
#[rustc_const_unstable(feature = "const_slice_ptr_len", issue = "71146")]
1639+
pub const fn is_empty(self) -> bool {
1640+
self.len() == 0
1641+
}
1642+
1643+
/// Divides one mutable raw slice into two at an index.
1644+
///
1645+
/// The first will contain all indices from `[0, mid)` (excluding
1646+
/// the index `mid` itself) and the second will contain all
1647+
/// indices from `[mid, len)` (excluding the index `len` itself).
1648+
///
1649+
/// # Panics
1650+
///
1651+
/// Panics if `mid > len`.
1652+
///
1653+
/// # Safety
1654+
///
1655+
/// `mid` must be [in-bounds] of the underlying [allocated object].
1656+
/// Which means `self` must be dereferenceable and span a single allocation
1657+
/// that is at least `mid * size_of::<T>()` bytes long. Not upholding these
1658+
/// requirements is *[undefined behavior]* even if the resulting pointers are not used.
1659+
///
1660+
/// Since `len` being in-bounds it is not a safety invariant of `*mut [T]` the
1661+
/// safety requirements of this method are the same as for [`split_at_mut_unchecked`].
1662+
/// The explicit bounds check is only as useful as `len` is correct.
1663+
///
1664+
/// [`split_at_mut_unchecked`]: #method.split_at_mut_unchecked
1665+
/// [in-bounds]: #method.add
1666+
/// [allocated object]: crate::ptr#allocated-object
1667+
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1668+
///
1669+
/// # Examples
1670+
///
1671+
/// ```
1672+
/// #![feature(raw_slice_split)]
1673+
/// #![feature(slice_ptr_get)]
1674+
///
1675+
/// let mut v = [1, 0, 3, 0, 5, 6];
1676+
/// let ptr = &mut v as *mut [_];
1677+
/// unsafe {
1678+
/// let (left, right) = ptr.split_at_mut(2);
1679+
/// assert_eq!(&*left, [1, 0]);
1680+
/// assert_eq!(&*right, [3, 0, 5, 6]);
1681+
/// }
1682+
/// ```
1683+
#[inline(always)]
1684+
#[track_caller]
1685+
#[unstable(feature = "raw_slice_split", issue = "95595")]
1686+
pub unsafe fn split_at_mut(self, mid: usize) -> (*mut [T], *mut [T]) {
1687+
assert!(mid <= self.len());
1688+
// SAFETY: The assert above is only a safety-net as long as `self.len()` is correct
1689+
// The actual safety requirements of this function are the same as for `split_at_mut_unchecked`
1690+
unsafe { self.split_at_mut_unchecked(mid) }
1691+
}
1692+
1693+
/// Divides one mutable raw slice into two at an index, without doing bounds checking.
1694+
///
1695+
/// The first will contain all indices from `[0, mid)` (excluding
1696+
/// the index `mid` itself) and the second will contain all
1697+
/// indices from `[mid, len)` (excluding the index `len` itself).
1698+
///
1699+
/// # Safety
1700+
///
1701+
/// `mid` must be [in-bounds] of the underlying [allocated object].
1702+
/// Which means `self` must be dereferenceable and span a single allocation
1703+
/// that is at least `mid * size_of::<T>()` bytes long. Not upholding these
1704+
/// requirements is *[undefined behavior]* even if the resulting pointers are not used.
1705+
///
1706+
/// [in-bounds]: #method.add
1707+
/// [out-of-bounds index]: #method.add
1708+
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1709+
///
1710+
/// # Examples
1711+
///
1712+
/// ```
1713+
/// #![feature(raw_slice_split)]
1714+
///
1715+
/// let mut v = [1, 0, 3, 0, 5, 6];
1716+
/// // scoped to restrict the lifetime of the borrows
1717+
/// unsafe {
1718+
/// let ptr = &mut v as *mut [_];
1719+
/// let (left, right) = ptr.split_at_mut_unchecked(2);
1720+
/// assert_eq!(&*left, [1, 0]);
1721+
/// assert_eq!(&*right, [3, 0, 5, 6]);
1722+
/// (&mut *left)[1] = 2;
1723+
/// (&mut *right)[1] = 4;
1724+
/// }
1725+
/// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
1726+
/// ```
1727+
#[inline(always)]
1728+
#[unstable(feature = "raw_slice_split", issue = "95595")]
1729+
pub unsafe fn split_at_mut_unchecked(self, mid: usize) -> (*mut [T], *mut [T]) {
1730+
let len = self.len();
1731+
let ptr = self.as_mut_ptr();
1732+
1733+
// SAFETY: Caller must pass a valid pointer and an index that is in-bounds.
1734+
let tail = unsafe { ptr.add(mid) };
1735+
(
1736+
crate::ptr::slice_from_raw_parts_mut(ptr, mid),
1737+
crate::ptr::slice_from_raw_parts_mut(tail, len - mid),
1738+
)
1739+
}
1740+
16251741
/// Returns a raw pointer to the slice's buffer.
16261742
///
16271743
/// This is equivalent to casting `self` to `*mut T`, but more type-safe.
@@ -1645,9 +1761,10 @@ impl<T> *mut [T] {
16451761
/// Returns a raw pointer to an element or subslice, without doing bounds
16461762
/// checking.
16471763
///
1648-
/// Calling this method with an out-of-bounds index or when `self` is not dereferenceable
1764+
/// Calling this method with an [out-of-bounds index] or when `self` is not dereferenceable
16491765
/// is *[undefined behavior]* even if the resulting pointer is not used.
16501766
///
1767+
/// [out-of-bounds index]: #method.add
16511768
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
16521769
///
16531770
/// # Examples

0 commit comments

Comments
 (0)
Please sign in to comment.