Skip to content

Commit 4a43976

Browse files
author
Jethro Beekman
committed
Implement split_array and split_array_mut
1 parent 42983a2 commit 4a43976

File tree

5 files changed

+219
-0
lines changed

5 files changed

+219
-0
lines changed

library/core/src/array/mod.rs

+78
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,84 @@ impl<T, const N: usize> [T; N] {
500500
// items.
501501
unsafe { collect_into_array_unchecked(&mut self.iter_mut()) }
502502
}
503+
504+
/// Divides one array reference into two at an index.
505+
///
506+
/// The first will contain all indices from `[0, M)` (excluding
507+
/// the index `M` itself) and the second will contain all
508+
/// indices from `[M, N)` (excluding the index `N` itself).
509+
///
510+
/// # Panics
511+
///
512+
/// Panics if `M > N`.
513+
///
514+
/// # Examples
515+
///
516+
/// ```
517+
/// #![feature(split_array)]
518+
///
519+
/// let v = [1, 2, 3, 4, 5, 6];
520+
///
521+
/// {
522+
/// let (left, right) = v.split_array_ref::<0>();
523+
/// assert_eq!(left, &[]);
524+
/// assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
525+
/// }
526+
///
527+
/// {
528+
/// let (left, right) = v.split_array_ref::<2>();
529+
/// assert_eq!(left, &[1, 2]);
530+
/// assert_eq!(right, &[3, 4, 5, 6]);
531+
/// }
532+
///
533+
/// {
534+
/// let (left, right) = v.split_array_ref::<6>();
535+
/// assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
536+
/// assert_eq!(right, &[]);
537+
/// }
538+
/// ```
539+
#[unstable(
540+
feature = "split_array",
541+
reason = "return type should have array as 2nd element",
542+
issue = "90091"
543+
)]
544+
#[inline]
545+
pub fn split_array_ref<const M: usize>(&self) -> (&[T; M], &[T]) {
546+
(&self[..]).split_array_ref::<M>()
547+
}
548+
549+
/// Divides one mutable array reference into two at an index.
550+
///
551+
/// The first will contain all indices from `[0, M)` (excluding
552+
/// the index `M` itself) and the second will contain all
553+
/// indices from `[M, N)` (excluding the index `N` itself).
554+
///
555+
/// # Panics
556+
///
557+
/// Panics if `M > N`.
558+
///
559+
/// # Examples
560+
///
561+
/// ```
562+
/// #![feature(split_array)]
563+
///
564+
/// let mut v = [1, 0, 3, 0, 5, 6];
565+
/// let (left, right) = v.split_array_mut::<2>();
566+
/// assert_eq!(left, &mut [1, 0][..]);
567+
/// assert_eq!(right, &mut [3, 0, 5, 6]);
568+
/// left[1] = 2;
569+
/// right[1] = 4;
570+
/// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
571+
/// ```
572+
#[unstable(
573+
feature = "split_array",
574+
reason = "return type should have array as 2nd element",
575+
issue = "90091"
576+
)]
577+
#[inline]
578+
pub fn split_array_mut<const M: usize>(&mut self) -> (&mut [T; M], &mut [T]) {
579+
(&mut self[..]).split_array_mut::<M>()
580+
}
503581
}
504582

505583
/// 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
@@ -1665,6 +1665,80 @@ impl<T> [T] {
16651665
unsafe { (from_raw_parts_mut(ptr, mid), from_raw_parts_mut(ptr.add(mid), len - mid)) }
16661666
}
16671667

1668+
/// Divides one slice into an array and a remainder slice at an index.
1669+
///
1670+
/// The array will contain all indices from `[0, N)` (excluding
1671+
/// the index `N` itself) and the slice will contain all
1672+
/// indices from `[N, len)` (excluding the index `len` itself).
1673+
///
1674+
/// # Panics
1675+
///
1676+
/// Panics if `N > len`.
1677+
///
1678+
/// # Examples
1679+
///
1680+
/// ```
1681+
/// #![feature(split_array)]
1682+
///
1683+
/// let v = &[1, 2, 3, 4, 5, 6][..];
1684+
///
1685+
/// {
1686+
/// let (left, right) = v.split_array_ref::<0>();
1687+
/// assert_eq!(left, &[]);
1688+
/// assert_eq!(right, [1, 2, 3, 4, 5, 6]);
1689+
/// }
1690+
///
1691+
/// {
1692+
/// let (left, right) = v.split_array_ref::<2>();
1693+
/// assert_eq!(left, &[1, 2]);
1694+
/// assert_eq!(right, [3, 4, 5, 6]);
1695+
/// }
1696+
///
1697+
/// {
1698+
/// let (left, right) = v.split_array_ref::<6>();
1699+
/// assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
1700+
/// assert_eq!(right, []);
1701+
/// }
1702+
/// ```
1703+
#[unstable(feature = "split_array", reason = "new API", issue = "90091")]
1704+
#[inline]
1705+
pub fn split_array_ref<const N: usize>(&self) -> (&[T; N], &[T]) {
1706+
let (a, b) = self.split_at(N);
1707+
// SAFETY: a points to [T; N]? Yes it's [T] of length N (checked by split_at)
1708+
unsafe { (&*(a.as_ptr() as *const [T; N]), b) }
1709+
}
1710+
1711+
/// Divides one mutable slice into an array and a remainder slice at an index.
1712+
///
1713+
/// The array will contain all indices from `[0, N)` (excluding
1714+
/// the index `N` itself) and the slice will contain all
1715+
/// indices from `[N, len)` (excluding the index `len` itself).
1716+
///
1717+
/// # Panics
1718+
///
1719+
/// Panics if `N > len`.
1720+
///
1721+
/// # Examples
1722+
///
1723+
/// ```
1724+
/// #![feature(split_array)]
1725+
///
1726+
/// let mut v = &mut [1, 0, 3, 0, 5, 6][..];
1727+
/// let (left, right) = v.split_array_mut::<2>();
1728+
/// assert_eq!(left, &mut [1, 0]);
1729+
/// assert_eq!(right, [3, 0, 5, 6]);
1730+
/// left[1] = 2;
1731+
/// right[1] = 4;
1732+
/// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
1733+
/// ```
1734+
#[unstable(feature = "split_array", reason = "new API", issue = "90091")]
1735+
#[inline]
1736+
pub fn split_array_mut<const N: usize>(&mut self) -> (&mut [T; N], &mut [T]) {
1737+
let (a, b) = self.split_at_mut(N);
1738+
// SAFETY: a points to [T; N]? Yes it's [T] of length N (checked by split_at_mut)
1739+
unsafe { (&mut *(a.as_mut_ptr() as *mut [T; N]), b) }
1740+
}
1741+
16681742
/// Returns an iterator over subslices separated by elements that match
16691743
/// `pred`. The matched element is not contained in the subslices.
16701744
///

library/core/tests/array.rs

+33
Original file line numberDiff line numberDiff line change
@@ -436,3 +436,36 @@ where
436436
std::panic::set_hook(prev_hook);
437437
result
438438
}
439+
440+
#[test]
441+
fn array_split_array_mut() {
442+
let mut v = [1, 2, 3, 4, 5, 6];
443+
444+
{
445+
let (left, right) = v.split_array_mut::<0>();
446+
assert_eq!(left, &mut []);
447+
assert_eq!(right, &mut [1, 2, 3, 4, 5, 6]);
448+
}
449+
450+
{
451+
let (left, right) = v.split_array_mut::<6>();
452+
assert_eq!(left, &mut [1, 2, 3, 4, 5, 6]);
453+
assert_eq!(right, &mut []);
454+
}
455+
}
456+
457+
#[should_panic]
458+
#[test]
459+
fn array_split_array_ref_out_of_bounds() {
460+
let v = [1, 2, 3, 4, 5, 6];
461+
462+
v.split_array_ref::<7>();
463+
}
464+
465+
#[should_panic]
466+
#[test]
467+
fn array_split_array_mut_out_of_bounds() {
468+
let mut v = [1, 2, 3, 4, 5, 6];
469+
470+
v.split_array_mut::<7>();
471+
}

library/core/tests/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
#![feature(integer_atomics)]
7171
#![feature(int_roundings)]
7272
#![feature(slice_group_by)]
73+
#![feature(split_array)]
7374
#![feature(trusted_random_access)]
7475
#![feature(unsize)]
7576
#![feature(unzip_option)]

library/core/tests/slice.rs

+33
Original file line numberDiff line numberDiff line change
@@ -2191,3 +2191,36 @@ mod swap_panics {
21912191
x.swap(2, 5);
21922192
}
21932193
}
2194+
2195+
#[test]
2196+
fn slice_split_array_mut() {
2197+
let v = &mut [1, 2, 3, 4, 5, 6][..];
2198+
2199+
{
2200+
let (left, right) = v.split_array_mut::<0>();
2201+
assert_eq!(left, &mut []);
2202+
assert_eq!(right, [1, 2, 3, 4, 5, 6]);
2203+
}
2204+
2205+
{
2206+
let (left, right) = v.split_array_mut::<6>();
2207+
assert_eq!(left, &mut [1, 2, 3, 4, 5, 6]);
2208+
assert_eq!(right, []);
2209+
}
2210+
}
2211+
2212+
#[should_panic]
2213+
#[test]
2214+
fn slice_split_array_ref_out_of_bounds() {
2215+
let v = &[1, 2, 3, 4, 5, 6][..];
2216+
2217+
v.split_array_ref::<7>();
2218+
}
2219+
2220+
#[should_panic]
2221+
#[test]
2222+
fn slice_split_array_mut_out_of_bounds() {
2223+
let v = &mut [1, 2, 3, 4, 5, 6][..];
2224+
2225+
v.split_array_mut::<7>();
2226+
}

0 commit comments

Comments
 (0)