Skip to content

Commit 4242335

Browse files
saethlinthe8472
authored andcommitted
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_unchecked` These methods reduce the amount of unsafe code needed to migrate ChunksMut and related iterators to raw slices (#94247) Co-authored-by:: The 8472 <[email protected]>
1 parent 07a461a commit 4242335

File tree

1 file changed

+105
-0
lines changed

1 file changed

+105
-0
lines changed

library/core/src/ptr/mut_ptr.rs

+105
Original file line numberDiff line numberDiff line change
@@ -1338,6 +1338,111 @@ impl<T> *mut [T] {
13381338
metadata(self)
13391339
}
13401340

1341+
/// Returns `true` if the raw slice has a length of 0.
1342+
///
1343+
/// # Examples
1344+
///
1345+
/// ```
1346+
/// #![feature(slice_ptr_len)]
1347+
///
1348+
/// let mut a = [1, 2, 3];
1349+
/// let ptr = &mut a as *mut [_];
1350+
/// assert!(!ptr.is_empty());
1351+
/// ```
1352+
#[inline(always)]
1353+
#[unstable(feature = "slice_ptr_len", issue = "71146")]
1354+
#[rustc_const_unstable(feature = "const_slice_ptr_len", issue = "71146")]
1355+
pub const fn is_empty(self) -> bool {
1356+
self.len() == 0
1357+
}
1358+
1359+
/// Divides one mutable raw slice into two at an index.
1360+
///
1361+
/// The first will contain all indices from `[0, mid)` (excluding
1362+
/// the index `mid` itself) and the second will contain all
1363+
/// indices from `[mid, len)` (excluding the index `len` itself).
1364+
///
1365+
/// # Panics
1366+
///
1367+
/// Panics if `mid > len`.
1368+
///
1369+
/// # Examples
1370+
///
1371+
/// ```
1372+
/// #![feature(raw_slice_split)]
1373+
/// #![feature(slice_ptr_get)]
1374+
///
1375+
/// let mut v = [1, 0, 3, 0, 5, 6];
1376+
/// let ptr = &mut v as *mut [_];
1377+
/// let (left, right) = ptr.split_at_mut(2);
1378+
/// unsafe {
1379+
/// assert_eq!(&*left, [1, 0]);
1380+
/// assert_eq!(&*right, [3, 0, 5, 6]);
1381+
/// }
1382+
/// ```
1383+
#[inline(always)]
1384+
#[track_caller]
1385+
#[unstable(feature = "raw_slice_split", issue = "71146")]
1386+
pub fn split_at_mut(self, mid: usize) -> (*mut [T], *mut [T]) {
1387+
assert!(mid <= self.len());
1388+
// SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
1389+
// fulfills the requirements of `from_raw_parts_mut`.
1390+
unsafe { self.split_at_mut_unchecked(mid) }
1391+
}
1392+
1393+
/// Divides one mutable raw slice into two at an index, without doing bounds checking.
1394+
///
1395+
/// The first will contain all indices from `[0, mid)` (excluding
1396+
/// the index `mid` itself) and the second will contain all
1397+
/// indices from `[mid, len)` (excluding the index `len` itself).
1398+
///
1399+
/// For a safe alternative see [`split_at_mut`].
1400+
///
1401+
/// [`split_at_mut`]: #method.split_at_mut
1402+
///
1403+
/// # Safety
1404+
///
1405+
/// Calling this method with an out-of-bounds index is *[undefined behavior]*
1406+
/// even if the resulting reference is not used. The caller has to ensure that
1407+
/// `0 <= mid <= self.len()`.
1408+
///
1409+
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1410+
///
1411+
/// # Examples
1412+
///
1413+
/// ```
1414+
/// #![feature(raw_slice_split)]
1415+
///
1416+
/// let mut v = [1, 0, 3, 0, 5, 6];
1417+
/// // scoped to restrict the lifetime of the borrows
1418+
/// unsafe {
1419+
/// let ptr = &mut v as *mut [_];
1420+
/// let (left, right) = ptr.split_at_mut_unchecked(2);
1421+
/// assert_eq!(&*left, [1, 0]);
1422+
/// assert_eq!(&*right, [3, 0, 5, 6]);
1423+
/// (&mut *left)[1] = 2;
1424+
/// (&mut *right)[1] = 4;
1425+
/// }
1426+
/// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
1427+
/// ```
1428+
#[inline(always)]
1429+
#[unstable(feature = "raw_slice_split", issue = "71146")]
1430+
pub unsafe fn split_at_mut_unchecked(self, mid: usize) -> (*mut [T], *mut [T]) {
1431+
let len = self.len();
1432+
let ptr = self.as_mut_ptr();
1433+
1434+
// SAFETY: Caller has to check that `0 <= mid <= self.len()`.
1435+
//
1436+
// `[ptr; mid]` and `[mid; len]` are not overlapping, so returning a mutable reference
1437+
// is fine.
1438+
unsafe {
1439+
(
1440+
crate::ptr::slice_from_raw_parts_mut(ptr, mid),
1441+
crate::ptr::slice_from_raw_parts_mut(ptr.add(mid), len - mid),
1442+
)
1443+
}
1444+
}
1445+
13411446
/// Returns a raw pointer to the slice's buffer.
13421447
///
13431448
/// This is equivalent to casting `self` to `*mut T`, but more type-safe.

0 commit comments

Comments
 (0)