@@ -640,6 +640,129 @@ where
640640#[ stable( feature = "split_inclusive" , since = "1.51.0" ) ]
641641impl < T , P > FusedIterator for SplitInclusive < ' _ , T , P > where P : FnMut ( & T ) -> bool { }
642642
643+ /// An iterator over subslices separated by elements that match a predicate
644+ /// function. Unlike `Split`, it contains the matched part as an initiator
645+ /// of the subslice.
646+ ///
647+ /// This struct is created by the [`split_left_inclusive`] method on [slices].
648+ ///
649+ /// # Example
650+ ///
651+ /// ```
652+ /// #![feature(split_left_inclusive)]
653+ ///
654+ /// let slice = [10, 40, 33, 20];
655+ /// let mut iter = slice.split_left_inclusive(|num| num % 3 == 0);
656+ /// ```
657+ ///
658+ /// [`split_left_inclusive`]: slice::split_left_inclusive
659+ /// [slices]: slice
660+ #[ unstable( feature = "split_left_inclusive" , issue = "none" ) ]
661+ pub struct SplitLeftInclusive < ' a , T : ' a , P >
662+ where
663+ P : FnMut ( & T ) -> bool ,
664+ {
665+ v : & ' a [ T ] ,
666+ pred : P ,
667+ finished : bool ,
668+ }
669+
670+ impl < ' a , T : ' a , P : FnMut ( & T ) -> bool > SplitLeftInclusive < ' a , T , P > {
671+ #[ inline]
672+ pub ( super ) fn new ( slice : & ' a [ T ] , pred : P ) -> Self {
673+ Self { v : slice, pred, finished : false }
674+ }
675+ }
676+
677+ #[ unstable( feature = "split_left_inclusive" , issue = "none" ) ]
678+ impl < T : fmt:: Debug , P > fmt:: Debug for SplitLeftInclusive < ' _ , T , P >
679+ where
680+ P : FnMut ( & T ) -> bool ,
681+ {
682+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
683+ f. debug_struct ( "SplitLeftInclusive" )
684+ . field ( "v" , & self . v )
685+ . field ( "finished" , & self . finished )
686+ . finish ( )
687+ }
688+ }
689+
690+ // FIXME(#26925) Remove in favor of `#[derive(Clone)]`
691+ #[ unstable( feature = "split_left_inclusive" , issue = "none" ) ]
692+ impl < T , P > Clone for SplitLeftInclusive < ' _ , T , P >
693+ where
694+ P : Clone + FnMut ( & T ) -> bool ,
695+ {
696+ fn clone ( & self ) -> Self {
697+ SplitLeftInclusive { v : self . v , pred : self . pred . clone ( ) , finished : self . finished }
698+ }
699+ }
700+
701+ #[ unstable( feature = "split_left_inclusive" , issue = "none" ) ]
702+ impl < ' a , T , P > Iterator for SplitLeftInclusive < ' a , T , P >
703+ where
704+ P : FnMut ( & T ) -> bool ,
705+ {
706+ type Item = & ' a [ T ] ;
707+
708+ #[ inline]
709+ fn next ( & mut self ) -> Option < & ' a [ T ] > {
710+ if self . finished {
711+ return None ;
712+ }
713+
714+ // The first index of self.v is already checked and found to match
715+ // by the last iteration, so we start searching a new match
716+ // one index to the right.
717+ let remainder = if self . v . is_empty ( ) { & [ ] } else { & self . v [ 1 ..] } ;
718+ let idx =
719+ remainder. iter ( ) . position ( |x| ( self . pred ) ( x) ) . map ( |x| x + 1 ) . unwrap_or ( self . v . len ( ) ) ;
720+ if idx == self . v . len ( ) {
721+ self . finished = true ;
722+ }
723+
724+ let ret = Some ( & self . v [ ..idx] ) ;
725+ self . v = & self . v [ idx..] ;
726+ ret
727+ }
728+
729+ #[ inline]
730+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
731+ if self . finished {
732+ ( 0 , Some ( 0 ) )
733+ } else {
734+ // If the predicate doesn't match anything, we yield one slice.
735+ // If it matches every element, we yield `len()` one-element slices,
736+ // or a single empty slice.
737+ ( 1 , Some ( cmp:: max ( 1 , self . v . len ( ) ) ) )
738+ }
739+ }
740+ }
741+
742+ #[ unstable( feature = "split_left_inclusive" , issue = "none" ) ]
743+ impl < ' a , T , P > DoubleEndedIterator for SplitLeftInclusive < ' a , T , P >
744+ where
745+ P : FnMut ( & T ) -> bool ,
746+ {
747+ #[ inline]
748+ fn next_back ( & mut self ) -> Option < & ' a [ T ] > {
749+ if self . finished {
750+ return None ;
751+ }
752+
753+ let idx = self . v . iter ( ) . rposition ( |x| ( self . pred ) ( x) ) . unwrap_or ( 0 ) ;
754+ if idx == 0 {
755+ self . finished = true ;
756+ }
757+ let ret = Some ( & self . v [ idx..] ) ;
758+ self . v = & self . v [ ..idx] ;
759+ ret
760+ }
761+ }
762+
763+ #[ unstable( feature = "split_left_inclusive" , issue = "none" ) ]
764+ impl < T , P > FusedIterator for SplitLeftInclusive < ' _ , T , P > where P : FnMut ( & T ) -> bool { }
765+
643766/// An iterator over the mutable subslices of the vector which are separated
644767/// by elements that match `pred`.
645768///
@@ -894,6 +1017,133 @@ where
8941017#[ stable( feature = "split_inclusive" , since = "1.51.0" ) ]
8951018impl < T , P > FusedIterator for SplitInclusiveMut < ' _ , T , P > where P : FnMut ( & T ) -> bool { }
8961019
1020+ /// An iterator over the mutable subslices of the vector which are separated
1021+ /// by elements that match `pred`. Unlike `SplitMut`, it contains the matched
1022+ /// parts in the beginnings of the subslices.
1023+ ///
1024+ /// This struct is created by the [`split_left_inclusive_mut`] method on
1025+ /// [slices].
1026+ ///
1027+ /// # Example
1028+ ///
1029+ /// ```
1030+ /// #![feature(split_left_inclusive)]
1031+ ///
1032+ /// let mut v = [10, 40, 30, 20, 60, 50];
1033+ /// let iter = v.split_left_inclusive_mut(|num| *num % 3 == 0);
1034+ /// ```
1035+ ///
1036+ /// [`split_left_inclusive_mut`]: slice::split_left_inclusive_mut
1037+ /// [slices]: slice
1038+ #[ unstable( feature = "split_left_inclusive" , issue = "none" ) ]
1039+ pub struct SplitLeftInclusiveMut < ' a , T : ' a , P >
1040+ where
1041+ P : FnMut ( & T ) -> bool ,
1042+ {
1043+ v : & ' a mut [ T ] ,
1044+ pred : P ,
1045+ finished : bool ,
1046+ }
1047+
1048+ impl < ' a , T : ' a , P : FnMut ( & T ) -> bool > SplitLeftInclusiveMut < ' a , T , P > {
1049+ #[ inline]
1050+ pub ( super ) fn new ( slice : & ' a mut [ T ] , pred : P ) -> Self {
1051+ Self { v : slice, pred, finished : false }
1052+ }
1053+ }
1054+
1055+ #[ unstable( feature = "split_left_inclusive" , issue = "none" ) ]
1056+ impl < T : fmt:: Debug , P > fmt:: Debug for SplitLeftInclusiveMut < ' _ , T , P >
1057+ where
1058+ P : FnMut ( & T ) -> bool ,
1059+ {
1060+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1061+ f. debug_struct ( "SplitLeftInclusiveMut" )
1062+ . field ( "v" , & self . v )
1063+ . field ( "finished" , & self . finished )
1064+ . finish ( )
1065+ }
1066+ }
1067+
1068+ #[ unstable( feature = "split_left_inclusive" , issue = "none" ) ]
1069+ impl < ' a , T , P > Iterator for SplitLeftInclusiveMut < ' a , T , P >
1070+ where
1071+ P : FnMut ( & T ) -> bool ,
1072+ {
1073+ type Item = & ' a mut [ T ] ;
1074+
1075+ #[ inline]
1076+ fn next ( & mut self ) -> Option < & ' a mut [ T ] > {
1077+ if self . finished {
1078+ return None ;
1079+ }
1080+
1081+ let idx_opt = {
1082+ // work around borrowck limitations
1083+ let pred = & mut self . pred ;
1084+
1085+ // The first index of self.v is already checked and found to match
1086+ // by the last iteration, so we start searching a new match
1087+ // one index to the right.
1088+ let remainder = if self . v . is_empty ( ) { & [ ] } else { & self . v [ 1 ..] } ;
1089+ remainder. iter ( ) . position ( |x| ( * pred) ( x) ) . map ( |x| x + 1 )
1090+ } ;
1091+ let idx = idx_opt. unwrap_or ( self . v . len ( ) ) ;
1092+ if idx == self . v . len ( ) {
1093+ self . finished = true ;
1094+ }
1095+ let tmp = mem:: replace ( & mut self . v , & mut [ ] ) ;
1096+ let ( head, tail) = tmp. split_at_mut ( idx) ;
1097+ self . v = tail;
1098+ Some ( head)
1099+ }
1100+
1101+ #[ inline]
1102+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
1103+ if self . finished {
1104+ ( 0 , Some ( 0 ) )
1105+ } else {
1106+ // If the predicate doesn't match anything, we yield one slice.
1107+ // If it matches every element, we yield `len()` one-element slices,
1108+ // or a single empty slice.
1109+ ( 1 , Some ( cmp:: max ( 1 , self . v . len ( ) ) ) )
1110+ }
1111+ }
1112+ }
1113+
1114+ #[ unstable( feature = "split_left_inclusive" , issue = "none" ) ]
1115+ impl < ' a , T , P > DoubleEndedIterator for SplitLeftInclusiveMut < ' a , T , P >
1116+ where
1117+ P : FnMut ( & T ) -> bool ,
1118+ {
1119+ #[ inline]
1120+ fn next_back ( & mut self ) -> Option < & ' a mut [ T ] > {
1121+ if self . finished {
1122+ return None ;
1123+ }
1124+
1125+ let idx_opt = if self . v . is_empty ( ) {
1126+ None
1127+ } else {
1128+ // work around borrowsck limitations
1129+ let pred = & mut self . pred ;
1130+
1131+ self . v . iter ( ) . rposition ( |x| ( * pred) ( x) )
1132+ } ;
1133+ let idx = idx_opt. unwrap_or ( 0 ) ;
1134+ if idx == 0 {
1135+ self . finished = true ;
1136+ }
1137+ let tmp = mem:: replace ( & mut self . v , & mut [ ] ) ;
1138+ let ( head, tail) = tmp. split_at_mut ( idx) ;
1139+ self . v = head;
1140+ Some ( tail)
1141+ }
1142+ }
1143+
1144+ #[ unstable( feature = "split_left_inclusive" , issue = "none" ) ]
1145+ impl < T , P > FusedIterator for SplitLeftInclusiveMut < ' _ , T , P > where P : FnMut ( & T ) -> bool { }
1146+
8971147/// An iterator over subslices separated by elements that match a predicate
8981148/// function, starting from the end of the slice.
8991149///
0 commit comments