about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/core/src/slice/mod.rs56
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--library/core/tests/slice.rs20
3 files changed, 77 insertions, 0 deletions
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 5d6e7dcfcee..d9dcf14ba02 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -2478,6 +2478,62 @@ impl<T> [T] {
         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*).
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 3e6d31fcd2f..99c73a85b26 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -47,6 +47,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)]
diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs
index 88f54591bb4..5b0e825dc00 100644
--- a/library/core/tests/slice.rs
+++ b/library/core/tests/slice.rs
@@ -2448,6 +2448,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)*);