@@ -1155,6 +1155,72 @@ impl<T> [T] {
11551155 SplitMut { v : self , pred, finished : false }
11561156 }
11571157
1158+ /// Returns an iterator over subslices separated by elements that match
1159+ /// `pred`. The matched element is contained in the end of the previous
1160+ /// subslice as a terminator.
1161+ ///
1162+ /// # Examples
1163+ ///
1164+ /// ```
1165+ /// #![feature(split_inclusive)]
1166+ /// let slice = [10, 40, 33, 20];
1167+ /// let mut iter = slice.split_inclusive(|num| num % 3 == 0);
1168+ ///
1169+ /// assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
1170+ /// assert_eq!(iter.next().unwrap(), &[20]);
1171+ /// assert!(iter.next().is_none());
1172+ /// ```
1173+ ///
1174+ /// If the first element is matched, an empty slice will be the first item
1175+ /// returned by the iterator. Similarly, if the last element in the slice
1176+ /// is matched, an empty slice will be the last item returned by the
1177+ /// iterator:
1178+ ///
1179+ /// ```
1180+ /// #![feature(split_inclusive)]
1181+ /// let slice = [10, 40, 33];
1182+ /// let mut iter = slice.split_inclusive(|num| num % 3 == 0);
1183+ ///
1184+ /// assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
1185+ /// assert_eq!(iter.next().unwrap(), &[]);
1186+ /// assert!(iter.next().is_none());
1187+ /// ```
1188+ #[ unstable( feature = "split_inclusive" , issue = "0" ) ]
1189+ #[ inline]
1190+ pub fn split_inclusive < F > ( & self , pred : F ) -> SplitInclusive < ' _ , T , F >
1191+ where F : FnMut ( & T ) -> bool
1192+ {
1193+ SplitInclusive {
1194+ v : self ,
1195+ pred,
1196+ finished : false
1197+ }
1198+ }
1199+
1200+ /// Returns an iterator over mutable subslices separated by elements that
1201+ /// match `pred`. The matched element is contained in the previous
1202+ /// subslice as a terminator.
1203+ ///
1204+ /// # Examples
1205+ ///
1206+ /// ```
1207+ /// #![feature(split_inclusive)]
1208+ /// let mut v = [10, 40, 30, 20, 60, 50];
1209+ ///
1210+ /// for group in v.split_inclusive_mut(|num| *num % 3 == 0) {
1211+ /// let terminator_idx = group.len()-1;
1212+ /// group[terminator_idx] = 1;
1213+ /// }
1214+ /// assert_eq!(v, [10, 40, 1, 20, 1, 1]);
1215+ /// ```
1216+ #[ unstable( feature = "split_inclusive" , issue = "0" ) ]
1217+ #[ inline]
1218+ pub fn split_inclusive_mut < F > ( & mut self , pred : F ) -> SplitInclusiveMut < ' _ , T , F >
1219+ where F : FnMut ( & T ) -> bool
1220+ {
1221+ SplitInclusiveMut { v : self , pred, finished : false }
1222+ }
1223+
11581224 /// Returns an iterator over subslices separated by elements that match
11591225 /// `pred`, starting at the end of the slice and working backwards.
11601226 /// The matched element is not contained in the subslices.
@@ -3675,7 +3741,100 @@ where
36753741#[ stable( feature = "fused" , since = "1.26.0" ) ]
36763742impl < T , P > FusedIterator for Split < ' _ , T , P > where P : FnMut ( & T ) -> bool { }
36773743
3678- /// An iterator over the subslices of the vector which are separated
3744+ /// An iterator over subslices separated by elements that match a predicate
3745+ /// function. Unlike `Split`, it contains the matched part as a terminator
3746+ /// of the subslice.
3747+ ///
3748+ /// This struct is created by the [`split_inclusive`] method on [slices].
3749+ ///
3750+ /// [`split_inclusive`]: ../../std/primitive.slice.html#method.split_inclusive
3751+ /// [slices]: ../../std/primitive.slice.html
3752+ #[ unstable( feature = "split_inclusive" , issue = "0" ) ]
3753+ pub struct SplitInclusive < ' a , T : ' a , P > where P : FnMut ( & T ) -> bool {
3754+ v : & ' a [ T ] ,
3755+ pred : P ,
3756+ finished : bool
3757+ }
3758+
3759+ #[ unstable( feature = "split_inclusive" , issue = "0" ) ]
3760+ impl < T : fmt:: Debug , P > fmt:: Debug for SplitInclusive < ' _ , T , P > where P : FnMut ( & T ) -> bool {
3761+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
3762+ f. debug_struct ( "SplitInclusive" )
3763+ . field ( "v" , & self . v )
3764+ . field ( "finished" , & self . finished )
3765+ . finish ( )
3766+ }
3767+ }
3768+
3769+ // FIXME(#26925) Remove in favor of `#[derive(Clone)]`
3770+ #[ unstable( feature = "split_inclusive" , issue = "0" ) ]
3771+ impl < T , P > Clone for SplitInclusive < ' _ , T , P > where P : Clone + FnMut ( & T ) -> bool {
3772+ fn clone ( & self ) -> Self {
3773+ SplitInclusive {
3774+ v : self . v ,
3775+ pred : self . pred . clone ( ) ,
3776+ finished : self . finished ,
3777+ }
3778+ }
3779+ }
3780+
3781+ #[ unstable( feature = "split_inclusive" , issue = "0" ) ]
3782+ impl < ' a , T , P > Iterator for SplitInclusive < ' a , T , P > where P : FnMut ( & T ) -> bool {
3783+ type Item = & ' a [ T ] ;
3784+
3785+ #[ inline]
3786+ fn next ( & mut self ) -> Option < & ' a [ T ] > {
3787+ if self . finished { return None ; }
3788+
3789+ match self . v . iter ( ) . position ( |x| ( self . pred ) ( x) ) {
3790+ None => self . finish ( ) ,
3791+ Some ( idx) => {
3792+ let ret = Some ( & self . v [ ..idx + 1 ] ) ;
3793+ self . v = & self . v [ idx + 1 ..] ;
3794+ ret
3795+ }
3796+ }
3797+ }
3798+
3799+ #[ inline]
3800+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
3801+ if self . finished {
3802+ ( 0 , Some ( 0 ) )
3803+ } else {
3804+ ( 1 , Some ( self . v . len ( ) + 1 ) )
3805+ }
3806+ }
3807+ }
3808+
3809+ #[ unstable( feature = "split_inclusive" , issue = "0" ) ]
3810+ impl < ' a , T , P > DoubleEndedIterator for SplitInclusive < ' a , T , P > where P : FnMut ( & T ) -> bool {
3811+ #[ inline]
3812+ fn next_back ( & mut self ) -> Option < & ' a [ T ] > {
3813+ if self . finished { return None ; }
3814+
3815+ match self . v . iter ( ) . rposition ( |x| ( self . pred ) ( x) ) {
3816+ None => self . finish ( ) ,
3817+ Some ( idx) => {
3818+ let ret = Some ( & self . v [ idx + 1 ..] ) ;
3819+ self . v = & self . v [ ..idx] ;
3820+ ret
3821+ }
3822+ }
3823+ }
3824+ }
3825+
3826+ #[ unstable( feature = "split_inclusive" , issue = "0" ) ]
3827+ impl < ' a , T , P > SplitIter for SplitInclusive < ' a , T , P > where P : FnMut ( & T ) -> bool {
3828+ #[ inline]
3829+ fn finish ( & mut self ) -> Option < & ' a [ T ] > {
3830+ if self . finished { None } else { self . finished = true ; Some ( self . v ) }
3831+ }
3832+ }
3833+
3834+ #[ unstable( feature = "split_inclusive" , issue = "0" ) ]
3835+ impl < T , P > FusedIterator for SplitInclusive < ' _ , T , P > where P : FnMut ( & T ) -> bool { }
3836+
3837+ /// An iterator over the mutable subslices of the vector which are separated
36793838/// by elements that match `pred`.
36803839///
36813840/// This struct is created by the [`split_mut`] method on [slices].
@@ -3789,6 +3948,106 @@ where
37893948#[ stable( feature = "fused" , since = "1.26.0" ) ]
37903949impl < T , P > FusedIterator for SplitMut < ' _ , T , P > where P : FnMut ( & T ) -> bool { }
37913950
3951+ /// An iterator over the mutable subslices of the vector which are separated
3952+ /// by elements that match `pred`. Unlike `SplitMut`, it contains the matched
3953+ /// parts in the ends of the subslices.
3954+ ///
3955+ /// This struct is created by the [`split_inclusive_mut`] method on [slices].
3956+ ///
3957+ /// [`split_inclusive_mut`]: ../../std/primitive.slice.html#method.split_inclusive_mut
3958+ /// [slices]: ../../std/primitive.slice.html
3959+ #[ unstable( feature = "split_inclusive" , issue = "0" ) ]
3960+ pub struct SplitInclusiveMut < ' a , T : ' a , P > where P : FnMut ( & T ) -> bool {
3961+ v : & ' a mut [ T ] ,
3962+ pred : P ,
3963+ finished : bool
3964+ }
3965+
3966+ #[ unstable( feature = "split_inclusive" , issue = "0" ) ]
3967+ impl < T : fmt:: Debug , P > fmt:: Debug for SplitInclusiveMut < ' _ , T , P > where P : FnMut ( & T ) -> bool {
3968+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
3969+ f. debug_struct ( "SplitInclusiveMut" )
3970+ . field ( "v" , & self . v )
3971+ . field ( "finished" , & self . finished )
3972+ . finish ( )
3973+ }
3974+ }
3975+
3976+ #[ unstable( feature = "split_inclusive" , issue = "0" ) ]
3977+ impl < ' a , T , P > SplitIter for SplitInclusiveMut < ' a , T , P > where P : FnMut ( & T ) -> bool {
3978+ #[ inline]
3979+ fn finish ( & mut self ) -> Option < & ' a mut [ T ] > {
3980+ if self . finished {
3981+ None
3982+ } else {
3983+ self . finished = true ;
3984+ Some ( mem:: replace ( & mut self . v , & mut [ ] ) )
3985+ }
3986+ }
3987+ }
3988+
3989+ #[ unstable( feature = "split_inclusive" , issue = "0" ) ]
3990+ impl < ' a , T , P > Iterator for SplitInclusiveMut < ' a , T , P > where P : FnMut ( & T ) -> bool {
3991+ type Item = & ' a mut [ T ] ;
3992+
3993+ #[ inline]
3994+ fn next ( & mut self ) -> Option < & ' a mut [ T ] > {
3995+ if self . finished { return None ; }
3996+
3997+ let idx_opt = { // work around borrowck limitations
3998+ let pred = & mut self . pred ;
3999+ self . v . iter ( ) . position ( |x| ( * pred) ( x) )
4000+ } ;
4001+ match idx_opt {
4002+ None => self . finish ( ) ,
4003+ Some ( idx) => {
4004+ let tmp = mem:: replace ( & mut self . v , & mut [ ] ) ;
4005+ let ( head, tail) = tmp. split_at_mut ( idx+1 ) ;
4006+ self . v = tail;
4007+ Some ( head)
4008+ }
4009+ }
4010+ }
4011+
4012+ #[ inline]
4013+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
4014+ if self . finished {
4015+ ( 0 , Some ( 0 ) )
4016+ } else {
4017+ // if the predicate doesn't match anything, we yield one slice
4018+ // if it matches every element, we yield len+1 empty slices.
4019+ ( 1 , Some ( self . v . len ( ) + 1 ) )
4020+ }
4021+ }
4022+ }
4023+
4024+ #[ unstable( feature = "split_inclusive" , issue = "0" ) ]
4025+ impl < ' a , T , P > DoubleEndedIterator for SplitInclusiveMut < ' a , T , P > where
4026+ P : FnMut ( & T ) -> bool ,
4027+ {
4028+ #[ inline]
4029+ fn next_back ( & mut self ) -> Option < & ' a mut [ T ] > {
4030+ if self . finished { return None ; }
4031+
4032+ let idx_opt = { // work around borrowck limitations
4033+ let pred = & mut self . pred ;
4034+ self . v . iter ( ) . rposition ( |x| ( * pred) ( x) )
4035+ } ;
4036+ match idx_opt {
4037+ None => self . finish ( ) ,
4038+ Some ( idx) => {
4039+ let tmp = mem:: replace ( & mut self . v , & mut [ ] ) ;
4040+ let ( head, tail) = tmp. split_at_mut ( idx+1 ) ;
4041+ self . v = head;
4042+ Some ( tail)
4043+ }
4044+ }
4045+ }
4046+ }
4047+
4048+ #[ unstable( feature = "split_inclusive" , issue = "0" ) ]
4049+ impl < T , P > FusedIterator for SplitInclusiveMut < ' _ , T , P > where P : FnMut ( & T ) -> bool { }
4050+
37924051/// An iterator over subslices separated by elements that match a predicate
37934052/// function, starting from the end of the slice.
37944053///
0 commit comments