1 use crate::iter::{DoubleEndedIterator, FusedIterator, Iterator, TrustedLen};
5 /// An iterator that links two iterators together, in a chain.
7 /// This `struct` is created by the [`chain`] method on [`Iterator`]. See its
8 /// documentation for more.
10 /// [`chain`]: trait.Iterator.html#method.chain
11 /// [`Iterator`]: trait.Iterator.html
12 #[derive(Clone, Debug)]
13 #[must_use = "iterators are lazy and do nothing unless consumed"]
14 #[stable(feature = "rust1", since = "1.0.0")]
15 pub struct Chain<A, B> {
16 // These are "fused" with `Option` so we don't need separate state to track which part is
17 // already exhausted, and we may also get niche layout for `None`. We don't use the real `Fuse`
18 // adapter because its specialization for `FusedIterator` unconditionally descends into the
19 // iterator, and that could be expensive to keep revisiting stuff like nested chains. It also
20 // hurts compiler performance to add more iterator layers to `Chain`.
22 // Only the "first" iterator is actually set `None` when exhausted, depending on whether you
23 // iterate forward or backward. If you mix directions, then both sides may be `None`.
27 impl<A, B> Chain<A, B> {
28 pub(in super::super) fn new(a: A, b: B) -> Chain<A, B> {
29 Chain { a: Some(a), b: Some(b) }
33 /// Fuse the iterator if the expression is `None`.
35 ($self:ident . $iter:ident . $($call:tt)+) => {
37 Some(ref mut iter) => match iter.$($call)+ {
49 /// Try an iterator method without fusing,
50 /// like an inline `.as_mut().and_then(...)`
52 ($self:ident . $iter:ident . $($call:tt)+) => {
54 Some(ref mut iter) => iter.$($call)+,
60 #[stable(feature = "rust1", since = "1.0.0")]
61 impl<A, B> Iterator for Chain<A, B>
64 B: Iterator<Item = A::Item>,
69 fn next(&mut self) -> Option<A::Item> {
70 match fuse!(self.a.next()) {
71 None => maybe!(self.b.next()),
77 #[rustc_inherit_overflow_checks]
78 fn count(self) -> usize {
79 let a_count = match self.a {
83 let b_count = match self.b {
90 fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
93 F: FnMut(Acc, Self::Item) -> R,
96 if let Some(ref mut a) = self.a {
97 acc = a.try_fold(acc, &mut f)?;
100 if let Some(ref mut b) = self.b {
101 acc = b.try_fold(acc, f)?;
102 // we don't fuse the second iterator
107 fn fold<Acc, F>(self, mut acc: Acc, mut f: F) -> Acc
109 F: FnMut(Acc, Self::Item) -> Acc,
111 if let Some(a) = self.a {
112 acc = a.fold(acc, &mut f);
114 if let Some(b) = self.b {
115 acc = b.fold(acc, f);
121 fn nth(&mut self, mut n: usize) -> Option<A::Item> {
122 if let Some(ref mut a) = self.a {
123 while let Some(x) = a.next() {
131 maybe!(self.b.nth(n))
135 fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item>
137 P: FnMut(&Self::Item) -> bool,
139 match fuse!(self.a.find(&mut predicate)) {
140 None => maybe!(self.b.find(predicate)),
146 fn last(self) -> Option<A::Item> {
147 // Must exhaust a before b.
148 let a_last = match self.a {
152 let b_last = match self.b {
160 fn size_hint(&self) -> (usize, Option<usize>) {
162 Chain { a: Some(a), b: Some(b) } => {
163 let (a_lower, a_upper) = a.size_hint();
164 let (b_lower, b_upper) = b.size_hint();
166 let lower = a_lower.saturating_add(b_lower);
168 let upper = match (a_upper, b_upper) {
169 (Some(x), Some(y)) => x.checked_add(y),
175 Chain { a: Some(a), b: None } => a.size_hint(),
176 Chain { a: None, b: Some(b) } => b.size_hint(),
177 Chain { a: None, b: None } => (0, Some(0)),
182 #[stable(feature = "rust1", since = "1.0.0")]
183 impl<A, B> DoubleEndedIterator for Chain<A, B>
185 A: DoubleEndedIterator,
186 B: DoubleEndedIterator<Item = A::Item>,
189 fn next_back(&mut self) -> Option<A::Item> {
190 match fuse!(self.b.next_back()) {
191 None => maybe!(self.a.next_back()),
197 fn nth_back(&mut self, mut n: usize) -> Option<A::Item> {
198 if let Some(ref mut b) = self.b {
199 while let Some(x) = b.next_back() {
207 maybe!(self.a.nth_back(n))
211 fn rfind<P>(&mut self, mut predicate: P) -> Option<Self::Item>
213 P: FnMut(&Self::Item) -> bool,
215 match fuse!(self.b.rfind(&mut predicate)) {
216 None => maybe!(self.a.rfind(predicate)),
221 fn try_rfold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
224 F: FnMut(Acc, Self::Item) -> R,
227 if let Some(ref mut b) = self.b {
228 acc = b.try_rfold(acc, &mut f)?;
231 if let Some(ref mut a) = self.a {
232 acc = a.try_rfold(acc, f)?;
233 // we don't fuse the second iterator
238 fn rfold<Acc, F>(self, mut acc: Acc, mut f: F) -> Acc
240 F: FnMut(Acc, Self::Item) -> Acc,
242 if let Some(b) = self.b {
243 acc = b.rfold(acc, &mut f);
245 if let Some(a) = self.a {
246 acc = a.rfold(acc, f);
252 // Note: *both* must be fused to handle double-ended iterators.
253 #[stable(feature = "fused", since = "1.26.0")]
254 impl<A, B> FusedIterator for Chain<A, B>
257 B: FusedIterator<Item = A::Item>,
261 #[unstable(feature = "trusted_len", issue = "37572")]
262 unsafe impl<A, B> TrustedLen for Chain<A, B>
265 B: TrustedLen<Item = A::Item>,