@@ -2968,127 +2968,6 @@ unsafe impl<'a, T> TrustedRandomAccess for IterMut<'a, T> {
29682968 }
29692969}
29702970
2971- macro_rules! group_by {
2972- (struct $name:ident, $elem:ty, $mkslice:ident) => {
2973- #[unstable(feature = "slice_group_by", issue = "0")]
2974- impl<'a, T: 'a, P> $name<'a, T, P> {
2975- #[inline]
2976- fn is_empty(&self) -> bool {
2977- self.ptr == self.end
2978- }
2979-
2980- #[inline]
2981- fn remaining_len(&self) -> usize {
2982- unsafe { self.end.offset_from(self.ptr) as usize }
2983- }
2984- }
2985-
2986- #[unstable(feature = "slice_group_by", issue = "0")]
2987- impl<'a, T: 'a, P> Iterator for $name<'a, T, P>
2988- where P: FnMut(&T, &T) -> bool,
2989- {
2990- type Item = $elem;
2991-
2992- fn next(&mut self) -> Option<Self::Item> {
2993- // we use an unsafe block to avoid bounds checking here.
2994- // this is safe because the only thing we do here is to get
2995- // two elements at `ptr` and `ptr + 1`, bounds checking is done by hand.
2996- unsafe {
2997- if self.is_empty() { return None }
2998-
2999- let mut i = 0;
3000- let mut ptr = self.ptr;
3001-
3002- // we need to get *two* contiguous elements so we check that:
3003- // - the first element is at the `end - 1` position because
3004- // - the second one will be read from `ptr + 1` that must
3005- // be lower or equal to `end`
3006- while ptr != self.end.sub(1) {
3007- let a = &*ptr;
3008- ptr = ptr.add(1);
3009- let b = &*ptr;
3010-
3011- i += 1;
3012-
3013- if !(self.predicate)(a, b) {
3014- let slice = $mkslice(self.ptr, i);
3015- self.ptr = ptr;
3016- return Some(slice)
3017- }
3018- }
3019-
3020- // `i` is either `0` or the slice `length - 1` because either:
3021- // - we have not entered the loop and so `i` is equal to `0`
3022- // the slice length is necessarily `1` because we ensure it is not empty
3023- // - we have entered the loop and we have not early returned
3024- // so `i` is equal to the slice `length - 1`
3025- let slice = $mkslice(self.ptr, i + 1);
3026- self.ptr = self.end;
3027- Some(slice)
3028- }
3029- }
3030-
3031- fn size_hint(&self) -> (usize, Option<usize>) {
3032- if self.is_empty() { return (0, Some(0)) }
3033- let len = self.remaining_len();
3034- (1, Some(len))
3035- }
3036-
3037- fn last(mut self) -> Option<Self::Item> {
3038- self.next_back()
3039- }
3040- }
3041-
3042- #[unstable(feature = "slice_group_by", issue = "0")]
3043- impl<'a, T: 'a, P> DoubleEndedIterator for $name<'a, T, P>
3044- where P: FnMut(&T, &T) -> bool,
3045- {
3046- fn next_back(&mut self) -> Option<Self::Item> {
3047- // during the loop we retrieve two elements at `ptr` and `ptr - 1`.
3048- unsafe {
3049- if self.is_empty() { return None }
3050-
3051- let mut i = 0;
3052- // we ensure that the first element that will be read
3053- // is not under `end` because `end` is out of bound.
3054- let mut ptr = self.end.sub(1);
3055-
3056- while ptr != self.ptr {
3057- // we first get `a` that is at the left of `ptr`
3058- // then `b` that is under the `ptr` position.
3059- let a = &*ptr.sub(1);
3060- let b = &*ptr;
3061-
3062- i += 1;
3063-
3064- if !(self.predicate)(a, b) {
3065- // the slice to return starts at the `ptr` position
3066- // and `i` is the length of it.
3067- let slice = $mkslice(ptr, i);
3068-
3069- // because `end` is always an invalid bound
3070- // we use `ptr` as `end` for the future call to `next`.
3071- self.end = ptr;
3072- return Some(slice)
3073- }
3074-
3075- ptr = ptr.sub(1);
3076- }
3077-
3078- let slice = $mkslice(self.ptr, i + 1);
3079- self.ptr = self.end;
3080- Some(slice)
3081- }
3082- }
3083- }
3084-
3085- #[unstable(feature = "slice_group_by", issue = "0")]
3086- impl<'a, T: 'a, P> FusedIterator for $name<'a, T, P>
3087- where P: FnMut(&T, &T) -> bool,
3088- { }
3089- }
3090- }
3091-
30922971/// An iterator over slice in (non-overlapping) chunks separated by a predicate.
30932972///
30942973/// This struct is created by the [`group_by`] method on [slices].
@@ -3098,25 +2977,65 @@ macro_rules! group_by {
30982977#[unstable(feature = "slice_group_by", issue = "0")]
30992978#[derive(Debug)] // FIXME implement Debug to be more user friendly
31002979pub struct GroupBy<'a, T: 'a, P> {
3101- ptr: *const T,
3102- end: *const T,
2980+ slice: &'a [T],
31032981 predicate: P,
3104- _phantom: marker::PhantomData<&'a T>,
31052982}
31062983
31072984#[unstable(feature = "slice_group_by", issue = "0")]
3108- impl<'a, T: 'a, P> GroupBy<'a, T, P>
2985+ impl<'a, T: 'a, P> GroupBy<'a, T, P> {
2986+ pub(super) fn new(slice: &'a [T], predicate: P) -> Self {
2987+ GroupBy { slice, predicate }
2988+ }
2989+ }
2990+
2991+ #[unstable(feature = "slice_group_by", issue = "0")]
2992+ impl<'a, T: 'a, P> Iterator for GroupBy<'a, T, P>
31092993where P: FnMut(&T, &T) -> bool,
31102994{
3111- /// Returns the remainder of the original slice that is going to be
3112- /// returned by the iterator.
3113- pub fn remaining(&self) -> &[T] {
3114- let len = self.remaining_len();
3115- unsafe { from_raw_parts(self.ptr, len) }
2995+ type Item = &'a [T];
2996+
2997+ #[inline]
2998+ fn next(&mut self) -> Option<Self::Item> {
2999+ if self.slice.is_empty() {
3000+ None
3001+ } else {
3002+ let mut len = 1;
3003+ let mut iter = self.slice.windows(2);
3004+ while let Some([l, r]) = iter.next() {
3005+ if (self.predicate)(l, r) { len += 1 } else { break }
3006+ }
3007+ let (head, tail) = self.slice.split_at(len);
3008+ self.slice = tail;
3009+ Some(head)
3010+ }
31163011 }
31173012}
31183013
3119- group_by!{ struct GroupBy, &'a [T], from_raw_parts }
3014+ #[unstable(feature = "slice_group_by", issue = "0")]
3015+ impl<'a, T: 'a, P> DoubleEndedIterator for GroupBy<'a, T, P>
3016+ where P: FnMut(&T, &T) -> bool,
3017+ {
3018+ #[inline]
3019+ fn next_back(&mut self) -> Option<Self::Item> {
3020+ if self.slice.is_empty() {
3021+ None
3022+ } else {
3023+ let mut len = 1;
3024+ let mut iter = self.slice.windows(2);
3025+ while let Some([l, r]) = iter.next_back() {
3026+ if (self.predicate)(l, r) { len += 1 } else { break }
3027+ }
3028+ let (head, tail) = self.slice.split_at(self.slice.len() - len);
3029+ self.slice = head;
3030+ Some(tail)
3031+ }
3032+ }
3033+ }
3034+
3035+ #[unstable(feature = "slice_group_by", issue = "0")]
3036+ impl<'a, T: 'a, P> FusedIterator for GroupBy<'a, T, P>
3037+ where P: FnMut(&T, &T) -> bool,
3038+ { }
31203039
31213040/// An iterator over slice in (non-overlapping) mutable chunks separated
31223041/// by a predicate.
@@ -3128,22 +3047,59 @@ group_by!{ struct GroupBy, &'a [T], from_raw_parts }
31283047#[unstable(feature = "slice_group_by", issue = "0")]
31293048#[derive(Debug)] // FIXME implement Debug to be more user friendly
31303049pub struct GroupByMut<'a, T: 'a, P> {
3131- ptr: *mut T,
3132- end: *mut T,
3050+ slice: &'a mut [T],
31333051 predicate: P,
3134- _phantom: marker::PhantomData<&'a T>,
31353052}
31363053
31373054#[unstable(feature = "slice_group_by", issue = "0")]
3138- impl<'a, T: 'a, P> GroupByMut<'a, T, P>
3055+ impl<'a, T: 'a, P> GroupByMut<'a, T, P> {
3056+ pub(super) fn new(slice: &'a mut [T], predicate: P) -> Self {
3057+ GroupByMut { slice, predicate }
3058+ }
3059+ }
3060+
3061+ #[unstable(feature = "slice_group_by", issue = "0")]
3062+ impl<'a, T: 'a, P> Iterator for GroupByMut<'a, T, P>
31393063where P: FnMut(&T, &T) -> bool,
31403064{
3141- /// Returns the remainder of the original slice that is going to be
3142- /// returned by the iterator.
3143- pub fn into_remaining(self) -> &'a mut [T] {
3144- let len = self.remaining_len();
3145- unsafe { from_raw_parts_mut(self.ptr, len) }
3065+ type Item = &'a mut [T];
3066+
3067+ #[inline]
3068+ fn next(&mut self) -> Option<Self::Item> {
3069+ if self.slice.is_empty() {
3070+ None
3071+ } else {
3072+ let mut len = 1;
3073+ let mut iter = self.slice.windows(2);
3074+ while let Some([l, r]) = iter.next() {
3075+ if (self.predicate)(l, r) { len += 1 } else { break }
3076+ }
3077+ let slice = mem::take(&mut self.slice);
3078+ let (head, tail) = slice.split_at_mut(len);
3079+ self.slice = tail;
3080+ Some(head)
3081+ }
31463082 }
31473083}
31483084
3149- group_by!{ struct GroupByMut, &'a mut [T], from_raw_parts_mut }
3085+ #[unstable(feature = "slice_group_by", issue = "0")]
3086+ impl<'a, T: 'a, P> DoubleEndedIterator for GroupByMut<'a, T, P>
3087+ where P: FnMut(&T, &T) -> bool,
3088+ {
3089+ #[inline]
3090+ fn next_back(&mut self) -> Option<Self::Item> {
3091+ if self.slice.is_empty() {
3092+ None
3093+ } else {
3094+ let mut len = 1;
3095+ let mut iter = self.slice.windows(2);
3096+ while let Some([l, r]) = iter.next_back() {
3097+ if (self.predicate)(l, r) { len += 1 } else { break }
3098+ }
3099+ let slice = mem::take(&mut self.slice);
3100+ let (head, tail) = slice.split_at_mut(slice.len() - len);
3101+ self.slice = head;
3102+ Some(tail)
3103+ }
3104+ }
3105+ }
0 commit comments