@@ -171,6 +171,79 @@ fn test_iterator_step_by_zero() {
171
171
it. next ( ) ;
172
172
}
173
173
174
+ #[ test]
175
+ fn test_iterator_step_by_size_hint ( ) {
176
+ struct StubSizeHint ( usize , Option < usize > ) ;
177
+ impl Iterator for StubSizeHint {
178
+ type Item = ( ) ;
179
+ fn next ( & mut self ) -> Option < ( ) > {
180
+ self . 0 -= 1 ;
181
+ if let Some ( ref mut upper) = self . 1 {
182
+ * upper -= 1 ;
183
+ }
184
+ Some ( ( ) )
185
+ }
186
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
187
+ ( self . 0 , self . 1 )
188
+ }
189
+ }
190
+
191
+ // The two checks in each case are needed because the logic
192
+ // is different before the first call to `next()`.
193
+
194
+ let mut it = StubSizeHint ( 10 , Some ( 10 ) ) . step_by ( 1 ) ;
195
+ assert_eq ! ( it. size_hint( ) , ( 10 , Some ( 10 ) ) ) ;
196
+ it. next ( ) ;
197
+ assert_eq ! ( it. size_hint( ) , ( 9 , Some ( 9 ) ) ) ;
198
+
199
+ // exact multiple
200
+ let mut it = StubSizeHint ( 10 , Some ( 10 ) ) . step_by ( 3 ) ;
201
+ assert_eq ! ( it. size_hint( ) , ( 4 , Some ( 4 ) ) ) ;
202
+ it. next ( ) ;
203
+ assert_eq ! ( it. size_hint( ) , ( 3 , Some ( 3 ) ) ) ;
204
+
205
+ // larger base range, but not enough to get another element
206
+ let mut it = StubSizeHint ( 12 , Some ( 12 ) ) . step_by ( 3 ) ;
207
+ assert_eq ! ( it. size_hint( ) , ( 4 , Some ( 4 ) ) ) ;
208
+ it. next ( ) ;
209
+ assert_eq ! ( it. size_hint( ) , ( 3 , Some ( 3 ) ) ) ;
210
+
211
+ // smaller base range, so fewer resulting elements
212
+ let mut it = StubSizeHint ( 9 , Some ( 9 ) ) . step_by ( 3 ) ;
213
+ assert_eq ! ( it. size_hint( ) , ( 3 , Some ( 3 ) ) ) ;
214
+ it. next ( ) ;
215
+ assert_eq ! ( it. size_hint( ) , ( 2 , Some ( 2 ) ) ) ;
216
+
217
+ // infinite upper bound
218
+ let mut it = StubSizeHint ( usize:: MAX , None ) . step_by ( 1 ) ;
219
+ assert_eq ! ( it. size_hint( ) , ( usize :: MAX , None ) ) ;
220
+ it. next ( ) ;
221
+ assert_eq ! ( it. size_hint( ) , ( usize :: MAX -1 , None ) ) ;
222
+
223
+ // still infinite with larger step
224
+ let mut it = StubSizeHint ( 7 , None ) . step_by ( 3 ) ;
225
+ assert_eq ! ( it. size_hint( ) , ( 3 , None ) ) ;
226
+ it. next ( ) ;
227
+ assert_eq ! ( it. size_hint( ) , ( 2 , None ) ) ;
228
+
229
+ // propagates ExactSizeIterator
230
+ let a = [ 1 , 2 , 3 , 4 , 5 ] ;
231
+ let it = a. iter ( ) . step_by ( 2 ) ;
232
+ assert_eq ! ( it. len( ) , 3 ) ;
233
+
234
+ // Cannot be TrustedLen as a step greater than one makes an iterator
235
+ // with (usize::MAX, None) no longer meet the safety requirements
236
+ trait TrustedLenCheck { fn test ( self ) -> bool ; }
237
+ impl < T : Iterator > TrustedLenCheck for T {
238
+ default fn test ( self ) -> bool { false }
239
+ }
240
+ impl < T : TrustedLen > TrustedLenCheck for T {
241
+ fn test ( self ) -> bool { true }
242
+ }
243
+ assert ! ( TrustedLenCheck :: test( a. iter( ) ) ) ;
244
+ assert ! ( !TrustedLenCheck :: test( a. iter( ) . step_by( 1 ) ) ) ;
245
+ }
246
+
174
247
#[ test]
175
248
fn test_filter_map ( ) {
176
249
let it = ( 0 ..) . step_by ( 1 ) . take ( 10 )
0 commit comments