88// option. This file may not be copied, modified, or distributed
99// except according to those terms.
1010
11- use std:: collections:: VecDeque ;
12- use std:: fmt:: { self , Write } ;
1311use decompose:: Decompositions ;
12+ use smallvec:: SmallVec ;
13+ use std:: fmt:: { self , Write } ;
1414
1515#[ derive( Clone ) ]
1616enum RecompositionState {
1717 Composing ,
18- Purging ,
19- Finished
18+ Purging ( usize ) ,
19+ Finished ( usize ) ,
2020}
2121
2222/// External iterator for a string recomposition's characters.
2323#[ derive( Clone ) ]
2424pub struct Recompositions < I > {
2525 iter : Decompositions < I > ,
2626 state : RecompositionState ,
27- buffer : VecDeque < char > ,
27+ buffer : SmallVec < [ char ; 4 ] > ,
2828 composee : Option < char > ,
29- last_ccc : Option < u8 >
29+ last_ccc : Option < u8 > ,
3030}
3131
3232#[ inline]
3333pub fn new_canonical < I : Iterator < Item =char > > ( iter : I ) -> Recompositions < I > {
3434 Recompositions {
3535 iter : super :: decompose:: new_canonical ( iter) ,
3636 state : self :: RecompositionState :: Composing ,
37- buffer : VecDeque :: new ( ) ,
37+ buffer : SmallVec :: new ( ) ,
3838 composee : None ,
3939 last_ccc : None ,
4040 }
@@ -45,7 +45,7 @@ pub fn new_compatible<I: Iterator<Item=char>>(iter: I) -> Recompositions<I> {
4545 Recompositions {
4646 iter : super :: decompose:: new_compatible ( iter) ,
4747 state : self :: RecompositionState :: Composing ,
48- buffer : VecDeque :: new ( ) ,
48+ buffer : SmallVec :: new ( ) ,
4949 composee : None ,
5050 last_ccc : None ,
5151 }
@@ -85,7 +85,7 @@ impl<I: Iterator<Item=char>> Iterator for Recompositions<I> {
8585 self . composee = Some ( ch) ;
8686 return Some ( k) ;
8787 }
88- self . buffer . push_back ( ch) ;
88+ self . buffer . push ( ch) ;
8989 self . last_ccc = Some ( ch_class) ;
9090 }
9191 }
@@ -96,10 +96,10 @@ impl<I: Iterator<Item=char>> Iterator for Recompositions<I> {
9696 if ch_class == 0 {
9797 self . composee = Some ( ch) ;
9898 self . last_ccc = None ;
99- self . state = Purging ;
99+ self . state = Purging ( 0 ) ;
100100 return Some ( k) ;
101101 }
102- self . buffer . push_back ( ch) ;
102+ self . buffer . push ( ch) ;
103103 self . last_ccc = Some ( ch_class) ;
104104 continue ;
105105 }
@@ -109,28 +109,40 @@ impl<I: Iterator<Item=char>> Iterator for Recompositions<I> {
109109 continue ;
110110 }
111111 None => {
112- self . buffer . push_back ( ch) ;
112+ self . buffer . push ( ch) ;
113113 self . last_ccc = Some ( ch_class) ;
114114 }
115115 }
116116 }
117117 }
118118 }
119- self . state = Finished ;
119+ self . state = Finished ( 0 ) ;
120120 if self . composee . is_some ( ) {
121121 return self . composee . take ( ) ;
122122 }
123123 }
124- Purging => {
125- match self . buffer . pop_front ( ) {
126- None => self . state = Composing ,
127- s => return s
124+ Purging ( next) => {
125+ match self . buffer . get ( next) . cloned ( ) {
126+ None => {
127+ self . buffer . clear ( ) ;
128+ self . state = Composing ;
129+ }
130+ s => {
131+ self . state = Purging ( next + 1 ) ;
132+ return s
133+ }
128134 }
129135 }
130- Finished => {
131- match self . buffer . pop_front ( ) {
132- None => return self . composee . take ( ) ,
133- s => return s
136+ Finished ( next) => {
137+ match self . buffer . get ( next) . cloned ( ) {
138+ None => {
139+ self . buffer . clear ( ) ;
140+ return self . composee . take ( )
141+ }
142+ s => {
143+ self . state = Finished ( next + 1 ) ;
144+ return s
145+ }
134146 }
135147 }
136148 }
0 commit comments