1use crate::iter::{FusedIterator, TrustedLen};
2use crate::num::NonZero;
3use crate::ops::Try;
4
5#[derive(Clone, Debug)]
21#[must_use = "iterators are lazy and do nothing unless consumed"]
22#[stable(feature = "rust1", since = "1.0.0")]
23#[ferrocene::prevalidated]
24pub struct Chain<A, B> {
25 a: Option<A>,
34 b: Option<B>,
35}
36impl<A, B> Chain<A, B> {
37 #[ferrocene::prevalidated]
38 pub(in super::super) fn new(a: A, b: B) -> Chain<A, B> {
39 Chain { a: Some(a), b: Some(b) }
40 }
41}
42
43#[stable(feature = "iter_chain", since = "1.91.0")]
66pub fn chain<A, B>(a: A, b: B) -> Chain<A::IntoIter, B::IntoIter>
67where
68 A: IntoIterator,
69 B: IntoIterator<Item = A::Item>,
70{
71 Chain::new(a.into_iter(), b.into_iter())
72}
73
74#[stable(feature = "rust1", since = "1.0.0")]
75impl<A, B> Iterator for Chain<A, B>
76where
77 A: Iterator,
78 B: Iterator<Item = A::Item>,
79{
80 type Item = A::Item;
81
82 #[inline]
83 #[ferrocene::prevalidated]
84 fn next(&mut self) -> Option<A::Item> {
85 and_then_or_clear(&mut self.a, Iterator::next).or_else(|| self.b.as_mut()?.next())
86 }
87
88 #[inline]
89 #[rustc_inherit_overflow_checks]
90 #[ferrocene::prevalidated]
91 fn count(self) -> usize {
92 let a_count = match self.a {
93 Some(a) => a.count(),
94 None => 0,
95 };
96 let b_count = match self.b {
97 Some(b) => b.count(),
98 None => 0,
99 };
100 a_count + b_count
101 }
102
103 #[ferrocene::prevalidated]
104 fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
105 where
106 Self: Sized,
107 F: FnMut(Acc, Self::Item) -> R,
108 R: Try<Output = Acc>,
109 {
110 if let Some(ref mut a) = self.a {
111 acc = a.try_fold(acc, &mut f)?;
112 self.a = None;
113 }
114 if let Some(ref mut b) = self.b {
115 acc = b.try_fold(acc, f)?;
116 }
118 try { acc }
119 }
120
121 #[ferrocene::prevalidated]
122 fn fold<Acc, F>(self, mut acc: Acc, mut f: F) -> Acc
123 where
124 F: FnMut(Acc, Self::Item) -> Acc,
125 {
126 if let Some(a) = self.a {
127 acc = a.fold(acc, &mut f);
128 }
129 if let Some(b) = self.b {
130 acc = b.fold(acc, f);
131 }
132 acc
133 }
134
135 #[inline]
136 #[ferrocene::prevalidated]
137 fn advance_by(&mut self, mut n: usize) -> Result<(), NonZero<usize>> {
138 if let Some(ref mut a) = self.a {
139 n = match a.advance_by(n) {
140 Ok(()) => return Ok(()),
141 Err(k) => k.get(),
142 };
143 self.a = None;
144 }
145
146 if let Some(ref mut b) = self.b {
147 return b.advance_by(n);
148 }
150
151 NonZero::new(n).map_or(Ok(()), Err)
152 }
153
154 #[inline]
155 #[ferrocene::prevalidated]
156 fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
157 if let Some(ref mut a) = self.a {
158 n = match a.advance_by(n) {
159 Ok(()) => match a.next() {
160 None => 0,
161 x => return x,
162 },
163 Err(k) => k.get(),
164 };
165
166 self.a = None;
167 }
168
169 self.b.as_mut()?.nth(n)
170 }
171
172 #[inline]
173 #[ferrocene::prevalidated]
174 fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item>
175 where
176 P: FnMut(&Self::Item) -> bool,
177 {
178 and_then_or_clear(&mut self.a, |a| a.find(&mut predicate))
179 .or_else(|| self.b.as_mut()?.find(predicate))
180 }
181
182 #[inline]
183 #[ferrocene::prevalidated]
184 fn last(self) -> Option<A::Item> {
185 let a_last = self.a.and_then(Iterator::last);
187 let b_last = self.b.and_then(Iterator::last);
188 b_last.or(a_last)
189 }
190
191 #[inline]
192 #[ferrocene::prevalidated]
193 fn size_hint(&self) -> (usize, Option<usize>) {
194 match self {
195 Chain { a: Some(a), b: Some(b) } => {
196 let (a_lower, a_upper) = a.size_hint();
197 let (b_lower, b_upper) = b.size_hint();
198
199 let lower = a_lower.saturating_add(b_lower);
200
201 let upper = match (a_upper, b_upper) {
202 (Some(x), Some(y)) => x.checked_add(y),
203 _ => None,
204 };
205
206 (lower, upper)
207 }
208 Chain { a: Some(a), b: None } => a.size_hint(),
209 Chain { a: None, b: Some(b) } => b.size_hint(),
210 Chain { a: None, b: None } => (0, Some(0)),
211 }
212 }
213}
214
215#[stable(feature = "rust1", since = "1.0.0")]
216impl<A, B> DoubleEndedIterator for Chain<A, B>
217where
218 A: DoubleEndedIterator,
219 B: DoubleEndedIterator<Item = A::Item>,
220{
221 #[inline]
222 fn next_back(&mut self) -> Option<A::Item> {
223 and_then_or_clear(&mut self.b, |b| b.next_back()).or_else(|| self.a.as_mut()?.next_back())
224 }
225
226 #[inline]
227 fn advance_back_by(&mut self, mut n: usize) -> Result<(), NonZero<usize>> {
228 if let Some(ref mut b) = self.b {
229 n = match b.advance_back_by(n) {
230 Ok(()) => return Ok(()),
231 Err(k) => k.get(),
232 };
233 self.b = None;
234 }
235
236 if let Some(ref mut a) = self.a {
237 return a.advance_back_by(n);
238 }
240
241 NonZero::new(n).map_or(Ok(()), Err)
242 }
243
244 #[inline]
245 fn nth_back(&mut self, mut n: usize) -> Option<Self::Item> {
246 if let Some(ref mut b) = self.b {
247 n = match b.advance_back_by(n) {
248 Ok(()) => match b.next_back() {
249 None => 0,
250 x => return x,
251 },
252 Err(k) => k.get(),
253 };
254
255 self.b = None;
256 }
257
258 self.a.as_mut()?.nth_back(n)
259 }
260
261 #[inline]
262 fn rfind<P>(&mut self, mut predicate: P) -> Option<Self::Item>
263 where
264 P: FnMut(&Self::Item) -> bool,
265 {
266 and_then_or_clear(&mut self.b, |b| b.rfind(&mut predicate))
267 .or_else(|| self.a.as_mut()?.rfind(predicate))
268 }
269
270 fn try_rfold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
271 where
272 Self: Sized,
273 F: FnMut(Acc, Self::Item) -> R,
274 R: Try<Output = Acc>,
275 {
276 if let Some(ref mut b) = self.b {
277 acc = b.try_rfold(acc, &mut f)?;
278 self.b = None;
279 }
280 if let Some(ref mut a) = self.a {
281 acc = a.try_rfold(acc, f)?;
282 }
284 try { acc }
285 }
286
287 fn rfold<Acc, F>(self, mut acc: Acc, mut f: F) -> Acc
288 where
289 F: FnMut(Acc, Self::Item) -> Acc,
290 {
291 if let Some(b) = self.b {
292 acc = b.rfold(acc, &mut f);
293 }
294 if let Some(a) = self.a {
295 acc = a.rfold(acc, f);
296 }
297 acc
298 }
299}
300
301#[stable(feature = "fused", since = "1.26.0")]
303impl<A, B> FusedIterator for Chain<A, B>
304where
305 A: FusedIterator,
306 B: FusedIterator<Item = A::Item>,
307{
308}
309
310#[unstable(feature = "trusted_len", issue = "37572")]
311unsafe impl<A, B> TrustedLen for Chain<A, B>
312where
313 A: TrustedLen,
314 B: TrustedLen<Item = A::Item>,
315{
316}
317
318#[stable(feature = "default_iters", since = "1.70.0")]
319impl<A: Default, B: Default> Default for Chain<A, B> {
320 fn default() -> Self {
337 Chain::new(Default::default(), Default::default())
338 }
339}
340
341#[inline]
342#[ferrocene::prevalidated]
343fn and_then_or_clear<T, U>(opt: &mut Option<T>, f: impl FnOnce(&mut T) -> Option<U>) -> Option<U> {
344 let x = f(opt.as_mut()?);
345 if x.is_none() {
346 *opt = None;
347 }
348 x
349}