1
1
use super :: plumbing:: * ;
2
2
use super :: * ;
3
- use std:: iter;
3
+ use std:: num:: NonZeroUsize ;
4
+ use std:: { fmt, iter, mem} ;
4
5
5
6
/// Iterator adaptor for [the `repeat()` function](fn.repeat.html).
6
7
#[ derive( Debug , Clone ) ]
7
- pub struct Repeat < T : Clone + Send > {
8
+ pub struct Repeat < T > {
8
9
element : T ,
9
10
}
10
11
11
- /// Creates a parallel iterator that endlessly repeats `elt ` (by
12
+ /// Creates a parallel iterator that endlessly repeats `element ` (by
12
13
/// cloning it). Note that this iterator has "infinite" length, so
13
14
/// typically you would want to use `zip` or `take` or some other
14
15
/// means to shorten it, or consider using
@@ -22,8 +23,8 @@ pub struct Repeat<T: Clone + Send> {
22
23
/// let x: Vec<(i32, i32)> = repeat(22).zip(0..3).collect();
23
24
/// assert_eq!(x, vec![(22, 0), (22, 1), (22, 2)]);
24
25
/// ```
25
- pub fn repeat < T : Clone + Send > ( elt : T ) -> Repeat < T > {
26
- Repeat { element : elt }
26
+ pub fn repeat < T : Clone + Send > ( element : T ) -> Repeat < T > {
27
+ Repeat { element }
27
28
}
28
29
29
30
impl < T > Repeat < T >
@@ -98,13 +99,12 @@ impl<T: Clone + Send> UnindexedProducer for RepeatProducer<T> {
98
99
}
99
100
100
101
/// Iterator adaptor for [the `repeat_n()` function](fn.repeat_n.html).
101
- #[ derive( Debug , Clone ) ]
102
- pub struct RepeatN < T : Clone + Send > {
103
- element : T ,
104
- count : usize ,
102
+ #[ derive( Clone ) ]
103
+ pub struct RepeatN < T > {
104
+ inner : RepeatNProducer < T > ,
105
105
}
106
106
107
- /// Creates a parallel iterator that produces `n` repeats of `elt `
107
+ /// Creates a parallel iterator that produces `n` repeats of `element `
108
108
/// (by cloning it).
109
109
///
110
110
/// # Examples
@@ -115,22 +115,33 @@ pub struct RepeatN<T: Clone + Send> {
115
115
/// let x: Vec<(i32, i32)> = repeat_n(22, 3).zip(0..3).collect();
116
116
/// assert_eq!(x, vec![(22, 0), (22, 1), (22, 2)]);
117
117
/// ```
118
- pub fn repeat_n < T : Clone + Send > ( elt : T , n : usize ) -> RepeatN < T > {
119
- RepeatN {
120
- element : elt,
121
- count : n,
122
- }
118
+ pub fn repeat_n < T : Clone + Send > ( element : T , n : usize ) -> RepeatN < T > {
119
+ let inner = match NonZeroUsize :: new ( n) {
120
+ Some ( count) => RepeatNProducer :: Repeats ( element, count) ,
121
+ None => RepeatNProducer :: Empty ,
122
+ } ;
123
+ RepeatN { inner }
123
124
}
124
125
125
- /// Creates a parallel iterator that produces `n` repeats of `elt `
126
+ /// Creates a parallel iterator that produces `n` repeats of `element `
126
127
/// (by cloning it).
127
128
///
128
129
/// Deprecated in favor of [`repeat_n`] for consistency with the standard library.
129
130
#[ deprecated( note = "use `repeat_n`" ) ]
130
- pub fn repeatn < T : Clone + Send > ( elt : T , n : usize ) -> RepeatN < T > {
131
- RepeatN {
132
- element : elt,
133
- count : n,
131
+ pub fn repeatn < T : Clone + Send > ( element : T , n : usize ) -> RepeatN < T > {
132
+ repeat_n ( element, n)
133
+ }
134
+
135
+ impl < T : fmt:: Debug > fmt:: Debug for RepeatN < T > {
136
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
137
+ let mut dbg = f. debug_struct ( "RepeatN" ) ;
138
+ if let RepeatNProducer :: Repeats ( element, count) = & self . inner {
139
+ dbg. field ( "count" , & count. get ( ) )
140
+ . field ( "element" , element)
141
+ . finish ( )
142
+ } else {
143
+ dbg. field ( "count" , & 0usize ) . finish_non_exhaustive ( )
144
+ }
134
145
}
135
146
}
136
147
@@ -148,7 +159,7 @@ where
148
159
}
149
160
150
161
fn opt_len ( & self ) -> Option < usize > {
151
- Some ( self . count )
162
+ Some ( self . inner . len ( ) )
152
163
}
153
164
}
154
165
@@ -167,86 +178,110 @@ where
167
178
where
168
179
CB : ProducerCallback < Self :: Item > ,
169
180
{
170
- callback. callback ( RepeatNProducer {
171
- element : self . element ,
172
- count : self . count ,
173
- } )
181
+ callback. callback ( self . inner )
174
182
}
175
183
176
184
fn len ( & self ) -> usize {
177
- self . count
185
+ self . inner . len ( )
178
186
}
179
187
}
180
188
181
189
/// Producer for `RepeatN`.
182
- struct RepeatNProducer < T : Clone + Send > {
183
- element : T ,
184
- count : usize ,
190
+ #[ derive( Clone ) ]
191
+ enum RepeatNProducer < T > {
192
+ Repeats ( T , NonZeroUsize ) ,
193
+ Empty ,
185
194
}
186
195
187
196
impl < T : Clone + Send > Producer for RepeatNProducer < T > {
188
197
type Item = T ;
189
- type IntoIter = Iter < T > ;
198
+ type IntoIter = Self ;
190
199
191
200
fn into_iter ( self ) -> Self :: IntoIter {
192
- Iter {
193
- element : self . element ,
194
- count : self . count ,
195
- }
201
+ // We could potentially use `std::iter::RepeatN` with MSRV 1.82, but we have no way to
202
+ // create an empty instance without a value in hand, like `repeat_n(value, 0)`.
203
+ self
196
204
}
197
205
198
206
fn split_at ( self , index : usize ) -> ( Self , Self ) {
199
- (
200
- RepeatNProducer {
201
- element : self . element . clone ( ) ,
202
- count : index,
203
- } ,
204
- RepeatNProducer {
205
- element : self . element ,
206
- count : self . count - index,
207
- } ,
208
- )
207
+ if let Self :: Repeats ( element, count) = self {
208
+ assert ! ( index <= count. get( ) ) ;
209
+ match (
210
+ NonZeroUsize :: new ( index) ,
211
+ NonZeroUsize :: new ( count. get ( ) - index) ,
212
+ ) {
213
+ ( Some ( left) , Some ( right) ) => (
214
+ Self :: Repeats ( element. clone ( ) , left) ,
215
+ Self :: Repeats ( element, right) ,
216
+ ) ,
217
+ ( Some ( left) , None ) => ( Self :: Repeats ( element, left) , Self :: Empty ) ,
218
+ ( None , Some ( right) ) => ( Self :: Empty , Self :: Repeats ( element, right) ) ,
219
+ ( None , None ) => unreachable ! ( ) ,
220
+ }
221
+ } else {
222
+ assert ! ( index == 0 ) ;
223
+ ( Self :: Empty , Self :: Empty )
224
+ }
209
225
}
210
226
}
211
227
212
- /// Iterator for `RepeatN`.
213
- ///
214
- /// This is conceptually like `std::iter::Take<std::iter::Repeat<T>>`, but
215
- /// we need `DoubleEndedIterator` and unconditional `ExactSizeIterator`.
216
- struct Iter < T : Clone > {
217
- element : T ,
218
- count : usize ,
219
- }
220
-
221
- impl < T : Clone > Iterator for Iter < T > {
228
+ impl < T : Clone > Iterator for RepeatNProducer < T > {
222
229
type Item = T ;
223
230
224
231
#[ inline]
225
232
fn next ( & mut self ) -> Option < T > {
226
- if self . count > 0 {
227
- self . count -= 1 ;
228
- Some ( self . element . clone ( ) )
233
+ if let Self :: Repeats ( element, count) = self {
234
+ if let Some ( rem) = NonZeroUsize :: new ( count. get ( ) - 1 ) {
235
+ * count = rem;
236
+ Some ( element. clone ( ) )
237
+ } else {
238
+ match mem:: replace ( self , Self :: Empty ) {
239
+ Self :: Repeats ( element, _) => Some ( element) ,
240
+ Self :: Empty => unreachable ! ( ) ,
241
+ }
242
+ }
229
243
} else {
230
244
None
231
245
}
232
246
}
233
247
248
+ #[ inline]
249
+ fn nth ( & mut self , n : usize ) -> Option < T > {
250
+ if let Self :: Repeats ( _, count) = self {
251
+ if let Some ( rem) = NonZeroUsize :: new ( count. get ( ) . saturating_sub ( n) ) {
252
+ * count = rem;
253
+ return self . next ( ) ;
254
+ }
255
+ * self = Self :: Empty ;
256
+ }
257
+ None
258
+ }
259
+
234
260
#[ inline]
235
261
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
236
- ( self . count , Some ( self . count ) )
262
+ let len = self . len ( ) ;
263
+ ( len, Some ( len) )
237
264
}
238
265
}
239
266
240
- impl < T : Clone > DoubleEndedIterator for Iter < T > {
267
+ impl < T : Clone > DoubleEndedIterator for RepeatNProducer < T > {
241
268
#[ inline]
242
269
fn next_back ( & mut self ) -> Option < T > {
243
270
self . next ( )
244
271
}
272
+
273
+ #[ inline]
274
+ fn nth_back ( & mut self , n : usize ) -> Option < T > {
275
+ self . nth ( n)
276
+ }
245
277
}
246
278
247
- impl < T : Clone > ExactSizeIterator for Iter < T > {
279
+ impl < T : Clone > ExactSizeIterator for RepeatNProducer < T > {
248
280
#[ inline]
249
281
fn len ( & self ) -> usize {
250
- self . count
282
+ match self {
283
+ Self :: Repeats ( _, count) => count. get ( ) ,
284
+ Self :: Empty => 0 ,
285
+ }
251
286
}
252
287
}
0 commit comments