]> git.lizzy.rs Git - rust.git/blob - library/core/tests/iter/adapters/chain.rs
Merge commit '40dd3e2b7089b5e96714e064b731f6dbf17c61a9' into sync_cg_clif-2021-05-27
[rust.git] / library / core / tests / iter / adapters / chain.rs
1 use super::*;
2 use core::iter::*;
3
4 #[test]
5 fn test_iterator_chain() {
6     let xs = [0, 1, 2, 3, 4, 5];
7     let ys = [30, 40, 50, 60];
8     let expected = [0, 1, 2, 3, 4, 5, 30, 40, 50, 60];
9     let it = xs.iter().chain(&ys);
10     let mut i = 0;
11     for &x in it {
12         assert_eq!(x, expected[i]);
13         i += 1;
14     }
15     assert_eq!(i, expected.len());
16
17     let ys = (30..).step_by(10).take(4);
18     let it = xs.iter().cloned().chain(ys);
19     let mut i = 0;
20     for x in it {
21         assert_eq!(x, expected[i]);
22         i += 1;
23     }
24     assert_eq!(i, expected.len());
25 }
26
27 #[test]
28 fn test_iterator_chain_advance_by() {
29     fn test_chain(xs: &[i32], ys: &[i32]) {
30         let len = xs.len() + ys.len();
31
32         for i in 0..xs.len() {
33             let mut iter = Unfuse::new(xs).chain(Unfuse::new(ys));
34             iter.advance_by(i).unwrap();
35             assert_eq!(iter.next(), Some(&xs[i]));
36             assert_eq!(iter.advance_by(100), Err(len - i - 1));
37         }
38
39         for i in 0..ys.len() {
40             let mut iter = Unfuse::new(xs).chain(Unfuse::new(ys));
41             iter.advance_by(xs.len() + i).unwrap();
42             assert_eq!(iter.next(), Some(&ys[i]));
43             assert_eq!(iter.advance_by(100), Err(ys.len() - i - 1));
44         }
45
46         let mut iter = xs.iter().chain(ys);
47         iter.advance_by(len).unwrap();
48         assert_eq!(iter.next(), None);
49
50         let mut iter = xs.iter().chain(ys);
51         assert_eq!(iter.advance_by(len + 1), Err(len));
52     }
53
54     test_chain(&[], &[]);
55     test_chain(&[], &[0, 1, 2, 3, 4, 5]);
56     test_chain(&[0, 1, 2, 3, 4, 5], &[]);
57     test_chain(&[0, 1, 2, 3, 4, 5], &[30, 40, 50, 60]);
58 }
59
60 #[test]
61 fn test_iterator_chain_advance_back_by() {
62     fn test_chain(xs: &[i32], ys: &[i32]) {
63         let len = xs.len() + ys.len();
64
65         for i in 0..ys.len() {
66             let mut iter = Unfuse::new(xs).chain(Unfuse::new(ys));
67             iter.advance_back_by(i).unwrap();
68             assert_eq!(iter.next_back(), Some(&ys[ys.len() - i - 1]));
69             assert_eq!(iter.advance_back_by(100), Err(len - i - 1));
70         }
71
72         for i in 0..xs.len() {
73             let mut iter = Unfuse::new(xs).chain(Unfuse::new(ys));
74             iter.advance_back_by(ys.len() + i).unwrap();
75             assert_eq!(iter.next_back(), Some(&xs[xs.len() - i - 1]));
76             assert_eq!(iter.advance_back_by(100), Err(xs.len() - i - 1));
77         }
78
79         let mut iter = xs.iter().chain(ys);
80         iter.advance_back_by(len).unwrap();
81         assert_eq!(iter.next_back(), None);
82
83         let mut iter = xs.iter().chain(ys);
84         assert_eq!(iter.advance_back_by(len + 1), Err(len));
85     }
86
87     test_chain(&[], &[]);
88     test_chain(&[], &[0, 1, 2, 3, 4, 5]);
89     test_chain(&[0, 1, 2, 3, 4, 5], &[]);
90     test_chain(&[0, 1, 2, 3, 4, 5], &[30, 40, 50, 60]);
91 }
92
93 #[test]
94 fn test_iterator_chain_nth() {
95     let xs = [0, 1, 2, 3, 4, 5];
96     let ys = [30, 40, 50, 60];
97     let zs = [];
98     let expected = [0, 1, 2, 3, 4, 5, 30, 40, 50, 60];
99     for (i, x) in expected.iter().enumerate() {
100         assert_eq!(Some(x), xs.iter().chain(&ys).nth(i));
101     }
102     assert_eq!(zs.iter().chain(&xs).nth(0), Some(&0));
103
104     let mut it = xs.iter().chain(&zs);
105     assert_eq!(it.nth(5), Some(&5));
106     assert_eq!(it.next(), None);
107 }
108
109 #[test]
110 fn test_iterator_chain_nth_back() {
111     let xs = [0, 1, 2, 3, 4, 5];
112     let ys = [30, 40, 50, 60];
113     let zs = [];
114     let expected = [0, 1, 2, 3, 4, 5, 30, 40, 50, 60];
115     for (i, x) in expected.iter().rev().enumerate() {
116         assert_eq!(Some(x), xs.iter().chain(&ys).nth_back(i));
117     }
118     assert_eq!(zs.iter().chain(&xs).nth_back(0), Some(&5));
119
120     let mut it = xs.iter().chain(&zs);
121     assert_eq!(it.nth_back(5), Some(&0));
122     assert_eq!(it.next(), None);
123 }
124
125 #[test]
126 fn test_iterator_chain_last() {
127     let xs = [0, 1, 2, 3, 4, 5];
128     let ys = [30, 40, 50, 60];
129     let zs = [];
130     assert_eq!(xs.iter().chain(&ys).last(), Some(&60));
131     assert_eq!(zs.iter().chain(&ys).last(), Some(&60));
132     assert_eq!(ys.iter().chain(&zs).last(), Some(&60));
133     assert_eq!(zs.iter().chain(&zs).last(), None);
134 }
135
136 #[test]
137 fn test_iterator_chain_count() {
138     let xs = [0, 1, 2, 3, 4, 5];
139     let ys = [30, 40, 50, 60];
140     let zs = [];
141     assert_eq!(xs.iter().chain(&ys).count(), 10);
142     assert_eq!(zs.iter().chain(&ys).count(), 4);
143 }
144
145 #[test]
146 fn test_iterator_chain_find() {
147     let xs = [0, 1, 2, 3, 4, 5];
148     let ys = [30, 40, 50, 60];
149     let mut iter = xs.iter().chain(&ys);
150     assert_eq!(iter.find(|&&i| i == 4), Some(&4));
151     assert_eq!(iter.next(), Some(&5));
152     assert_eq!(iter.find(|&&i| i == 40), Some(&40));
153     assert_eq!(iter.next(), Some(&50));
154     assert_eq!(iter.find(|&&i| i == 100), None);
155     assert_eq!(iter.next(), None);
156 }
157
158 #[test]
159 fn test_iterator_chain_size_hint() {
160     // this chains an iterator of length 0 with an iterator of length 1,
161     // so after calling `.next()` once, the iterator is empty and the
162     // state is `ChainState::Back`. `.size_hint()` should now disregard
163     // the size hint of the left iterator
164     let mut iter = Toggle { is_empty: true }.chain(once(()));
165     assert_eq!(iter.next(), Some(()));
166     assert_eq!(iter.size_hint(), (0, Some(0)));
167
168     let mut iter = once(()).chain(Toggle { is_empty: true });
169     assert_eq!(iter.next_back(), Some(()));
170     assert_eq!(iter.size_hint(), (0, Some(0)));
171 }
172
173 #[test]
174 fn test_iterator_chain_unfused() {
175     // Chain shouldn't be fused in its second iterator, depending on direction
176     let mut iter = NonFused::new(empty()).chain(Toggle { is_empty: true });
177     assert!(iter.next().is_none());
178     assert!(iter.next().is_some());
179     assert!(iter.next().is_none());
180
181     let mut iter = Toggle { is_empty: true }.chain(NonFused::new(empty()));
182     assert!(iter.next_back().is_none());
183     assert!(iter.next_back().is_some());
184     assert!(iter.next_back().is_none());
185 }
186
187 #[test]
188 fn test_chain_fold() {
189     let xs = [1, 2, 3];
190     let ys = [1, 2, 0];
191
192     let mut iter = xs.iter().chain(&ys);
193     iter.next();
194     let mut result = Vec::new();
195     iter.fold((), |(), &elt| result.push(elt));
196     assert_eq!(&[2, 3, 1, 2, 0], &result[..]);
197 }
198
199 #[test]
200 fn test_chain_try_folds() {
201     let c = || (0..10).chain(10..20);
202
203     let f = &|acc, x| i32::checked_add(2 * acc, x);
204     assert_eq!(c().try_fold(7, f), (0..20).try_fold(7, f));
205     assert_eq!(c().try_rfold(7, f), (0..20).rev().try_fold(7, f));
206
207     let mut iter = c();
208     assert_eq!(iter.position(|x| x == 5), Some(5));
209     assert_eq!(iter.next(), Some(6), "stopped in front, state Both");
210     assert_eq!(iter.position(|x| x == 13), Some(6));
211     assert_eq!(iter.next(), Some(14), "stopped in back, state Back");
212     assert_eq!(iter.try_fold(0, |acc, x| Some(acc + x)), Some((15..20).sum()));
213
214     let mut iter = c().rev(); // use rev to access try_rfold
215     assert_eq!(iter.position(|x| x == 15), Some(4));
216     assert_eq!(iter.next(), Some(14), "stopped in back, state Both");
217     assert_eq!(iter.position(|x| x == 5), Some(8));
218     assert_eq!(iter.next(), Some(4), "stopped in front, state Front");
219     assert_eq!(iter.try_fold(0, |acc, x| Some(acc + x)), Some((0..4).sum()));
220
221     let mut iter = c();
222     iter.by_ref().rev().nth(14); // skip the last 15, ending in state Front
223     assert_eq!(iter.try_fold(7, f), (0..5).try_fold(7, f));
224
225     let mut iter = c();
226     iter.nth(14); // skip the first 15, ending in state Back
227     assert_eq!(iter.try_rfold(7, f), (15..20).try_rfold(7, f));
228 }
229
230 #[test]
231 fn test_double_ended_chain() {
232     let xs = [1, 2, 3, 4, 5];
233     let ys = [7, 9, 11];
234     let mut it = xs.iter().chain(&ys).rev();
235     assert_eq!(it.next().unwrap(), &11);
236     assert_eq!(it.next().unwrap(), &9);
237     assert_eq!(it.next_back().unwrap(), &1);
238     assert_eq!(it.next_back().unwrap(), &2);
239     assert_eq!(it.next_back().unwrap(), &3);
240     assert_eq!(it.next_back().unwrap(), &4);
241     assert_eq!(it.next_back().unwrap(), &5);
242     assert_eq!(it.next_back().unwrap(), &7);
243     assert_eq!(it.next_back(), None);
244
245     // test that .chain() is well behaved with an unfused iterator
246     struct CrazyIterator(bool);
247     impl CrazyIterator {
248         fn new() -> CrazyIterator {
249             CrazyIterator(false)
250         }
251     }
252     impl Iterator for CrazyIterator {
253         type Item = i32;
254         fn next(&mut self) -> Option<i32> {
255             if self.0 {
256                 Some(99)
257             } else {
258                 self.0 = true;
259                 None
260             }
261         }
262     }
263
264     impl DoubleEndedIterator for CrazyIterator {
265         fn next_back(&mut self) -> Option<i32> {
266             self.next()
267         }
268     }
269
270     assert_eq!(CrazyIterator::new().chain(0..10).rev().last(), Some(0));
271     assert!((0..10).chain(CrazyIterator::new()).rev().any(|i| i == 0));
272 }