|
| 1 | +// ignore-tidy-filelength |
| 2 | + |
1 | 3 | use core::cell::Cell;
|
2 | 4 | use core::convert::TryFrom;
|
3 | 5 | use core::iter::*;
|
@@ -2940,3 +2942,73 @@ fn test_partition() {
|
2940 | 2942 | check(xs, |&x| x < 3, 3); // small
|
2941 | 2943 | check(xs, |&x| x > 6, 3); // large
|
2942 | 2944 | }
|
| 2945 | + |
| 2946 | +/// An iterator that panics whenever `next` or next_back` is called |
| 2947 | +/// after `None` has already been returned. This does not violate |
| 2948 | +/// `Iterator`'s contract. Used to test that iterator adaptors don't |
| 2949 | +/// poll their inner iterators after exhausting them. |
| 2950 | +struct NonFused<I> { |
| 2951 | + iter: I, |
| 2952 | + done: bool, |
| 2953 | +} |
| 2954 | + |
| 2955 | +impl<I> NonFused<I> { |
| 2956 | + fn new(iter: I) -> Self { |
| 2957 | + Self { iter, done: false } |
| 2958 | + } |
| 2959 | +} |
| 2960 | + |
| 2961 | +impl<I> Iterator for NonFused<I> |
| 2962 | +where |
| 2963 | + I: Iterator, |
| 2964 | +{ |
| 2965 | + type Item = I::Item; |
| 2966 | + |
| 2967 | + fn next(&mut self) -> Option<Self::Item> { |
| 2968 | + assert!(!self.done, "this iterator has already returned None"); |
| 2969 | + self.iter.next().or_else(|| { |
| 2970 | + self.done = true; |
| 2971 | + None |
| 2972 | + }) |
| 2973 | + } |
| 2974 | +} |
| 2975 | + |
| 2976 | +impl<I> DoubleEndedIterator for NonFused<I> |
| 2977 | +where |
| 2978 | + I: DoubleEndedIterator, |
| 2979 | +{ |
| 2980 | + fn next_back(&mut self) -> Option<Self::Item> { |
| 2981 | + assert!(!self.done, "this iterator has already returned None"); |
| 2982 | + self.iter.next_back().or_else(|| { |
| 2983 | + self.done = true; |
| 2984 | + None |
| 2985 | + }) |
| 2986 | + } |
| 2987 | +} |
| 2988 | + |
| 2989 | +#[test] |
| 2990 | +fn test_peekable_non_fused() { |
| 2991 | + let mut iter = NonFused::new(empty::<i32>()).peekable(); |
| 2992 | + |
| 2993 | + assert_eq!(iter.peek(), None); |
| 2994 | + assert_eq!(iter.next_back(), None); |
| 2995 | +} |
| 2996 | + |
| 2997 | +#[test] |
| 2998 | +fn test_flatten_non_fused_outer() { |
| 2999 | + let mut iter = NonFused::new(once(0..2)).flatten(); |
| 3000 | + |
| 3001 | + assert_eq!(iter.next_back(), Some(1)); |
| 3002 | + assert_eq!(iter.next(), Some(0)); |
| 3003 | + assert_eq!(iter.next(), None); |
| 3004 | +} |
| 3005 | + |
| 3006 | +#[test] |
| 3007 | +fn test_flatten_non_fused_inner() { |
| 3008 | + let mut iter = once(0..1).chain(once(1..3)).flat_map(NonFused::new); |
| 3009 | + |
| 3010 | + assert_eq!(iter.next_back(), Some(2)); |
| 3011 | + assert_eq!(iter.next(), Some(0)); |
| 3012 | + assert_eq!(iter.next(), Some(1)); |
| 3013 | + assert_eq!(iter.next(), None); |
| 3014 | +} |
0 commit comments