1 use crate::iter::{DoubleEndedIterator, FusedIterator, Iterator, TrustedLen};
4 /// An iterator that links two iterators together, in a chain.
6 /// This `struct` is created by [`Iterator::chain`]. See its documentation
12 /// use std::iter::Chain;
13 /// use std::slice::Iter;
15 /// let a1 = [1, 2, 3];
16 /// let a2 = [4, 5, 6];
17 /// let iter: Chain<Iter<_>, Iter<_>> = a1.iter().chain(a2.iter());
19 #[derive(Clone, Debug)]
20 #[must_use = "iterators are lazy and do nothing unless consumed"]
21 #[stable(feature = "rust1", since = "1.0.0")]
22 pub struct Chain<A, B> {
23 // These are "fused" with `Option` so we don't need separate state to track which part is
24 // already exhausted, and we may also get niche layout for `None`. We don't use the real `Fuse`
25 // adapter because its specialization for `FusedIterator` unconditionally descends into the
26 // iterator, and that could be expensive to keep revisiting stuff like nested chains. It also
27 // hurts compiler performance to add more iterator layers to `Chain`.
29 // Only the "first" iterator is actually set `None` when exhausted, depending on whether you
30 // iterate forward or backward. If you mix directions, then both sides may be `None`.
34 impl<A, B> Chain<A, B> {
35 pub(in super::super) fn new(a: A, b: B) -> Chain<A, B> {
36 Chain { a: Some(a), b: Some(b) }
40 #[stable(feature = "rust1", since = "1.0.0")]
41 impl<A, B> Iterator for Chain<A, B>
44 B: Iterator<Item = A::Item>,
49 fn next(&mut self) -> Option<A::Item> {
50 and_then_or_clear(&mut self.a, Iterator::next).or_else(|| self.b.as_mut()?.next())
54 #[rustc_inherit_overflow_checks]
55 fn count(self) -> usize {
56 let a_count = match self.a {
60 let b_count = match self.b {
67 fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
70 F: FnMut(Acc, Self::Item) -> R,
73 if let Some(ref mut a) = self.a {
74 acc = a.try_fold(acc, &mut f)?;
77 if let Some(ref mut b) = self.b {
78 acc = b.try_fold(acc, f)?;
79 // we don't fuse the second iterator
84 fn fold<Acc, F>(self, mut acc: Acc, mut f: F) -> Acc
86 F: FnMut(Acc, Self::Item) -> Acc,
88 if let Some(a) = self.a {
89 acc = a.fold(acc, &mut f);
91 if let Some(b) = self.b {
98 fn advance_by(&mut self, n: usize) -> Result<(), usize> {
101 if let Some(ref mut a) = self.a {
102 match a.advance_by(rem) {
103 Ok(()) => return Ok(()),
109 if let Some(ref mut b) = self.b {
110 match b.advance_by(rem) {
111 Ok(()) => return Ok(()),
114 // we don't fuse the second iterator
117 if rem == 0 { Ok(()) } else { Err(n - rem) }
121 fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
122 if let Some(ref mut a) = self.a {
123 match a.advance_by(n) {
124 Ok(()) => match a.next() {
134 self.b.as_mut()?.nth(n)
138 fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item>
140 P: FnMut(&Self::Item) -> bool,
142 and_then_or_clear(&mut self.a, |a| a.find(&mut predicate))
143 .or_else(|| self.b.as_mut()?.find(predicate))
147 fn last(self) -> Option<A::Item> {
148 // Must exhaust a before b.
149 let a_last = self.a.and_then(Iterator::last);
150 let b_last = self.b.and_then(Iterator::last);
155 fn size_hint(&self) -> (usize, Option<usize>) {
157 Chain { a: Some(a), b: Some(b) } => {
158 let (a_lower, a_upper) = a.size_hint();
159 let (b_lower, b_upper) = b.size_hint();
161 let lower = a_lower.saturating_add(b_lower);
163 let upper = match (a_upper, b_upper) {
164 (Some(x), Some(y)) => x.checked_add(y),
170 Chain { a: Some(a), b: None } => a.size_hint(),
171 Chain { a: None, b: Some(b) } => b.size_hint(),
172 Chain { a: None, b: None } => (0, Some(0)),
177 #[stable(feature = "rust1", since = "1.0.0")]
178 impl<A, B> DoubleEndedIterator for Chain<A, B>
180 A: DoubleEndedIterator,
181 B: DoubleEndedIterator<Item = A::Item>,
184 fn next_back(&mut self) -> Option<A::Item> {
185 and_then_or_clear(&mut self.b, |b| b.next_back()).or_else(|| self.a.as_mut()?.next_back())
189 fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
192 if let Some(ref mut b) = self.b {
193 match b.advance_back_by(rem) {
194 Ok(()) => return Ok(()),
200 if let Some(ref mut a) = self.a {
201 match a.advance_back_by(rem) {
202 Ok(()) => return Ok(()),
205 // we don't fuse the second iterator
208 if rem == 0 { Ok(()) } else { Err(n - rem) }
212 fn nth_back(&mut self, mut n: usize) -> Option<Self::Item> {
213 if let Some(ref mut b) = self.b {
214 match b.advance_back_by(n) {
215 Ok(()) => match b.next_back() {
225 self.a.as_mut()?.nth_back(n)
229 fn rfind<P>(&mut self, mut predicate: P) -> Option<Self::Item>
231 P: FnMut(&Self::Item) -> bool,
233 and_then_or_clear(&mut self.b, |b| b.rfind(&mut predicate))
234 .or_else(|| self.a.as_mut()?.rfind(predicate))
237 fn try_rfold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
240 F: FnMut(Acc, Self::Item) -> R,
241 R: Try<Output = Acc>,
243 if let Some(ref mut b) = self.b {
244 acc = b.try_rfold(acc, &mut f)?;
247 if let Some(ref mut a) = self.a {
248 acc = a.try_rfold(acc, f)?;
249 // we don't fuse the second iterator
254 fn rfold<Acc, F>(self, mut acc: Acc, mut f: F) -> Acc
256 F: FnMut(Acc, Self::Item) -> Acc,
258 if let Some(b) = self.b {
259 acc = b.rfold(acc, &mut f);
261 if let Some(a) = self.a {
262 acc = a.rfold(acc, f);
268 // Note: *both* must be fused to handle double-ended iterators.
269 #[stable(feature = "fused", since = "1.26.0")]
270 impl<A, B> FusedIterator for Chain<A, B>
273 B: FusedIterator<Item = A::Item>,
277 #[unstable(feature = "trusted_len", issue = "37572")]
278 unsafe impl<A, B> TrustedLen for Chain<A, B>
281 B: TrustedLen<Item = A::Item>,
286 fn and_then_or_clear<T, U>(opt: &mut Option<T>, f: impl FnOnce(&mut T) -> Option<U>) -> Option<U> {
287 let x = f(opt.as_mut()?);