@@ -509,7 +509,7 @@ impl<'a> Rope<'a> {
509509 Lines {
510510 iter : match & self . repr {
511511 Repr :: Light ( s) => LinesEnum :: Light ( s) ,
512- Repr :: Full ( data) => LinesEnum :: Complex {
512+ Repr :: Full ( data) => LinesEnum :: Full {
513513 iter : data,
514514 in_chunk_byte_idx : 0 ,
515515 chunk_idx : 0 ,
@@ -554,7 +554,7 @@ impl Hash for Rope<'_> {
554554
555555enum LinesEnum < ' a , ' b > {
556556 Light ( & ' b str ) ,
557- Complex {
557+ Full {
558558 iter : & ' a Vec < ( & ' b str , usize ) > ,
559559 in_chunk_byte_idx : usize ,
560560 chunk_idx : usize ,
@@ -605,7 +605,7 @@ impl<'a> Iterator for Lines<'_, 'a> {
605605 }
606606 Lines {
607607 iter :
608- LinesEnum :: Complex {
608+ LinesEnum :: Full {
609609 iter : chunks,
610610 ref mut in_chunk_byte_idx,
611611 ref mut chunk_idx,
@@ -777,6 +777,27 @@ impl Iterator for CharIndices<'_, '_> {
777777 }
778778 }
779779 }
780+
781+ #[ inline]
782+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
783+ match & self . iter {
784+ CharIndicesEnum :: Light { iter } => iter. size_hint ( ) ,
785+ CharIndicesEnum :: Full {
786+ chunks,
787+ char_indices,
788+ chunk_index,
789+ } => {
790+ let Some ( total) = chunks. last ( ) . map ( |( s, l) | * l + s. len ( ) ) else {
791+ return ( 0 , None ) ;
792+ } ;
793+
794+ let ( _, prev) = chunks[ * chunk_index] ;
795+ // SAFETY: The previous length is guaranteed be less than or equal to the latter one.
796+ let remaining = total - prev;
797+ ( ( remaining + 3 ) / 4 + char_indices. len ( ) , Some ( remaining) )
798+ }
799+ }
800+ }
780801}
781802
782803impl Default for Rope < ' _ > {
@@ -1226,25 +1247,38 @@ mod tests {
12261247
12271248 #[ test]
12281249 fn char_indices ( ) {
1250+ // The algorithm is the same as the one used in `std::str::CharIndices::size_hint`.
1251+ macro_rules! lo {
1252+ ( $expr: expr) => {
1253+ ( $expr + 3 ) / 4
1254+ } ;
1255+ }
1256+
12291257 let mut a = Rope :: new ( ) ;
12301258 a. add ( "abc" ) ;
12311259 a. add ( "def" ) ;
12321260 assert_eq ! (
12331261 a. char_indices( ) . collect:: <Vec <_>>( ) ,
12341262 "abcdef" . char_indices( ) . collect:: <Vec <_>>( )
12351263 ) ;
1264+ let len = "abcdef" . char_indices ( ) . size_hint ( ) . 1 . unwrap ( ) ;
1265+ assert_eq ! ( a. char_indices( ) . size_hint( ) , ( lo!( len) , Some ( len) ) ) ;
12361266
12371267 let mut a = Rope :: new ( ) ;
12381268 a. add ( "こんにちは" ) ;
12391269 assert_eq ! (
12401270 a. char_indices( ) . collect:: <Vec <_>>( ) ,
12411271 "こんにちは" . char_indices( ) . collect:: <Vec <_>>( )
12421272 ) ;
1273+ let len = "こんにちは" . char_indices ( ) . size_hint ( ) . 1 . unwrap ( ) ;
1274+ assert_eq ! ( a. char_indices( ) . size_hint( ) , ( lo!( len) , Some ( len) ) ) ;
12431275 a. add ( "世界" ) ;
12441276 assert_eq ! (
12451277 a. char_indices( ) . collect:: <Vec <_>>( ) ,
12461278 "こんにちは世界" . char_indices( ) . collect:: <Vec <_>>( )
12471279 ) ;
1280+ let len = "こんにちは世界" . char_indices ( ) . size_hint ( ) . 1 . unwrap ( ) ;
1281+ assert_eq ! ( a. char_indices( ) . size_hint( ) , ( lo!( len) , Some ( len) ) ) ;
12481282 }
12491283
12501284 #[ test]
0 commit comments