combin_iterator/altern/
bi_altern.rs

1//! # BiAltern
2//!
3//! The `bi_altern` module provides an iterator, `BiAltern`, for alternately traversing exactly 2 iterators.
4//!
5//! ## Usage
6//!
7//! To use `BiAltern`, create a new instance with `BiAltern::new(Iterator<Item>, Iterator<Item>)`, or
8//! from an `Iterable<Item>`, use `Iterable<Item>::altern_with(Iterable<Item>)`. <br/>
9//! The `next` method will then yield elements from the 2 iterators in a round-robin fashion until both iterators are exhausted.<br/>
10//! `BiAltern`is more complete than `crate::altern::VecAltern`, and implements `core::iter::traits::exact_size::ExactSizeIterator` if both
11//! iterators implement it. Also, if both additionally implement `DoubleEndedIterator`, then so does `BiAltern`.
12//!
13//! ## Examples
14//!
15//! ```rust
16//! use combin_iterator::altern::BiAltern;
17//! let vec1 = vec![1, 3, 5, 6];
18//! let vec2 = vec![2, 4];
19//!
20//! // Create a BiAltern iterator and add individual iterators
21//! let iter = BiAltern::new(vec1.iter(), vec2.iter());
22//!
23//! assert_eq!(iter.collect::<Vec<_>>(), vec![&1, &2, &3, &4, &5, &6]);
24//!
25//!
26//! // You can also build it in a line thanks to the trait:
27//! use combin_iterator::altern::AlternWith;
28//! let iter = vec1.iter().altern_with(vec2.iter());
29//!
30//! assert_eq!(iter.collect::<Vec<_>>(), vec![&1, &2, &3, &4, &5, &6]);
31//! ```
32//! ### Common mistake
33//! `BiAltern` like `VecAltern`can be used to iter over more than 2 iterable by combining them with each other,
34//! but the number of iterable must be a power of 2. Otherwise the number of pass on each iterable will not be equal (but maybe it is waht you want).
35//! And even if the number of iterable is a number of two, the order need to be correct to have the result expected.
36//!
37//! For example:
38//! ```
39//! use combin_iterator::altern::BiAltern;
40//! let vec1 = vec![1, 1, 1, 1];
41//! let vec2 = vec![2, 2];
42//! let vec3 = vec![3, 3, 3];
43//!
44//! // Here, `iter` will NOT be equivalent to
45//! // vec![true, true, false, true ,true, false, true, false, true],
46//! // but instead to vec![true, false, true, false, true, false, true, true, true].
47//! // We alternate between BiAltern(vec1.iter(), vec2.iter()) and vec3.iter(),
48//! // not between vec1.iter(), vec2.iter() and vec3.iter() at the same level.
49//! let iter = BiAltern::new(BiAltern::new(vec1.iter(), vec2.iter()), vec3.iter());
50//! assert_ne!(iter.collect::<Vec<_>>(), vec![&1, &2, &3, &1, &2, &3, &1, &3, &1]);
51//!
52//! let iter = BiAltern::new(BiAltern::new(vec1.iter(), vec2.iter()), vec3.iter());
53//! assert_eq!(iter.collect::<Vec<_>>(), vec![&1, &3, &2, &3, &1, &3, &2, &1, &1]);
54//!
55//! // For the exact same reason:
56//! use combin_iterator::altern::AlternWith;
57//! let iter = vec1.iter().altern_with(vec2.iter()).altern_with(vec3.iter());
58//! assert_ne!(iter.collect::<Vec<_>>(), vec![&1, &2, &3, &1, &2, &3, &1, &3, &1]);
59//!
60//! let iter = vec1.iter().altern_with(vec2.iter()).altern_with(vec3.iter());
61//! assert_eq!(iter.collect::<Vec<_>>(), vec![&1, &3, &2, &3, &1, &3, &2, &1, &1]);
62//!
63//! // Now if we have 4 vec than we want to iterate over, we can at the same level:
64//! let vec1 = vec![1, 1];
65//! let vec2 = vec![2, 2];
66//! let vec3 = vec![3, 3];
67//! let vec4 = vec![4, 4];
68//!
69//! // Notice: Don't use `altern_with`, otherwise they will never be at the same level, and the last iter will always be iter over one time of two.
70//! let iter = BiAltern::new(BiAltern::new(vec1.iter(), vec2.iter()), BiAltern::new(vec3.iter(), vec4.iter()));
71//!
72//! // Here, the order on wich we will iterate is: vec1.iter() -> vec3.iter() -> vec2.iter() -> vec4.iter() -> vec1.iter() -> ...
73//! assert_eq!(iter.collect::<Vec<_>>(), vec![&1, &3, &2, &4, &1, &3, &2, &4]);
74//!
75//! // If you want it to be vec1.iter() -> vec2.iter() -> vec3.iter() -> vec4.iter() -> vec1.iter() -> ...,
76//! // then you should construct it like this:
77//! let iter = BiAltern::new(BiAltern::new(vec1.iter(), vec3.iter()), BiAltern::new(vec2.iter(), vec4.iter()));
78//! assert_eq!(iter.collect::<Vec<_>>(), vec![&1, &2, &3, &4, &1, &2, &3, &4]);
79//! ```
80
81
82/// Trait to convert to a BiAltern iterator
83/// Implemented on Iterator
84pub trait AlternWith<T1 : Iterator<Item = A>, A> {
85
86    /// Create the BiAltern, with self and an other iterator
87    fn altern_with<T2: Iterator<Item = A>>(self : Self, other: T2) -> BiAltern<T1, T2, A>
88    where
89        Self: Sized;
90}
91
92impl<T1 : Iterator<Item = A>, A> AlternWith<T1, A> for T1 {
93    fn altern_with<T2: Iterator<Item = A>>(self : Self, other: T2) -> BiAltern<T1, T2, A>
94    where
95        Self: Sized {
96            BiAltern::new(self, other)
97    }
98}
99
100/// BiAltern struct, to altern between 2 iterator.
101pub struct BiAltern<Iter1 : Iterator, Iter2 : Iterator, Item>
102where
103    Iter1: Iterator<Item = Item>,
104    Iter2: Iterator<Item = Item>
105{
106    iter1 : Option<Iter1>,
107    iter2 :  Option<Iter2>,
108    next_is_first : bool,
109}
110
111impl<Iter1, Iter2, Item> BiAltern<Iter1, Iter2, Item>
112where
113    Iter1: Iterator<Item = Item>,
114    Iter2: Iterator<Item = Item>
115{
116    /// Creates a new instance of an `BiAltern` iterator.
117    pub fn new(iter1 : Iter1, iter2 : Iter2) -> BiAltern<Iter1, Iter2, Item> {
118        BiAltern {
119            iter1: Some(iter1),
120            iter2: Some(iter2),
121            next_is_first: true,
122        }
123    }
124}
125
126impl<Iter1: Iterator<Item = Item>, Iter2: Iterator<Item = Item>, Item> Iterator for BiAltern<Iter1, Iter2, Item>
127{
128    type Item = Item;
129
130    fn next(&mut self) -> Option<Self::Item> {
131        match (self.next_is_first, self.iter1.as_mut(), self.iter2.as_mut()) {
132            (true, Some(iter1), Some( iter2)) => {
133                self.next_is_first = !self.next_is_first;
134                iter1.next().or_else(|| {self.iter1 = None; iter2.next()})
135            },
136            (false, Some(iter1), Some( iter2)) => {
137                self.next_is_first = !self.next_is_first;
138                iter2.next().or_else(|| {self.iter2 = None; iter1.next()})
139            },
140            (true, Some(iter1), None) => iter1.next(),
141            (false, Some(iter1), None) => iter1.next(),
142            (true, None, Some(iter2)) => iter2.next(),
143            (false, None, Some(iter2)) => iter2.next(),
144            (true, None, None) => None,
145            (false, None, None) => None,
146        }
147    }
148
149    fn size_hint(&self) -> (usize, Option<usize>) {
150        match (self.iter1.as_ref(), self.iter2.as_ref()) {
151            (None, None) => (0, Some(0)),
152            (None, Some(iter2)) => iter2.size_hint(),
153            (Some(iter1), None) => iter1.size_hint(),
154            (Some(iter1), Some(iter2)) => {
155                let hint1 = iter1.size_hint();
156                let hint2 = iter2.size_hint();
157                let upper_bound = match (hint1.1, hint2.1)  {
158                    (None, None) => None,
159                    (None, Some(_)) => None,
160                    (Some(_), None) => None,
161                    (Some(u1), Some(u2)) => Some(u1 + u2),
162                };
163                (hint1.0 + hint2.0, upper_bound)
164            },
165        }
166    }
167}
168
169impl<Iter1: Iterator<Item = Item>, Iter2: Iterator<Item = Item>, Item> DoubleEndedIterator for BiAltern<Iter1, Iter2, Item>
170where
171        Iter1 : DoubleEndedIterator<Item = Item> + ExactSizeIterator,
172        Iter2 : DoubleEndedIterator<Item = Item> + ExactSizeIterator,
173{
174    fn next_back(&mut self) -> Option<Self::Item> {
175        match (self.iter1.as_mut(), self.iter2.as_mut()) {
176            (None, None) => None,
177            (None, Some(iter2)) => iter2.next_back(),
178            (Some(iter1), None) => iter1.next_back(),
179            (Some(iter1), Some(iter2)) => {
180                let n1 = iter1.len() + self.next_is_first.then(|| 0).unwrap_or_else(|| 1);
181                let n2 = iter2.len();
182                if n2 >= n1 {
183                    iter2.next_back()
184                } else {
185                    iter1.next_back()
186                }
187            },
188        }
189    }
190}
191
192impl<Iter1: Iterator<Item = Item>, Iter2: Iterator<Item = Item>, Item> ExactSizeIterator for BiAltern<Iter1, Iter2, Item>
193where Iter1 : ExactSizeIterator,
194      Iter2 : ExactSizeIterator {}
195
196#[cfg(test)]
197mod tests {
198    use std::vec;
199
200    use super::BiAltern;
201
202    #[test]
203    fn normal_usage() {
204        let vec1 = vec![1, 3, 5, 6];
205        let vec2 = vec![2, 4];
206
207        let iter = BiAltern::new(vec1.iter(), vec2.iter());
208
209        assert_eq!(iter.collect::<Vec<_>>(), vec![&1,&2,&3,&4,&5,&6]);
210    }
211
212    #[test]
213    fn reverse() {
214        let vec1 = vec![1, 3, 5, 6];
215        let vec2 = vec![2, 4];
216
217        let iter = BiAltern::new(vec1.iter(), vec2.iter()).rev();
218
219        assert_eq!(iter.collect::<Vec<_>>(), vec![&6,&5,&4,&3,&2,&1]);
220    }
221
222    #[test]
223    fn next_and_next_back() {
224        let vec1 = vec![1, 3, 5, 6];
225        let vec2 = vec![2, 4];
226
227        let mut iter = BiAltern::new(vec1.iter(), vec2.iter());
228
229        assert_eq!(iter.next(), Some(&1));
230        assert_eq!(iter.next_back(), Some(&6));
231        assert_eq!(iter.next_back(), Some(&5));
232        assert_eq!(iter.next(), Some(&2));
233        assert_eq!(iter.next_back(), Some(&4));
234        assert_eq!(iter.next(), Some(&3));
235        assert_eq!(iter.next_back(), None);
236    }
237
238    #[test]
239    fn len() {
240        let vec1 = vec![1, 3, 5, 6];
241        let vec2 = vec![2, 4];
242        let iter = BiAltern::new(vec1.iter(), vec2.iter());
243        assert_eq!(iter.len(), 6);
244    }
245}