@@ -111,7 +111,24 @@ macro_rules! delegate_iter {
111
111
self . 0 . size_hint( )
112
112
}
113
113
}
114
- }
114
+ } ;
115
+ ( pattern reverse $te: ty : $ti: ty) => {
116
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
117
+ impl <' a, P : Pattern <' a>> Iterator for $ti
118
+ where P :: Searcher : ReverseSearcher <' a>
119
+ {
120
+ type Item = $te;
121
+
122
+ #[ inline]
123
+ fn next( & mut self ) -> Option <$te> {
124
+ self . 0 . next( )
125
+ }
126
+ #[ inline]
127
+ fn size_hint( & self ) -> ( usize , Option <usize >) {
128
+ self . 0 . size_hint( )
129
+ }
130
+ }
131
+ } ;
115
132
}
116
133
117
134
/// A trait to abstract the idea of creating a new instance of a type from a
@@ -553,6 +570,19 @@ struct CharSplitsN<'a, P: Pattern<'a>> {
553
570
invert : bool ,
554
571
}
555
572
573
+ /// An iterator over the substrings of a string, separated by a
574
+ /// pattern, in reverse order.
575
+ struct RCharSplits < ' a , P : Pattern < ' a > > {
576
+ /// The slice remaining to be iterated
577
+ start : usize ,
578
+ end : usize ,
579
+ matcher : P :: Searcher ,
580
+ /// Whether an empty string at the end of iteration is allowed
581
+ allow_final_empty : bool ,
582
+ finished : bool ,
583
+ }
584
+
585
+
556
586
/// An iterator over the lines of a string, separated by `\n`.
557
587
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
558
588
pub struct Lines < ' a > {
@@ -646,6 +676,43 @@ where P::Searcher: DoubleEndedSearcher<'a> {
646
676
}
647
677
}
648
678
679
+ impl < ' a , P : Pattern < ' a > > RCharSplits < ' a , P > {
680
+ #[ inline]
681
+ fn get_remainder ( & mut self ) -> Option < & ' a str > {
682
+ if !self . finished && ( self . allow_final_empty || self . end - self . start > 0 ) {
683
+ self . finished = true ;
684
+ unsafe {
685
+ let string = self . matcher . haystack ( ) . slice_unchecked ( self . start , self . end ) ;
686
+ Some ( string)
687
+ }
688
+ } else {
689
+ None
690
+ }
691
+ }
692
+ }
693
+
694
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
695
+ impl < ' a , P : Pattern < ' a > > Iterator for RCharSplits < ' a , P >
696
+ where P :: Searcher : ReverseSearcher < ' a >
697
+ {
698
+ type Item = & ' a str ;
699
+
700
+ #[ inline]
701
+ fn next ( & mut self ) -> Option < & ' a str > {
702
+ if self . finished { return None }
703
+
704
+ let haystack = self . matcher . haystack ( ) ;
705
+ match self . matcher . next_match_back ( ) {
706
+ Some ( ( a, b) ) => unsafe {
707
+ let elt = haystack. slice_unchecked ( b, self . end ) ;
708
+ self . end = a;
709
+ Some ( elt)
710
+ } ,
711
+ None => self . get_remainder ( ) ,
712
+ }
713
+ }
714
+ }
715
+
649
716
/// The internal state of an iterator that searches for matches of a substring
650
717
/// within a larger string using two-way search
651
718
#[ derive( Clone ) ]
@@ -1321,6 +1388,11 @@ delegate_iter!{pattern &'a str : SplitTerminator<'a, P>}
1321
1388
pub struct SplitN < ' a , P : Pattern < ' a > > ( CharSplitsN < ' a , P > ) ;
1322
1389
delegate_iter ! { pattern forward & ' a str : SplitN <' a, P >}
1323
1390
1391
+ /// Return type of `StrExt::rsplit`
1392
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1393
+ pub struct RSplit < ' a , P : Pattern < ' a > > ( RCharSplits < ' a , P > ) ;
1394
+ delegate_iter ! { pattern reverse & ' a str : RSplit <' a, P >}
1395
+
1324
1396
/// Return type of `StrExt::rsplitn`
1325
1397
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1326
1398
pub struct RSplitN < ' a , P : Pattern < ' a > > ( CharSplitsN < ' a , P > ) ;
@@ -1340,6 +1412,8 @@ pub trait StrExt {
1340
1412
fn split < ' a , P : Pattern < ' a > > ( & ' a self , pat : P ) -> Split < ' a , P > ;
1341
1413
fn splitn < ' a , P : Pattern < ' a > > ( & ' a self , count : usize , pat : P ) -> SplitN < ' a , P > ;
1342
1414
fn split_terminator < ' a , P : Pattern < ' a > > ( & ' a self , pat : P ) -> SplitTerminator < ' a , P > ;
1415
+ fn rsplit < ' a , P : Pattern < ' a > > ( & ' a self , pat : P ) -> RSplit < ' a , P >
1416
+ where P :: Searcher : ReverseSearcher < ' a > ;
1343
1417
fn rsplitn < ' a , P : Pattern < ' a > > ( & ' a self , count : usize , pat : P ) -> RSplitN < ' a , P > ;
1344
1418
fn match_indices < ' a , P : Pattern < ' a > > ( & ' a self , pat : P ) -> MatchIndices < ' a , P > ;
1345
1419
#[ allow( deprecated) /* for SplitStr */ ]
@@ -1436,6 +1510,19 @@ impl StrExt for str {
1436
1510
} )
1437
1511
}
1438
1512
1513
+ #[ inline]
1514
+ fn rsplit < ' a , P : Pattern < ' a > > ( & ' a self , pat : P ) -> RSplit < ' a , P >
1515
+ where P :: Searcher : ReverseSearcher < ' a >
1516
+ {
1517
+ RSplit ( RCharSplits {
1518
+ start : 0 ,
1519
+ end : self . len ( ) ,
1520
+ matcher : pat. into_searcher ( self ) ,
1521
+ allow_final_empty : true ,
1522
+ finished : false ,
1523
+ } )
1524
+ }
1525
+
1439
1526
#[ inline]
1440
1527
fn rsplitn < ' a , P : Pattern < ' a > > ( & ' a self , count : usize , pat : P ) -> RSplitN < ' a , P > {
1441
1528
RSplitN ( CharSplitsN {
0 commit comments