mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-15 05:26:47 +00:00
Merge ef569a29c9
into 65fa0ab924
This commit is contained in:
commit
61dc3158bc
@ -1308,6 +1308,144 @@ forward_iterator! { RSplitN: T, &'a [T] }
|
||||
forward_iterator! { SplitNMut: T, &'a mut [T] }
|
||||
forward_iterator! { RSplitNMut: T, &'a mut [T] }
|
||||
|
||||
/// An iterator over subslices separated by a given slice
|
||||
///
|
||||
/// This struct is created by the [`split_pattern`] method on [slices].
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(split_pattern)]
|
||||
/// let slice = [10, 10, 40, 33, 30, 10, 40, 20];
|
||||
/// let pat = [10, 40];
|
||||
/// let mut iter = slice.split_pattern(&pat);
|
||||
/// assert_eq!(iter.next(), Some(&[10][..]));
|
||||
/// assert_eq!(iter.next(), Some(&[33, 30][..]));
|
||||
/// assert_eq!(iter.next(), Some(&[20][..]));
|
||||
/// assert_eq!(iter.next(), None);
|
||||
/// ```
|
||||
///
|
||||
/// [`split_pattern`]: slice::split_pattern
|
||||
/// [slices]: slice
|
||||
#[unstable(feature = "split_pattern", issue = "49036")]
|
||||
#[must_use = "iterators are lazy and do nothing unless consumed"]
|
||||
pub struct SplitPattern<'a, 'b, T>
|
||||
where
|
||||
T: cmp::PartialEq,
|
||||
{
|
||||
v: &'a [T],
|
||||
pattern: &'b [T],
|
||||
finished: bool,
|
||||
}
|
||||
|
||||
#[unstable(feature = "split_pattern", issue = "49036")]
|
||||
impl<'a, 'b, T: cmp::PartialEq> SplitPattern<'a, 'b, T> {
|
||||
#![allow(unused)]
|
||||
#[inline]
|
||||
pub(super) fn new(slice: &'a [T], pattern: &'b [T]) -> Self {
|
||||
Self { v: slice, pattern, finished: false }
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "split_pattern", issue = "49036")]
|
||||
impl<T: fmt::Debug> fmt::Debug for SplitPattern<'_, '_, T>
|
||||
where
|
||||
T: cmp::PartialEq,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("SplitPattern")
|
||||
.field("v", &self.v)
|
||||
.field("pattern", &self.pattern)
|
||||
.field("finished", &self.finished)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "split_pattern", issue = "49036")]
|
||||
impl<T> Clone for SplitPattern<'_, '_, T>
|
||||
where
|
||||
T: cmp::PartialEq,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
SplitPattern { v: self.v, pattern: self.pattern, finished: self.finished }
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "split_pattern", issue = "49036")]
|
||||
impl<'a, 'b, T> Iterator for SplitPattern<'a, 'b, T>
|
||||
where
|
||||
T: cmp::PartialEq,
|
||||
{
|
||||
type Item = &'a [T];
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<&'a [T]> {
|
||||
if self.finished {
|
||||
return None;
|
||||
}
|
||||
|
||||
for i in 0..self.v.len() {
|
||||
if self.v[i..].starts_with(&self.pattern) {
|
||||
let (left, right) = (&self.v[0..i], &self.v[i + self.pattern.len()..]);
|
||||
let ret = Some(left);
|
||||
self.v = right;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
self.finish()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
if self.finished {
|
||||
(0, Some(0))
|
||||
} else {
|
||||
// If the predicate doesn't match anything, we yield one slice.
|
||||
// If it matches every element, we yield `len() + 1` empty slices.
|
||||
(1, Some(self.v.len() + 1))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "split_pattern", issue = "49036")]
|
||||
impl<'a, 'b, T> DoubleEndedIterator for SplitPattern<'a, 'b, T>
|
||||
where
|
||||
T: cmp::PartialEq,
|
||||
{
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<&'a [T]> {
|
||||
if self.finished {
|
||||
return None;
|
||||
}
|
||||
|
||||
for i in (0..self.v.len()).rev() {
|
||||
if self.v[..i].ends_with(&self.pattern) {
|
||||
let (left, right) = (&self.v[i..], &self.v[..i - self.pattern.len()]);
|
||||
let ret = Some(left);
|
||||
self.v = right;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
self.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "split_pattern", issue = "49036")]
|
||||
impl<'a, 'b, T> SplitIter for SplitPattern<'a, 'b, T>
|
||||
where
|
||||
T: cmp::PartialEq,
|
||||
{
|
||||
#[inline]
|
||||
fn finish(&mut self) -> Option<&'a [T]> {
|
||||
if self.finished {
|
||||
None
|
||||
} else {
|
||||
self.finished = true;
|
||||
Some(self.v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator over overlapping subslices of length `size`.
|
||||
///
|
||||
/// This struct is created by the [`windows`] method on [slices].
|
||||
|
@ -51,6 +51,8 @@ pub use index::SliceIndex;
|
||||
pub use index::{range, try_range};
|
||||
#[unstable(feature = "array_windows", issue = "75027")]
|
||||
pub use iter::ArrayWindows;
|
||||
#[unstable(feature = "split_pattern", issue = "49036")]
|
||||
pub use iter::SplitPattern;
|
||||
#[unstable(feature = "array_chunks", issue = "74985")]
|
||||
pub use iter::{ArrayChunks, ArrayChunksMut};
|
||||
#[stable(feature = "slice_group_by", since = "1.77.0")]
|
||||
@ -4089,6 +4091,16 @@ impl<T> [T] {
|
||||
unsafe { self.align_to() }
|
||||
}
|
||||
|
||||
/// Splits a slice by a pattern
|
||||
#[unstable(feature = "split_pattern", issue = "49036")]
|
||||
#[inline]
|
||||
pub fn split_pattern<'a, 'b>(&'a self, pattern: &'b [T]) -> SplitPattern<'a, 'b, T>
|
||||
where
|
||||
T: PartialEq,
|
||||
{
|
||||
SplitPattern::new(&self, pattern)
|
||||
}
|
||||
|
||||
/// Splits a mutable slice into a mutable prefix, a middle of aligned SIMD types,
|
||||
/// and a mutable suffix.
|
||||
///
|
||||
|
Loading…
Reference in New Issue
Block a user