trait_theories_std/
fused_iterators.rs1pub fn next_map_commutes<I, F>(mut gen: impl FnMut() -> (I, F))
12where
13 I: Iterator, I::Item: PartialEq,
14 F: FnMut(I::Item) -> I::Item,
15{
16 let a = Vec::from_iter({ let (mut i, f) = gen(); i.next().map(f) });
17 let b = Vec::from_iter({ let ( i, f) = gen(); i.map(f).next() });
18 assert!(a == b);
19}
20
21pub fn filter_next_is_find<I, P>(mut gen: impl FnMut() -> (I, P))
23where
24 I: Iterator, I::Item: PartialEq,
25 P: for<'a> FnMut(&'a I::Item) -> bool,
26{
27 let a = Vec::from_iter({ let ( i, p) = gen(); i.filter(p).next() });
28 let b = Vec::from_iter({ let (mut i, p) = gen(); i.find(p) });
29 assert!(a == b);
30}
31
32pub fn filter_map_then_decomposable<I, P, F>(mut gen: impl FnMut() -> (I, P, F))
34where
35 I: Iterator, I::Item: PartialEq,
36 P: for<'a> FnMut(&'a I::Item) -> bool,
37 F: FnMut(I::Item) -> I::Item,
38{
39 let a = Vec::from_iter({ let (i, mut p, mut f) = gen(); i.filter_map(move |x| p(&x).then(|| f(x))) });
40 let b = Vec::from_iter({ let (i, p, f) = gen(); i.filter(p).map(f) });
41 assert!(a == b);
42}
43
44pub fn check_fused_iterator<I, P, F>(mut gen: impl FnMut() -> (I, P, F))
45where
46 I: Iterator, I::Item: PartialEq,
47 P: for<'a> FnMut(&'a I::Item) -> bool,
48 F: FnMut(I::Item) -> I::Item,
49{
50 next_map_commutes(|| { let (i, _, f) = gen(); (i, f) });
51 filter_next_is_find(|| { let (i, p, _) = gen(); (i, p) });
52 filter_map_then_decomposable(|| { let (i, p, f) = gen(); (i, p, f) });
53}
54
55#[cfg(test)]
56mod tests {
57 use crate::randutil::MT19937LCG64;
58 use super::check_fused_iterator;
59
60 #[test]
61 fn test_range_iterator() {
62 check_fused_iterator(|| {
63 let mut p_state = MT19937LCG64::new(0x87654321);
64 let p = move |&x: &u32| (x ^ p_state.next()) % 2 == 0;
65
66 let mut f_state = MT19937LCG64::new(0x86407531);
67 let f = move |x: u32| x ^ f_state.next();
68
69 (0u32..64u32, p, f)
70 });
71 }
72}