@@ -1155,6 +1155,72 @@ impl<T> [T] {
1155
1155
SplitMut { v : self , pred, finished : false }
1156
1156
}
1157
1157
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
+
1158
1224
/// Returns an iterator over subslices separated by elements that match
1159
1225
/// `pred`, starting at the end of the slice and working backwards.
1160
1226
/// The matched element is not contained in the subslices.
@@ -3675,7 +3741,100 @@ where
3675
3741
#[ stable( feature = "fused" , since = "1.26.0" ) ]
3676
3742
impl < T , P > FusedIterator for Split < ' _ , T , P > where P : FnMut ( & T ) -> bool { }
3677
3743
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
3679
3838
/// by elements that match `pred`.
3680
3839
///
3681
3840
/// This struct is created by the [`split_mut`] method on [slices].
@@ -3789,6 +3948,106 @@ where
3789
3948
#[ stable( feature = "fused" , since = "1.26.0" ) ]
3790
3949
impl < T , P > FusedIterator for SplitMut < ' _ , T , P > where P : FnMut ( & T ) -> bool { }
3791
3950
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
+
3792
4051
/// An iterator over subslices separated by elements that match a predicate
3793
4052
/// function, starting from the end of the slice.
3794
4053
///
0 commit comments