@@ -640,6 +640,129 @@ where
640
640
#[ stable( feature = "split_inclusive" , since = "1.51.0" ) ]
641
641
impl < T , P > FusedIterator for SplitInclusive < ' _ , T , P > where P : FnMut ( & T ) -> bool { }
642
642
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
+
643
766
/// An iterator over the mutable subslices of the vector which are separated
644
767
/// by elements that match `pred`.
645
768
///
@@ -894,6 +1017,133 @@ where
894
1017
#[ stable( feature = "split_inclusive" , since = "1.51.0" ) ]
895
1018
impl < T , P > FusedIterator for SplitInclusiveMut < ' _ , T , P > where P : FnMut ( & T ) -> bool { }
896
1019
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
+
897
1147
/// An iterator over subslices separated by elements that match a predicate
898
1148
/// function, starting from the end of the slice.
899
1149
///
0 commit comments