8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- use std:: collections:: VecDeque ;
12
- use std:: fmt:: { self , Write } ;
13
11
use decompose:: Decompositions ;
12
+ use smallvec:: SmallVec ;
13
+ use std:: fmt:: { self , Write } ;
14
14
15
15
#[ derive( Clone ) ]
16
16
enum RecompositionState {
17
17
Composing ,
18
- Purging ,
19
- Finished
18
+ Purging ( usize ) ,
19
+ Finished ( usize ) ,
20
20
}
21
21
22
22
/// External iterator for a string recomposition's characters.
23
23
#[ derive( Clone ) ]
24
24
pub struct Recompositions < I > {
25
25
iter : Decompositions < I > ,
26
26
state : RecompositionState ,
27
- buffer : VecDeque < char > ,
27
+ buffer : SmallVec < [ char ; 4 ] > ,
28
28
composee : Option < char > ,
29
- last_ccc : Option < u8 >
29
+ last_ccc : Option < u8 > ,
30
30
}
31
31
32
32
#[ inline]
33
33
pub fn new_canonical < I : Iterator < Item =char > > ( iter : I ) -> Recompositions < I > {
34
34
Recompositions {
35
35
iter : super :: decompose:: new_canonical ( iter) ,
36
36
state : self :: RecompositionState :: Composing ,
37
- buffer : VecDeque :: new ( ) ,
37
+ buffer : SmallVec :: new ( ) ,
38
38
composee : None ,
39
39
last_ccc : None ,
40
40
}
@@ -45,7 +45,7 @@ pub fn new_compatible<I: Iterator<Item=char>>(iter: I) -> Recompositions<I> {
45
45
Recompositions {
46
46
iter : super :: decompose:: new_compatible ( iter) ,
47
47
state : self :: RecompositionState :: Composing ,
48
- buffer : VecDeque :: new ( ) ,
48
+ buffer : SmallVec :: new ( ) ,
49
49
composee : None ,
50
50
last_ccc : None ,
51
51
}
@@ -85,7 +85,7 @@ impl<I: Iterator<Item=char>> Iterator for Recompositions<I> {
85
85
self . composee = Some ( ch) ;
86
86
return Some ( k) ;
87
87
}
88
- self . buffer . push_back ( ch) ;
88
+ self . buffer . push ( ch) ;
89
89
self . last_ccc = Some ( ch_class) ;
90
90
}
91
91
}
@@ -96,10 +96,10 @@ impl<I: Iterator<Item=char>> Iterator for Recompositions<I> {
96
96
if ch_class == 0 {
97
97
self . composee = Some ( ch) ;
98
98
self . last_ccc = None ;
99
- self . state = Purging ;
99
+ self . state = Purging ( 0 ) ;
100
100
return Some ( k) ;
101
101
}
102
- self . buffer . push_back ( ch) ;
102
+ self . buffer . push ( ch) ;
103
103
self . last_ccc = Some ( ch_class) ;
104
104
continue ;
105
105
}
@@ -109,28 +109,40 @@ impl<I: Iterator<Item=char>> Iterator for Recompositions<I> {
109
109
continue ;
110
110
}
111
111
None => {
112
- self . buffer . push_back ( ch) ;
112
+ self . buffer . push ( ch) ;
113
113
self . last_ccc = Some ( ch_class) ;
114
114
}
115
115
}
116
116
}
117
117
}
118
118
}
119
- self . state = Finished ;
119
+ self . state = Finished ( 0 ) ;
120
120
if self . composee . is_some ( ) {
121
121
return self . composee . take ( ) ;
122
122
}
123
123
}
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
+ }
128
134
}
129
135
}
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
+ }
134
146
}
135
147
}
136
148
}
0 commit comments