diff options
Diffstat (limited to 'src/libcore/slice/mod.rs')
| -rw-r--r-- | src/libcore/slice/mod.rs | 172 |
1 files changed, 152 insertions, 20 deletions
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 45667bb4299..6d598677c9b 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -81,6 +81,10 @@ pub trait SliceExt { fn split<P>(&self, pred: P) -> Split<Self::Item, P> where P: FnMut(&Self::Item) -> bool; + #[unstable(feature = "slice_rsplit", issue = "41020")] + fn rsplit<P>(&self, pred: P) -> RSplit<Self::Item, P> + where P: FnMut(&Self::Item) -> bool; + #[stable(feature = "core", since = "1.6.0")] fn splitn<P>(&self, n: usize, pred: P) -> SplitN<Self::Item, P> where P: FnMut(&Self::Item) -> bool; @@ -159,6 +163,10 @@ pub trait SliceExt { fn split_mut<P>(&mut self, pred: P) -> SplitMut<Self::Item, P> where P: FnMut(&Self::Item) -> bool; + #[unstable(feature = "slice_rsplit", issue = "41020")] + fn rsplit_mut<P>(&mut self, pred: P) -> RSplitMut<Self::Item, P> + where P: FnMut(&Self::Item) -> bool; + #[stable(feature = "core", since = "1.6.0")] fn splitn_mut<P>(&mut self, n: usize, pred: P) -> SplitNMut<Self::Item, P> where P: FnMut(&Self::Item) -> bool; @@ -294,14 +302,20 @@ impl<T> SliceExt for [T] { } #[inline] + fn rsplit<P>(&self, pred: P) -> RSplit<T, P> + where P: FnMut(&T) -> bool + { + RSplit { inner: self.split(pred) } + } + + #[inline] fn splitn<P>(&self, n: usize, pred: P) -> SplitN<T, P> where P: FnMut(&T) -> bool { SplitN { inner: GenericSplitN { iter: self.split(pred), - count: n, - invert: false + count: n } } } @@ -312,9 +326,8 @@ impl<T> SliceExt for [T] { { RSplitN { inner: GenericSplitN { - iter: self.split(pred), - count: n, - invert: true + iter: self.rsplit(pred), + count: n } } } @@ -476,14 +489,20 @@ impl<T> SliceExt for [T] { } #[inline] + fn rsplit_mut<P>(&mut self, pred: P) -> RSplitMut<T, P> + where P: FnMut(&T) -> bool + { + RSplitMut { inner: self.split_mut(pred) } + } + + #[inline] fn splitn_mut<P>(&mut self, n: usize, pred: P) -> SplitNMut<T, P> where P: FnMut(&T) -> bool { SplitNMut { inner: GenericSplitN { iter: self.split_mut(pred), - count: n, - invert: false + count: n } } } @@ -494,9 +513,8 @@ impl<T> SliceExt for [T] { { RSplitNMut { inner: GenericSplitN { - iter: self.split_mut(pred), - count: n, - invert: true + iter: self.rsplit_mut(pred), + count: n } } } @@ -1498,9 +1516,10 @@ unsafe impl<'a, T> TrustedLen for IterMut<'a, T> {} // Return the arithmetic difference if `T` is zero size. #[inline(always)] fn ptrdistance<T>(start: *const T, end: *const T) -> usize { - let diff = (end as usize).wrapping_sub(start as usize); - let size = mem::size_of::<T>(); - diff / (if size == 0 { 1 } else { size }) + match start.offset_to(end) { + Some(x) => x as usize, + None => (end as usize).wrapping_sub(start as usize), + } } // Extension methods for raw pointers, used by the iterators @@ -1735,6 +1754,123 @@ impl<'a, T, P> DoubleEndedIterator for SplitMut<'a, T, P> where #[unstable(feature = "fused", issue = "35602")] impl<'a, T, P> FusedIterator for SplitMut<'a, T, P> where P: FnMut(&T) -> bool {} +/// An iterator over subslices separated by elements that match a predicate +/// function, starting from the end of the slice. +/// +/// This struct is created by the [`rsplit`] method on [slices]. +/// +/// [`rsplit`]: ../../std/primitive.slice.html#method.rsplit +/// [slices]: ../../std/primitive.slice.html +#[unstable(feature = "slice_rsplit", issue = "41020")] +#[derive(Clone)] // Is this correct, or does it incorrectly require `T: Clone`? +pub struct RSplit<'a, T:'a, P> where P: FnMut(&T) -> bool { + inner: Split<'a, T, P> +} + +#[unstable(feature = "slice_rsplit", issue = "41020")] +impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for RSplit<'a, T, P> where P: FnMut(&T) -> bool { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("RSplit") + .field("v", &self.inner.v) + .field("finished", &self.inner.finished) + .finish() + } +} + +#[unstable(feature = "slice_rsplit", issue = "41020")] +impl<'a, T, P> Iterator for RSplit<'a, T, P> where P: FnMut(&T) -> bool { + type Item = &'a [T]; + + #[inline] + fn next(&mut self) -> Option<&'a [T]> { + self.inner.next_back() + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + self.inner.size_hint() + } +} + +#[unstable(feature = "slice_rsplit", issue = "41020")] +impl<'a, T, P> DoubleEndedIterator for RSplit<'a, T, P> where P: FnMut(&T) -> bool { + #[inline] + fn next_back(&mut self) -> Option<&'a [T]> { + self.inner.next() + } +} + +#[unstable(feature = "slice_rsplit", issue = "41020")] +impl<'a, T, P> SplitIter for RSplit<'a, T, P> where P: FnMut(&T) -> bool { + #[inline] + fn finish(&mut self) -> Option<&'a [T]> { + self.inner.finish() + } +} + +//#[unstable(feature = "fused", issue = "35602")] +#[unstable(feature = "slice_rsplit", issue = "41020")] +impl<'a, T, P> FusedIterator for RSplit<'a, T, P> where P: FnMut(&T) -> bool {} + +/// An iterator over the subslices of the vector which are separated +/// by elements that match `pred`, starting from the end of the slice. +/// +/// This struct is created by the [`rsplit_mut`] method on [slices]. +/// +/// [`rsplit_mut`]: ../../std/primitive.slice.html#method.rsplit_mut +/// [slices]: ../../std/primitive.slice.html +#[unstable(feature = "slice_rsplit", issue = "41020")] +pub struct RSplitMut<'a, T:'a, P> where P: FnMut(&T) -> bool { + inner: SplitMut<'a, T, P> +} + +#[unstable(feature = "slice_rsplit", issue = "41020")] +impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("RSplitMut") + .field("v", &self.inner.v) + .field("finished", &self.inner.finished) + .finish() + } +} + +#[unstable(feature = "slice_rsplit", issue = "41020")] +impl<'a, T, P> SplitIter for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool { + #[inline] + fn finish(&mut self) -> Option<&'a mut [T]> { + self.inner.finish() + } +} + +#[unstable(feature = "slice_rsplit", issue = "41020")] +impl<'a, T, P> Iterator for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool { + type Item = &'a mut [T]; + + #[inline] + fn next(&mut self) -> Option<&'a mut [T]> { + self.inner.next_back() + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + self.inner.size_hint() + } +} + +#[unstable(feature = "slice_rsplit", issue = "41020")] +impl<'a, T, P> DoubleEndedIterator for RSplitMut<'a, T, P> where + P: FnMut(&T) -> bool, +{ + #[inline] + fn next_back(&mut self) -> Option<&'a mut [T]> { + self.inner.next() + } +} + +//#[unstable(feature = "fused", issue = "35602")] +#[unstable(feature = "slice_rsplit", issue = "41020")] +impl<'a, T, P> FusedIterator for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool {} + /// An private iterator over subslices separated by elements that /// match a predicate function, splitting at most a fixed number of /// times. @@ -1742,7 +1878,6 @@ impl<'a, T, P> FusedIterator for SplitMut<'a, T, P> where P: FnMut(&T) -> bool { struct GenericSplitN<I> { iter: I, count: usize, - invert: bool } impl<T, I: SplitIter<Item=T>> Iterator for GenericSplitN<I> { @@ -1753,10 +1888,7 @@ impl<T, I: SplitIter<Item=T>> Iterator for GenericSplitN<I> { match self.count { 0 => None, 1 => { self.count -= 1; self.iter.finish() } - _ => { - self.count -= 1; - if self.invert {self.iter.next_back()} else {self.iter.next()} - } + _ => { self.count -= 1; self.iter.next() } } } @@ -1798,7 +1930,7 @@ impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for SplitN<'a, T, P> where P: FnMut(& /// [slices]: ../../std/primitive.slice.html #[stable(feature = "rust1", since = "1.0.0")] pub struct RSplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool { - inner: GenericSplitN<Split<'a, T, P>> + inner: GenericSplitN<RSplit<'a, T, P>> } #[stable(feature = "core_impl_debug", since = "1.9.0")] @@ -1841,7 +1973,7 @@ impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for SplitNMut<'a, T, P> where P: FnMu /// [slices]: ../../std/primitive.slice.html #[stable(feature = "rust1", since = "1.0.0")] pub struct RSplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool { - inner: GenericSplitN<SplitMut<'a, T, P>> + inner: GenericSplitN<RSplitMut<'a, T, P>> } #[stable(feature = "core_impl_debug", since = "1.9.0")] |
