@@ -2967,3 +2967,183 @@ unsafe impl<'a, T> TrustedRandomAccess for IterMut<'a, T> {
29672967 false
29682968 }
29692969}
2970+
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+
3092+ /// An iterator over slice in (non-overlapping) chunks separated by a predicate.
3093+ ///
3094+ /// This struct is created by the [`group_by`] method on [slices].
3095+ ///
3096+ /// [`group_by`]: ../../std/primitive.slice.html#method.group_by
3097+ /// [slices]: ../../std/primitive.slice.html
3098+ #[ unstable( feature = "slice_group_by" , issue = "0" ) ]
3099+ #[ derive( Debug ) ] // FIXME implement Debug to be more user friendly
3100+ pub struct GroupBy < ' a , T : ' a , P > {
3101+ ptr : * const T ,
3102+ end : * const T ,
3103+ predicate : P ,
3104+ _phantom : marker:: PhantomData < & ' a T > ,
3105+ }
3106+
3107+ #[ unstable( feature = "slice_group_by" , issue = "0" ) ]
3108+ impl < ' a , T : ' a , P > GroupBy < ' a , T , P >
3109+ where P : FnMut ( & T , & T ) -> bool ,
3110+ {
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) }
3116+ }
3117+ }
3118+
3119+ group_by ! { struct GroupBy , & ' a [ T ] , from_raw_parts }
3120+
3121+ /// An iterator over slice in (non-overlapping) mutable chunks separated
3122+ /// by a predicate.
3123+ ///
3124+ /// This struct is created by the [`group_by_mut`] method on [slices].
3125+ ///
3126+ /// [`group_by_mut`]: ../../std/primitive.slice.html#method.group_by_mut
3127+ /// [slices]: ../../std/primitive.slice.html
3128+ #[ unstable( feature = "slice_group_by" , issue = "0" ) ]
3129+ #[ derive( Debug ) ] // FIXME implement Debug to be more user friendly
3130+ pub struct GroupByMut < ' a , T : ' a , P > {
3131+ ptr : * mut T ,
3132+ end : * mut T ,
3133+ predicate : P ,
3134+ _phantom : marker:: PhantomData < & ' a T > ,
3135+ }
3136+
3137+ #[ unstable( feature = "slice_group_by" , issue = "0" ) ]
3138+ impl < ' a , T : ' a , P > GroupByMut < ' a , T , P >
3139+ where P : FnMut ( & T , & T ) -> bool ,
3140+ {
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) }
3146+ }
3147+ }
3148+
3149+ group_by ! { struct GroupByMut , & ' a mut [ T ] , from_raw_parts_mut }
0 commit comments