Skip to content

Commit 3e245fa

Browse files
committed
core: add array::split_array()
1 parent 274a7e0 commit 3e245fa

File tree

1 file changed

+55
-1
lines changed

1 file changed

+55
-1
lines changed

library/core/src/array/mod.rs

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ use crate::borrow::{Borrow, BorrowMut};
88
use crate::cmp::Ordering;
99
use crate::convert::{Infallible, TryFrom};
1010
use crate::error::Error;
11-
use crate::fmt;
1211
use crate::hash::{self, Hash};
1312
use crate::iter::UncheckedIterator;
1413
use crate::mem::{self, MaybeUninit};
1514
use crate::ops::{
1615
ChangeOutputType, ControlFlow, FromResidual, Index, IndexMut, NeverShortCircuit, Residual, Try,
1716
};
1817
use crate::slice::{Iter, IterMut};
18+
use crate::{fmt, ptr};
1919

2020
mod ascii;
2121
mod drain;
@@ -625,6 +625,60 @@ impl<T, const N: usize> [T; N] {
625625
from_trusted_iterator(self.iter_mut())
626626
}
627627

628+
/// Divides one array into two at an index.
629+
///
630+
/// The first will contain all indices from `[0, M)` (excluding
631+
/// the index `M` itself) and the second will contain all
632+
/// indices from `[M, N)` (excluding the index `N` itself).
633+
///
634+
/// # Examples
635+
///
636+
/// ```
637+
/// #![feature(split_array)]
638+
///
639+
/// let v = [1, 2, 3, 4, 5, 6];
640+
///
641+
/// {
642+
/// let (left, right) = v.split_array::<0>();
643+
/// assert_eq!(left, []);
644+
/// assert_eq!(right, [1, 2, 3, 4, 5, 6]);
645+
/// }
646+
///
647+
/// {
648+
/// let (left, right) = v.split_array::<2>();
649+
/// assert_eq!(left, [1, 2]);
650+
/// assert_eq!(right, [3, 4, 5, 6]);
651+
/// }
652+
///
653+
/// {
654+
/// let (left, right) = v.split_array::<6>();
655+
/// assert_eq!(left, [1, 2, 3, 4, 5, 6]);
656+
/// assert_eq!(right, []);
657+
/// }
658+
/// ```
659+
#[unstable(feature = "split_array", reason = "new API", issue = "90091")]
660+
#[inline]
661+
pub const fn split_array<const M: usize>(self) -> ([T; M], [T; N - M]) {
662+
// SAFETY: 0 <= M <= len (N)
663+
let (left, right) = unsafe { self.split_at_unchecked(M) };
664+
665+
let left = left.as_ptr() as *const [T; M];
666+
let right = right.as_ptr() as *const [T; N - M];
667+
668+
// SAFETY: `left` is a valid and aligned pointer to the first `M` elements of `self`
669+
// (guaranteed by `split_at_unchecked()`).
670+
// `self` will be forgotten immediately after (ptr::read() cannot unwind).
671+
let left = unsafe { ptr::read(left) };
672+
// SAFETY: `right` is a valid and aligned pointer to the last `N-M` elements of `self`
673+
// (guaranteed by `split_at_unchecked()`).
674+
// `self` will be forgotten immediately after (ptr::read() cannot unwind).
675+
let right = unsafe { ptr::read(right) };
676+
677+
mem::forget(self);
678+
679+
(left, right)
680+
}
681+
628682
/// Divides one array reference into two at an index.
629683
///
630684
/// The first will contain all indices from `[0, M)` (excluding

0 commit comments

Comments
 (0)