Skip to content

Commit cc332fa

Browse files
author
Jethro Beekman
committed
Implement split_array and split_array_mut
1 parent 0ce0fed commit cc332fa

File tree

2 files changed

+156
-0
lines changed

2 files changed

+156
-0
lines changed

library/core/src/array/mod.rs

+82
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,88 @@ impl<T, const N: usize> [T; N] {
530530
// items.
531531
unsafe { collect_into_array_unchecked(&mut self.iter_mut()) }
532532
}
533+
534+
/// Divides one array into two at an index.
535+
///
536+
/// The first will contain all indices from `[0, M)` (excluding
537+
/// the index `M` itself) and the second will contain all
538+
/// indices from `[M, N)` (excluding the index `N` itself).
539+
///
540+
/// # Panics
541+
///
542+
/// Panics if `M > N`.
543+
///
544+
/// # Examples
545+
///
546+
/// ```
547+
/// #![feature(array_split_array)]
548+
///
549+
/// let v = [1, 2, 3, 4, 5, 6];
550+
///
551+
/// {
552+
/// let (left, right) = v.split_array::<0>();
553+
/// assert_eq!(left, &[]);
554+
/// assert_eq!(right, [1, 2, 3, 4, 5, 6]);
555+
/// }
556+
///
557+
/// {
558+
/// let (left, right) = v.split_array::<2>();
559+
/// assert_eq!(left, &[1, 2]);
560+
/// assert_eq!(right, [3, 4, 5, 6]);
561+
/// }
562+
///
563+
/// {
564+
/// let (left, right) = v.split_array::<6>();
565+
/// assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
566+
/// assert_eq!(right, []);
567+
/// }
568+
/// ```
569+
// Note: this is not intended to be stabilized in its current form. The
570+
// second element of the return value should instead be `&[T; {N - M}]`.
571+
#[unstable(
572+
feature = "array_split_array",
573+
reason = "not intended for stabilization",
574+
issue = "74674"
575+
)]
576+
#[inline]
577+
pub fn split_array<const M: usize>(&self) -> (&[T; M], &[T]) {
578+
self[..].split_array::<M>()
579+
}
580+
581+
/// Divides one mutable array into two at an index.
582+
///
583+
/// The first will contain all indices from `[0, M)` (excluding
584+
/// the index `M` itself) and the second will contain all
585+
/// indices from `[M, N)` (excluding the index `N` itself).
586+
///
587+
/// # Panics
588+
///
589+
/// Panics if `M > N`.
590+
///
591+
/// # Examples
592+
///
593+
/// ```
594+
/// #![feature(array_split_array)]
595+
///
596+
/// let mut v = [1, 0, 3, 0, 5, 6];
597+
/// let (left, right) = v.split_array_mut::<2>();
598+
/// assert_eq!(left, &mut [1, 0]);
599+
/// assert_eq!(right, [3, 0, 5, 6]);
600+
/// left[1] = 2;
601+
/// right[1] = 4;
602+
/// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
603+
/// ```
604+
// Note: this is not intended to be stabilized in its current form. The
605+
// second element of the return value should instead be `&mut [T; {N - M}]`.
606+
#[unstable(
607+
feature = "array_split_array",
608+
reason = "not intended for stabilization",
609+
issue = "74674"
610+
)]
611+
#[inline]
612+
pub fn split_array_mut<const M: usize>(&mut self) -> (&mut [T; M], &mut [T]) {
613+
self[..].split_array_mut::<M>()
614+
}
533615
}
534616

535617
/// Pulls `N` items from `iter` and returns them as an array. If the iterator

library/core/src/slice/mod.rs

+74
Original file line numberDiff line numberDiff line change
@@ -1633,6 +1633,80 @@ impl<T> [T] {
16331633
unsafe { (from_raw_parts_mut(ptr, mid), from_raw_parts_mut(ptr.add(mid), len - mid)) }
16341634
}
16351635

1636+
/// Divides one slice into an array and a remainder slice at an index.
1637+
///
1638+
/// The array will contain all indices from `[0, N)` (excluding
1639+
/// the index `N` itself) and the slice will contain all
1640+
/// indices from `[N, len)` (excluding the index `len` itself).
1641+
///
1642+
/// # Panics
1643+
///
1644+
/// Panics if `N > len`.
1645+
///
1646+
/// # Examples
1647+
///
1648+
/// ```
1649+
/// #![feature(slice_split_array)]
1650+
///
1651+
/// let v = &[1, 2, 3, 4, 5, 6][..];
1652+
///
1653+
/// {
1654+
/// let (left, right) = v.split_array::<0>();
1655+
/// assert_eq!(left, &[]);
1656+
/// assert_eq!(right, [1, 2, 3, 4, 5, 6]);
1657+
/// }
1658+
///
1659+
/// {
1660+
/// let (left, right) = v.split_array::<2>();
1661+
/// assert_eq!(left, &[1, 2]);
1662+
/// assert_eq!(right, [3, 4, 5, 6]);
1663+
/// }
1664+
///
1665+
/// {
1666+
/// let (left, right) = v.split_array::<6>();
1667+
/// assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
1668+
/// assert_eq!(right, []);
1669+
/// }
1670+
/// ```
1671+
#[unstable(feature = "slice_split_array", reason = "new API", issue = "74674")]
1672+
#[inline]
1673+
pub fn split_array<const N: usize>(&self) -> (&[T; N], &[T]) {
1674+
let (a, b) = self.split_at(N);
1675+
// SAFETY: a points to [T; N]? Yes it's [T] of length N (checked by split_at)
1676+
unsafe { (&*(a.as_ptr() as *const [T; N]), b) }
1677+
}
1678+
1679+
/// Divides one mutable slice into an array and a remainder slice at an index.
1680+
///
1681+
/// The array will contain all indices from `[0, N)` (excluding
1682+
/// the index `N` itself) and the slice will contain all
1683+
/// indices from `[N, len)` (excluding the index `len` itself).
1684+
///
1685+
/// # Panics
1686+
///
1687+
/// Panics if `N > len`.
1688+
///
1689+
/// # Examples
1690+
///
1691+
/// ```
1692+
/// #![feature(slice_split_array)]
1693+
///
1694+
/// let mut v = &mut [1, 0, 3, 0, 5, 6][..];
1695+
/// let (left, right) = v.split_array_mut::<2>();
1696+
/// assert_eq!(left, &mut [1, 0]);
1697+
/// assert_eq!(right, [3, 0, 5, 6]);
1698+
/// left[1] = 2;
1699+
/// right[1] = 4;
1700+
/// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
1701+
/// ```
1702+
#[unstable(feature = "slice_split_array", reason = "new API", issue = "74674")]
1703+
#[inline]
1704+
pub fn split_array_mut<const N: usize>(&mut self) -> (&mut [T; N], &mut [T]) {
1705+
let (a, b) = self.split_at_mut(N);
1706+
// SAFETY: a points to [T; N]? Yes it's [T] of length N (checked by split_at_mut)
1707+
unsafe { (&mut *(a.as_mut_ptr() as *mut [T; N]), b) }
1708+
}
1709+
16361710
/// Returns an iterator over subslices separated by elements that match
16371711
/// `pred`. The matched element is not contained in the subslices.
16381712
///

0 commit comments

Comments
 (0)