]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_data_structures/src/sso/either_iter.rs
Rollup merge of #96609 - ibraheemdev:arc-downcast-unchecked, r=m-ou-se
[rust.git] / compiler / rustc_data_structures / src / sso / either_iter.rs
1 use std::fmt;
2 use std::iter::ExactSizeIterator;
3 use std::iter::FusedIterator;
4 use std::iter::Iterator;
5
6 /// Iterator which may contain instance of
7 /// one of two specific implementations.
8 ///
9 /// Note: For most methods providing custom
10 ///       implementation may marginally
11 ///       improve performance by avoiding
12 ///       doing Left/Right match on every step
13 ///       and doing it only once instead.
14 #[derive(Clone)]
15 pub enum EitherIter<L, R> {
16     Left(L),
17     Right(R),
18 }
19
20 impl<L, R> Iterator for EitherIter<L, R>
21 where
22     L: Iterator,
23     R: Iterator<Item = L::Item>,
24 {
25     type Item = L::Item;
26
27     fn next(&mut self) -> Option<Self::Item> {
28         match self {
29             EitherIter::Left(l) => l.next(),
30             EitherIter::Right(r) => r.next(),
31         }
32     }
33
34     fn size_hint(&self) -> (usize, Option<usize>) {
35         match self {
36             EitherIter::Left(l) => l.size_hint(),
37             EitherIter::Right(r) => r.size_hint(),
38         }
39     }
40 }
41
42 impl<L, R> ExactSizeIterator for EitherIter<L, R>
43 where
44     L: ExactSizeIterator,
45     R: ExactSizeIterator,
46     EitherIter<L, R>: Iterator,
47 {
48     fn len(&self) -> usize {
49         match self {
50             EitherIter::Left(l) => l.len(),
51             EitherIter::Right(r) => r.len(),
52         }
53     }
54 }
55
56 impl<L, R> FusedIterator for EitherIter<L, R>
57 where
58     L: FusedIterator,
59     R: FusedIterator,
60     EitherIter<L, R>: Iterator,
61 {
62 }
63
64 impl<L, R> fmt::Debug for EitherIter<L, R>
65 where
66     L: fmt::Debug,
67     R: fmt::Debug,
68 {
69     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70         match self {
71             EitherIter::Left(l) => l.fmt(f),
72             EitherIter::Right(r) => r.fmt(f),
73         }
74     }
75 }