22
33use std:: {
44 borrow:: Cow ,
5- collections:: VecDeque ,
65 hash:: Hash ,
76 ops:: { Bound , RangeBounds } ,
87 rc:: Rc ,
@@ -136,7 +135,7 @@ impl<'a> Rope<'a> {
136135 }
137136
138137 /// Returns an iterator over the characters and their byte positions.
139- pub fn char_indices ( & self ) -> CharIndices < ' _ , ' a > {
138+ pub fn char_indices ( & self ) -> CharIndices < ' _ > {
140139 match & self . repr {
141140 Repr :: Light ( s) => CharIndices {
142141 iter : CharIndicesEnum :: Light {
@@ -146,8 +145,9 @@ impl<'a> Rope<'a> {
146145 Repr :: Full ( data) => CharIndices {
147146 iter : CharIndicesEnum :: Full {
148147 chunks : data,
149- char_indices : VecDeque :: new ( ) ,
150148 chunk_index : 0 ,
149+ iter : data[ 0 ] . 0 . char_indices ( ) ,
150+ start_pos : 0 ,
151151 } ,
152152 } ,
153153 }
@@ -729,51 +729,58 @@ impl<'a> Iterator for Lines<'_, 'a> {
729729 }
730730}
731731
732- enum CharIndicesEnum < ' a , ' b > {
732+ enum CharIndicesEnum < ' a > {
733733 Light {
734- iter : std:: str:: CharIndices < ' b > ,
734+ iter : std:: str:: CharIndices < ' a > ,
735735 } ,
736736 Full {
737- chunks : & ' a [ ( & ' b str , usize ) ] ,
738- char_indices : VecDeque < ( usize , char ) > ,
737+ chunks : & ' a [ ( & ' a str , usize ) ] ,
739738 chunk_index : usize ,
739+ start_pos : usize ,
740+ iter : std:: str:: CharIndices < ' a > ,
740741 } ,
741742}
742743
743- pub struct CharIndices < ' a , ' b > {
744- iter : CharIndicesEnum < ' a , ' b > ,
744+ pub struct CharIndices < ' a > {
745+ iter : CharIndicesEnum < ' a > ,
745746}
746747
747- impl Iterator for CharIndices < ' _ , ' _ > {
748+ impl Iterator for CharIndices < ' _ > {
748749 type Item = ( usize , char ) ;
749750
750751 fn next ( & mut self ) -> Option < Self :: Item > {
751752 match & mut self . iter {
752753 CharIndicesEnum :: Light { iter } => iter. next ( ) ,
753754 CharIndicesEnum :: Full {
754755 chunks,
755- char_indices,
756756 chunk_index,
757+ iter,
758+ start_pos,
757759 } => {
758- if let Some ( item ) = char_indices . pop_front ( ) {
759- return Some ( item ) ;
760+ if let Some ( ( i , c ) ) = iter . next ( ) {
761+ return Some ( ( * start_pos + i , c ) ) ;
760762 }
761-
762- if * chunk_index >= chunks. len ( ) {
763- return None ;
764- }
765-
766- // skip empty chunks
767- while * chunk_index < chunks. len ( ) && chunks[ * chunk_index] . 0 . is_empty ( ) {
763+ loop {
764+ if * chunk_index == chunks. len ( ) - 1 {
765+ return None ;
766+ }
768767 * chunk_index += 1 ;
769- }
768+ // SAFETY: We just checked bounds above
769+ let ( chunk, next_start_pos) =
770+ unsafe { chunks. get_unchecked ( * chunk_index) } ;
771+
772+ // Skip empty chunks without creating iterators
773+ if chunk. is_empty ( ) {
774+ continue ;
775+ }
770776
771- let ( chunk, start_pos) = chunks[ * chunk_index] ;
777+ * iter = chunk. char_indices ( ) ;
778+ * start_pos = * next_start_pos;
772779
773- char_indices
774- . extend ( chunk . char_indices ( ) . map ( | ( i , c ) | ( start_pos + i, c) ) ) ;
775- * chunk_index += 1 ;
776- char_indices . pop_front ( )
780+ if let Some ( ( i , c ) ) = iter . next ( ) {
781+ return Some ( ( * start_pos + i, c) ) ;
782+ }
783+ }
777784 }
778785 }
779786 }
0 commit comments