Auto merge of #112818 - Benjamin-L:add-slice_split_once, r=cuviper

Implement `slice::split_once` and `slice::rsplit_once`

Feature gate is `slice_split_once` and tracking issue is #112811. These are equivalents to the existing `str::split_once` and `str::rsplit_once` methods.
This commit is contained in:
bors 2023-10-11 08:19:13 +00:00
commit 156da98b29
3 changed files with 77 additions and 0 deletions

View File

@ -2482,6 +2482,62 @@ pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<'_, T, F>
RSplitNMut::new(self.rsplit_mut(pred), n)
}
/// Splits the slice on the first element that matches the specified
/// predicate.
///
/// If any matching elements are resent in the slice, returns the prefix
/// before the match and suffix after. The matching element itself is not
/// included. If no elements match, returns `None`.
///
/// # Examples
///
/// ```
/// #![feature(slice_split_once)]
/// let s = [1, 2, 3, 2, 4];
/// assert_eq!(s.split_once(|&x| x == 2), Some((
/// &[1][..],
/// &[3, 2, 4][..]
/// )));
/// assert_eq!(s.split_once(|&x| x == 0), None);
/// ```
#[unstable(feature = "slice_split_once", reason = "newly added", issue = "112811")]
#[inline]
pub fn split_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where
F: FnMut(&T) -> bool,
{
let index = self.iter().position(pred)?;
Some((&self[..index], &self[index + 1..]))
}
/// Splits the slice on the last element that matches the specified
/// predicate.
///
/// If any matching elements are resent in the slice, returns the prefix
/// before the match and suffix after. The matching element itself is not
/// included. If no elements match, returns `None`.
///
/// # Examples
///
/// ```
/// #![feature(slice_split_once)]
/// let s = [1, 2, 3, 2, 4];
/// assert_eq!(s.rsplit_once(|&x| x == 2), Some((
/// &[1, 2, 3][..],
/// &[4][..]
/// )));
/// assert_eq!(s.rsplit_once(|&x| x == 0), None);
/// ```
#[unstable(feature = "slice_split_once", reason = "newly added", issue = "112811")]
#[inline]
pub fn rsplit_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where
F: FnMut(&T) -> bool,
{
let index = self.iter().rposition(pred)?;
Some((&self[..index], &self[index + 1..]))
}
/// Returns `true` if the slice contains an element with the given value.
///
/// This operation is *O*(*n*).

View File

@ -49,6 +49,7 @@
#![feature(sort_internals)]
#![feature(slice_take)]
#![feature(slice_from_ptr_range)]
#![feature(slice_split_once)]
#![feature(split_as_slice)]
#![feature(maybe_uninit_uninit_array)]
#![feature(maybe_uninit_write_slice)]

View File

@ -2476,6 +2476,26 @@ fn slice_rsplit_array_mut_out_of_bounds() {
let _ = v.rsplit_array_mut::<7>();
}
#[test]
fn slice_split_once() {
let v = &[1, 2, 3, 2, 4][..];
assert_eq!(v.split_once(|&x| x == 2), Some((&[1][..], &[3, 2, 4][..])));
assert_eq!(v.split_once(|&x| x == 1), Some((&[][..], &[2, 3, 2, 4][..])));
assert_eq!(v.split_once(|&x| x == 4), Some((&[1, 2, 3, 2][..], &[][..])));
assert_eq!(v.split_once(|&x| x == 0), None);
}
#[test]
fn slice_rsplit_once() {
let v = &[1, 2, 3, 2, 4][..];
assert_eq!(v.rsplit_once(|&x| x == 2), Some((&[1, 2, 3][..], &[4][..])));
assert_eq!(v.rsplit_once(|&x| x == 1), Some((&[][..], &[2, 3, 2, 4][..])));
assert_eq!(v.rsplit_once(|&x| x == 4), Some((&[1, 2, 3, 2][..], &[][..])));
assert_eq!(v.rsplit_once(|&x| x == 0), None);
}
macro_rules! take_tests {
(slice: &[], $($tts:tt)*) => {
take_tests!(ty: &[()], slice: &[], $($tts)*);