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}