sqnc/
concat.rs

1use crate::traits::*;
2use core::iter::FusedIterator;
3
4/// The concatenation of two sequences.
5///
6/// This struct is created by [`Sequence::concat()`]. See its documentation for more.
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub struct Concat<Seq0, Seq1>(Seq0, Seq1);
9
10impl<Seq0, Seq1> Concat<Seq0, Seq1>
11where
12    Seq0: Sequence,
13    Seq1: Sequence,
14{
15    #[inline]
16    pub(crate) fn new(seq0: Seq0, seq1: Seq1) -> Option<Self> {
17        if seq0.len().checked_add(seq1.len()).is_some() {
18            Some(Self(seq0, seq1))
19        } else {
20            None
21        }
22    }
23}
24
25impl<'this, Seq0, Seq1, Item> SequenceTypes<'this> for Concat<Seq0, Seq1>
26where
27    Seq0: SequenceTypes<'this, Item = Item>,
28    Seq1: SequenceTypes<'this, Item = Item>,
29{
30    type Item = Item;
31    type Iter = ConcatIter<Seq0::Iter, Seq1::Iter>;
32}
33
34impl<'this, Seq0, Seq1, Item, MutItem> MutSequenceTypes<'this> for Concat<Seq0, Seq1>
35where
36    Seq0: SequenceTypes<'this, Item = Item> + MutSequenceTypes<'this, MutItem = MutItem>,
37    Seq1: SequenceTypes<'this, Item = Item> + MutSequenceTypes<'this, MutItem = MutItem>,
38{
39    type MutItem = MutItem;
40    type IterMut = ConcatIter<Seq0::IterMut, Seq1::IterMut>;
41}
42
43impl<Seq0, Seq1> Sequence for Concat<Seq0, Seq1>
44where
45    Seq0: Sequence,
46    Seq1: Sequence + for<'a> SequenceTypes<'a, Item = <Seq0 as SequenceTypes<'a>>::Item>,
47{
48    #[inline]
49    fn len(&self) -> usize {
50        self.0.len() + self.1.len()
51    }
52
53    #[inline]
54    fn is_empty(&self) -> bool {
55        self.0.is_empty() && self.1.is_empty()
56    }
57
58    #[inline]
59    fn get(&self, index: usize) -> Option<<Self as SequenceTypes<'_>>::Item> {
60        if let Some(index1) = index.checked_sub(self.0.len()) {
61            self.1.get(index1)
62        } else {
63            self.0.get(index)
64        }
65    }
66
67    #[inline]
68    fn rget(&self, rindex: usize) -> Option<<Self as SequenceTypes<'_>>::Item> {
69        if let Some(rindex0) = rindex.checked_sub(self.1.len()) {
70            self.0.rget(rindex0)
71        } else {
72            self.1.rget(rindex)
73        }
74    }
75
76    #[inline]
77    fn first(&self) -> Option<<Self as SequenceTypes<'_>>::Item> {
78        self.0.first().or_else(|| self.1.first())
79    }
80
81    #[inline]
82    fn last(&self) -> Option<<Self as SequenceTypes<'_>>::Item> {
83        self.1.last().or_else(|| self.0.last())
84    }
85
86    #[inline]
87    fn iter(&self) -> <Self as SequenceTypes<'_>>::Iter {
88        ConcatIter(self.0.iter(), self.1.iter())
89    }
90
91    #[inline]
92    fn min<'a>(&'a self) -> Option<<Self as SequenceTypes<'a>>::Item>
93    where
94        <Self as SequenceTypes<'a>>::Item: Ord,
95    {
96        self.0.min().min(self.1.min())
97    }
98
99    #[inline]
100    fn max<'a>(&'a self) -> Option<<Self as SequenceTypes<'a>>::Item>
101    where
102        <Self as SequenceTypes<'a>>::Item: Ord,
103    {
104        self.0.max().max(self.1.max())
105    }
106}
107
108impl<Seq0, Seq1> MutSequence for Concat<Seq0, Seq1>
109where
110    Seq0: MutSequence,
111    Seq1: MutSequence
112        + for<'a> SequenceTypes<'a, Item = <Seq0 as SequenceTypes<'a>>::Item>
113        + for<'a> MutSequenceTypes<'a, MutItem = <Seq0 as MutSequenceTypes<'a>>::MutItem>,
114{
115    #[inline]
116    fn get_mut(&mut self, index: usize) -> Option<<Self as MutSequenceTypes<'_>>::MutItem> {
117        if let Some(index1) = index.checked_sub(self.0.len()) {
118            self.1.get_mut(index1)
119        } else {
120            self.0.get_mut(index)
121        }
122    }
123
124    #[inline]
125    fn rget_mut(&mut self, rindex: usize) -> Option<<Self as MutSequenceTypes<'_>>::MutItem> {
126        if let Some(rindex0) = rindex.checked_sub(self.1.len()) {
127            self.0.rget_mut(rindex0)
128        } else {
129            self.1.rget_mut(rindex)
130        }
131    }
132
133    #[inline]
134    fn first_mut(&mut self) -> Option<<Self as MutSequenceTypes<'_>>::MutItem> {
135        self.0.first_mut().or_else(|| self.1.first_mut())
136    }
137
138    #[inline]
139    fn last_mut(&mut self) -> Option<<Self as MutSequenceTypes<'_>>::MutItem> {
140        self.1.last_mut().or_else(|| self.0.last_mut())
141    }
142
143    #[inline]
144    fn iter_mut(&mut self) -> <Self as MutSequenceTypes<'_>>::IterMut {
145        ConcatIter(self.0.iter_mut(), self.1.iter_mut())
146    }
147}
148
149impl<Seq0, Seq1, Item> IntoIterator for Concat<Seq0, Seq1>
150where
151    Seq0: Sequence + for<'a> SequenceTypes<'a, Item = Item> + IntoIterator<Item = Item>,
152    Seq1: Sequence + for<'a> SequenceTypes<'a, Item = Item> + IntoIterator<Item = Item>,
153    Seq0::IntoIter: FusedIterator,
154    Seq1::IntoIter: FusedIterator,
155{
156    type Item = Item;
157    type IntoIter = ConcatIter<Seq0::IntoIter, Seq1::IntoIter>;
158
159    #[inline]
160    fn into_iter(self) -> Self::IntoIter {
161        ConcatIter(self.0.into_iter(), self.1.into_iter())
162    }
163}
164
165pub struct ConcatIter<Iter0, Iter1>(Iter0, Iter1);
166
167impl<Iter0, Iter1> Iterator for ConcatIter<Iter0, Iter1>
168where
169    Iter0: FusedIterator,
170    Iter1: Iterator<Item = Iter0::Item> + FusedIterator,
171{
172    type Item = Iter0::Item;
173
174    #[inline]
175    fn next(&mut self) -> Option<Self::Item> {
176        if let Some(value) = self.0.next() {
177            return Some(value);
178        }
179        self.1.next()
180    }
181
182    #[inline]
183    fn size_hint(&self) -> (usize, Option<usize>) {
184        let (lower0, upper0) = self.0.size_hint();
185        let (lower1, upper1) = self.1.size_hint();
186        (lower0 + lower1, upper0.zip(upper1).map(|(a, b)| a + b))
187    }
188}
189
190impl<Iter0, Iter1> DoubleEndedIterator for ConcatIter<Iter0, Iter1>
191where
192    Iter0: FusedIterator + DoubleEndedIterator,
193    Iter1: Iterator<Item = Iter0::Item> + FusedIterator + DoubleEndedIterator,
194{
195    #[inline]
196    fn next_back(&mut self) -> Option<Self::Item> {
197        if let Some(value) = self.1.next_back() {
198            return Some(value);
199        }
200        self.0.next_back()
201    }
202}
203
204// The upper bound potentially overflows. However, since `ConcatIter` has no
205// public constructor and the constructor of `Concat` verifies that the length
206// doesn not exceed `usize::MAX`, we can safely implement `ExactSizeIterator`.
207impl<Iter0, Iter1> ExactSizeIterator for ConcatIter<Iter0, Iter1>
208where
209    Iter0: FusedIterator + ExactSizeIterator,
210    Iter1: Iterator<Item = Iter0::Item> + FusedIterator + ExactSizeIterator,
211{
212}
213
214impl<Iter0, Iter1> FusedIterator for ConcatIter<Iter0, Iter1>
215where
216    Iter0: FusedIterator,
217    Iter1: Iterator<Item = Iter0::Item> + FusedIterator,
218{
219}
220
221#[cfg(test)]
222mod tests {
223    use super::Concat;
224    use crate::traits::*;
225
226    #[test]
227    fn overflow() {
228        assert!(Concat::new(0..usize::MAX, 0..2).is_none());
229    }
230
231    #[test]
232    fn len() {
233        assert_eq!(Concat::new(2..5, 5..7).unwrap().len(), 5);
234        assert_eq!(Concat::new(2..5, 5..5).unwrap().len(), 3);
235        assert_eq!(Concat::new(5..5, 5..7).unwrap().len(), 2);
236        assert_eq!(Concat::new(5..5, 5..5).unwrap().len(), 0);
237    }
238
239    #[test]
240    fn is_empty() {
241        assert!(!Concat::new(2..5, 5..7).unwrap().is_empty());
242        assert!(!Concat::new(2..5, 5..5).unwrap().is_empty());
243        assert!(!Concat::new(5..5, 5..7).unwrap().is_empty());
244        assert!(Concat::new(5..5, 5..5).unwrap().is_empty());
245    }
246
247    #[test]
248    fn get() {
249        let x = Concat::new(2..5, 5..7).unwrap();
250        assert_eq!(x.get(0), Some(2));
251        assert_eq!(x.get(1), Some(3));
252        assert_eq!(x.get(2), Some(4));
253        assert_eq!(x.get(3), Some(5));
254        assert_eq!(x.get(4), Some(6));
255        assert_eq!(x.get(5), None);
256    }
257
258    #[test]
259    fn rget() {
260        let x = Concat::new(2..5, 5..7).unwrap();
261        assert_eq!(x.rget(0), Some(6));
262        assert_eq!(x.rget(1), Some(5));
263        assert_eq!(x.rget(2), Some(4));
264        assert_eq!(x.rget(3), Some(3));
265        assert_eq!(x.rget(4), Some(2));
266        assert_eq!(x.rget(5), None);
267    }
268
269    #[test]
270    fn first() {
271        assert_eq!(Concat::new(2..5, 5..7).unwrap().first(), Some(2));
272        assert_eq!(Concat::new(2..2, 5..7).unwrap().first(), Some(5));
273        assert_eq!(Concat::new(2..2, 5..5).unwrap().first(), None);
274    }
275
276    #[test]
277    fn last() {
278        assert_eq!(Concat::new(2..5, 5..7).unwrap().last(), Some(6));
279        assert_eq!(Concat::new(2..5, 7..7).unwrap().last(), Some(4));
280        assert_eq!(Concat::new(2..2, 5..5).unwrap().last(), None);
281    }
282
283    #[test]
284    fn get_mut() {
285        let mut x = [2, 3, 4];
286        let mut y = [5, 6];
287        let mut z = Concat::new(x.as_mut_sqnc(), y.as_mut_sqnc()).unwrap();
288        *z.get_mut(0).unwrap() = 8;
289        *z.get_mut(1).unwrap() = 9;
290        *z.get_mut(2).unwrap() = 0;
291        *z.get_mut(3).unwrap() = 1;
292        *z.get_mut(4).unwrap() = 2;
293        assert_eq!(z.get_mut(5), None);
294        assert_eq!(x, [8, 9, 0]);
295        assert_eq!(y, [1, 2]);
296    }
297
298    #[test]
299    fn rget_mut() {
300        let mut x = [2, 3, 4];
301        let mut y = [5, 6];
302        let mut z = Concat::new(x.as_mut_sqnc(), y.as_mut_sqnc()).unwrap();
303        *z.rget_mut(0).unwrap() = 2;
304        *z.rget_mut(1).unwrap() = 1;
305        *z.rget_mut(2).unwrap() = 0;
306        *z.rget_mut(3).unwrap() = 9;
307        *z.rget_mut(4).unwrap() = 8;
308        assert_eq!(z.rget_mut(5), None);
309        assert_eq!(x, [8, 9, 0]);
310        assert_eq!(y, [1, 2]);
311    }
312
313    #[test]
314    fn first_mut() {
315        let mut x = [2, 3, 4];
316        let mut y = [5, 6];
317        let mut z: [usize; 0] = [];
318        *Concat::new(x.as_mut_sqnc(), y.as_mut_sqnc())
319            .unwrap()
320            .first_mut()
321            .unwrap() = 7;
322        assert_eq!(x, [7, 3, 4]);
323        *Concat::new(z.as_mut_sqnc(), y.as_mut_sqnc())
324            .unwrap()
325            .first_mut()
326            .unwrap() = 8;
327        assert_eq!(y, [8, 6]);
328        assert!(Concat::new(z.as_mut_sqnc(), [].as_mut_sqnc())
329            .unwrap()
330            .first_mut()
331            .is_none());
332    }
333
334    #[test]
335    fn last_mut() {
336        let mut x = [2, 3, 4];
337        let mut y = [5, 6];
338        let mut z: [usize; 0] = [];
339        *Concat::new(x.as_mut_sqnc(), y.as_mut_sqnc())
340            .unwrap()
341            .last_mut()
342            .unwrap() = 7;
343        assert_eq!(y, [5, 7]);
344        *Concat::new(x.as_mut_sqnc(), z.as_mut_sqnc())
345            .unwrap()
346            .last_mut()
347            .unwrap() = 8;
348        assert_eq!(x, [2, 3, 8]);
349        assert!(Concat::new(z.as_mut_sqnc(), [].as_mut_sqnc(),)
350            .unwrap()
351            .last_mut()
352            .is_none());
353    }
354
355    #[test]
356    fn iter() {
357        assert!(Concat::new(2..5, 5..7).unwrap().iter().eq(2..7));
358    }
359
360    #[test]
361    fn rev_iter() {
362        assert!(Concat::new(2..5, 5..7)
363            .unwrap()
364            .iter()
365            .rev()
366            .eq(Iterator::rev(2..7)));
367    }
368
369    #[test]
370    fn iter_size_hint() {
371        let mut iter = Concat::new(2..5, 5..7).unwrap().iter();
372        assert_eq!(iter.size_hint(), (5, Some(5)));
373        iter.next();
374        assert_eq!(iter.size_hint(), (4, Some(4)));
375        iter.next();
376        assert_eq!(iter.size_hint(), (3, Some(3)));
377        iter.next();
378        assert_eq!(iter.size_hint(), (2, Some(2)));
379        iter.next();
380        assert_eq!(iter.size_hint(), (1, Some(1)));
381        iter.next();
382        assert_eq!(iter.size_hint(), (0, Some(0)));
383    }
384
385    #[test]
386    fn min() {
387        assert_eq!(Concat::new(2..5, 5..7).unwrap().min(), Some(2));
388        assert_eq!(Concat::new(5..7, 2..5).unwrap().min(), Some(2));
389        assert_eq!(Concat::new(2..2, 5..5).unwrap().min(), None);
390    }
391
392    #[test]
393    fn max() {
394        assert_eq!(Concat::new(2..5, 5..7).unwrap().max(), Some(6));
395        assert_eq!(Concat::new(5..7, 2..5).unwrap().max(), Some(6));
396        assert_eq!(Concat::new(2..2, 5..5).unwrap().max(), None);
397    }
398
399    #[test]
400    fn iter_mut() {
401        let mut x = [2, 3, 4];
402        let mut y = [5, 6];
403        Concat::new(x.as_mut_sqnc(), y.as_mut_sqnc())
404            .unwrap()
405            .iter_mut()
406            .for_each(|v| *v += 2);
407        assert_eq!(x, [4, 5, 6]);
408        assert_eq!(y, [7, 8]);
409    }
410
411    #[test]
412    fn into_iter() {
413        assert!(Concat::new(2..5, 5..7).unwrap().into_iter().eq(2..7))
414    }
415}