@@ -2266,6 +2266,144 @@ pub trait Iterator {
2266
2266
self . try_fold ( ( ) , check ( f) ) == ControlFlow :: BREAK
2267
2267
}
2268
2268
2269
+ /// Tests if at least `n` elements of the iterator matches a predicate.
2270
+ ///
2271
+ /// `at_least()` takes a usize `n` and a closure that returns `true` or `false`. It applies
2272
+ /// this closure to each element of the iterator, and if more than `n` of them return
2273
+ /// `true`, then so does `at_least()`. If less than `n` of them return `true`, it
2274
+ /// returns `false`.
2275
+ ///
2276
+ /// `at_least()` is short-circuiting; in other words, it will stop processing
2277
+ /// as soon as it finds `n` `true`, given that no matter what else happens,
2278
+ /// the result will also be `true`.
2279
+ ///
2280
+ /// An empty iterator returns `false`.
2281
+ ///
2282
+ /// # Examples
2283
+ ///
2284
+ /// Basic usage:
2285
+ ///
2286
+ /// ```
2287
+ /// let a = [1, 2, 3];
2288
+ ///
2289
+ /// assert!(a.iter().at_least(1, |&x| x > 0));
2290
+ ///
2291
+ /// assert!(!a.iter().at_least(1, |&x| x > 5));
2292
+ /// ```
2293
+ ///
2294
+ /// Stopping at the `n`th `true`:
2295
+ ///
2296
+ /// ```
2297
+ /// let a = vec![1, 2, 3, 4, 5];
2298
+ ///
2299
+ /// let mut iter = a.iter();
2300
+ ///
2301
+ /// assert!(iter.at_least(0, |&x| x % 2 == 0));
2302
+ /// assert!(iter.at_least(1, |&x| x % 2 == 0));
2303
+ /// assert!(iter.at_least(2, |&x| x % 2 == 0));
2304
+ /// assert!(!iter.at_least(3, |&x| x % 2 == 0));
2305
+ ///
2306
+ /// // we can still use `iter`, as there are more elements.
2307
+ /// let a = [1, 2, 3];
2308
+ /// let mut iter = a.iter();
2309
+ /// assert!(iter.at_least(1, |&x| x > 0));
2310
+ /// assert_eq!(iter.next(), Some(&2));
2311
+ /// ```
2312
+ #[ inline]
2313
+ #[ unstable( feature = "at_least" , reason = "new API" , issue = "none" ) ]
2314
+ fn at_least < F > ( & mut self , n : usize , f : F ) -> bool
2315
+ where
2316
+ Self : Sized ,
2317
+ F : FnMut ( Self :: Item ) -> bool ,
2318
+ {
2319
+ #[ inline]
2320
+ fn check < T > (
2321
+ n : usize ,
2322
+ mut f : impl FnMut ( T ) -> bool ,
2323
+ ) -> impl FnMut ( usize , T ) -> ControlFlow < usize , usize > {
2324
+ move |mut i, x| {
2325
+ i += f ( x) as usize ;
2326
+
2327
+ if i < n {
2328
+ ControlFlow :: Continue ( i)
2329
+ } else {
2330
+ ControlFlow :: Break ( i)
2331
+ }
2332
+ }
2333
+ }
2334
+
2335
+ matches ! ( self . try_fold( 0 , check( n, f) ) , ControlFlow :: Break ( _) )
2336
+ }
2337
+
2338
+ /// Tests if at most `n` elements of the iterator matches a predicate.
2339
+ ///
2340
+ /// `at_most()` takes a usize `n` and a closure that returns `true` or `false`. It applies
2341
+ /// this closure to each element of the iterator, and if less than `n` of them return
2342
+ /// `true`, then so does `at_least()`. If more than `n` of them return `true`, it
2343
+ /// returns `false`.
2344
+ ///
2345
+ /// `at_most()` is short-circuiting; in other words, it will stop processing
2346
+ /// as soon as it finds `n` `false`, given that no matter what else happens,
2347
+ /// the result will also be `false`.
2348
+ ///
2349
+ /// An empty iterator returns `true`.
2350
+ ///
2351
+ /// # Examples
2352
+ ///
2353
+ /// Basic usage:
2354
+ ///
2355
+ /// ```
2356
+ /// let a = [1, 2, 3];
2357
+ ///
2358
+ /// assert!(a.iter().at_most(1, |&x| x > 3));
2359
+ ///
2360
+ /// assert!(!a.iter().at_most(1, |&x| x > 0));
2361
+ /// ```
2362
+ ///
2363
+ /// Stopping at the `n + 1`th `true`:
2364
+ ///
2365
+ /// ```
2366
+ /// let a = vec![1, 2, 3, 4, 5];
2367
+ ///
2368
+ /// let mut iter = a.iter();
2369
+ ///
2370
+ /// assert!(iter.at_least(0, |&x| x % 2 == 0));
2371
+ /// assert!(iter.at_least(1, |&x| x % 2 == 0));
2372
+ /// assert!(iter.at_least(2, |&x| x % 2 == 0));
2373
+ /// assert!(!iter.at_least(3, |&x| x % 2 == 0));
2374
+ ///
2375
+ /// // we can still use `iter`, as there are more elements.
2376
+ /// let a = [1, 1, 3];
2377
+ /// let mut iter = a.iter();
2378
+ /// assert!(!iter.at_most(1, |&x| x == 1));
2379
+ /// assert_eq!(iter.next(), Some(&3));
2380
+ /// ```
2381
+ #[ inline]
2382
+ #[ unstable( feature = "at_most" , reason = "new API" , issue = "none" ) ]
2383
+ fn at_most < F > ( & mut self , n : usize , f : F ) -> bool
2384
+ where
2385
+ Self : Sized ,
2386
+ F : FnMut ( Self :: Item ) -> bool ,
2387
+ {
2388
+ #[ inline]
2389
+ fn check < T > (
2390
+ n : usize ,
2391
+ mut f : impl FnMut ( T ) -> bool ,
2392
+ ) -> impl FnMut ( usize , T ) -> ControlFlow < usize , usize > {
2393
+ move |mut i, x| {
2394
+ i += f ( x) as usize ;
2395
+
2396
+ if i <= n {
2397
+ ControlFlow :: Continue ( i)
2398
+ } else {
2399
+ ControlFlow :: Break ( i)
2400
+ }
2401
+ }
2402
+ }
2403
+
2404
+ matches ! ( self . try_fold( 0 , check( n, f) ) , ControlFlow :: Continue ( _) )
2405
+ }
2406
+
2269
2407
/// Searches for an element of an iterator that satisfies a predicate.
2270
2408
///
2271
2409
/// `find()` takes a closure that returns `true` or `false`. It applies
0 commit comments