4 use super::super::{Iterator, DoubleEndedIterator, FusedIterator, TrustedLen}
;
6 /// An iterator that links two iterators together, in a chain.
8 /// This `struct` is created by the [`chain`] method on [`Iterator`]. See its
9 /// documentation for more.
11 /// [`chain`]: trait.Iterator.html#method.chain
12 /// [`Iterator`]: trait.Iterator.html
13 #[derive(Clone, Debug)]
14 #[must_use = "iterators are lazy and do nothing unless consumed"]
15 #[stable(feature = "rust1", since = "1.0.0")]
16 pub struct Chain
<A
, B
> {
21 impl<A
, B
> Chain
<A
, B
> {
22 pub(in super::super) fn new(a
: A
, b
: B
) -> Chain
<A
, B
> {
23 Chain { a, b, state: ChainState::Both }
27 // The iterator protocol specifies that iteration ends with the return value
28 // `None` from `.next()` (or `.next_back()`) and it is unspecified what
29 // further calls return. The chain adaptor must account for this since it uses
32 // It uses three states:
34 // - Both: `a` and `b` are remaining
35 // - Front: `a` remaining
36 // - Back: `b` remaining
38 // The fourth state (neither iterator is remaining) only occurs after Chain has
39 // returned None once, so we don't need to store this state.
40 #[derive(Clone, Debug)]
42 // both front and back iterator are remaining
44 // only front is remaining
46 // only back is remaining
50 #[stable(feature = "rust1", since = "1.0.0")]
51 impl<A
, B
> Iterator
for Chain
<A
, B
> where
53 B
: Iterator
<Item
= A
::Item
>
58 fn next(&mut self) -> Option
<A
::Item
> {
60 ChainState
::Both
=> match self.a
.next() {
61 elt @
Some(..) => elt
,
63 self.state
= ChainState
::Back
;
67 ChainState
::Front
=> self.a
.next(),
68 ChainState
::Back
=> self.b
.next(),
73 #[rustc_inherit_overflow_checks]
74 fn count(self) -> usize {
76 ChainState
::Both
=> self.a
.count() + self.b
.count(),
77 ChainState
::Front
=> self.a
.count(),
78 ChainState
::Back
=> self.b
.count(),
82 fn try_fold
<Acc
, F
, R
>(&mut self, init
: Acc
, mut f
: F
) -> R
where
83 Self: Sized
, F
: FnMut(Acc
, Self::Item
) -> R
, R
: Try
<Ok
=Acc
>
87 ChainState
::Both
| ChainState
::Front
=> {
88 accum
= self.a
.try_fold(accum
, &mut f
)?
;
89 if let ChainState
::Both
= self.state
{
90 self.state
= ChainState
::Back
;
95 if let ChainState
::Back
= self.state
{
96 accum
= self.b
.try_fold(accum
, &mut f
)?
;
101 fn fold
<Acc
, F
>(self, init
: Acc
, mut f
: F
) -> Acc
102 where F
: FnMut(Acc
, Self::Item
) -> Acc
,
104 let mut accum
= init
;
106 ChainState
::Both
| ChainState
::Front
=> {
107 accum
= self.a
.fold(accum
, &mut f
);
112 ChainState
::Both
| ChainState
::Back
=> {
113 accum
= self.b
.fold(accum
, &mut f
);
121 fn nth(&mut self, mut n
: usize) -> Option
<A
::Item
> {
123 ChainState
::Both
| ChainState
::Front
=> {
124 for x
in self.a
.by_ref() {
130 if let ChainState
::Both
= self.state
{
131 self.state
= ChainState
::Back
;
134 ChainState
::Back
=> {}
136 if let ChainState
::Back
= self.state
{
144 fn find
<P
>(&mut self, mut predicate
: P
) -> Option
<Self::Item
> where
145 P
: FnMut(&Self::Item
) -> bool
,
148 ChainState
::Both
=> match self.a
.find(&mut predicate
) {
150 self.state
= ChainState
::Back
;
151 self.b
.find(predicate
)
155 ChainState
::Front
=> self.a
.find(predicate
),
156 ChainState
::Back
=> self.b
.find(predicate
),
161 fn last(self) -> Option
<A
::Item
> {
163 ChainState
::Both
=> {
164 // Must exhaust a before b.
165 let a_last
= self.a
.last();
166 let b_last
= self.b
.last();
169 ChainState
::Front
=> self.a
.last(),
170 ChainState
::Back
=> self.b
.last()
175 fn size_hint(&self) -> (usize, Option
<usize>) {
177 ChainState
::Both
=> {
178 let (a_lower
, a_upper
) = self.a
.size_hint();
179 let (b_lower
, b_upper
) = self.b
.size_hint();
181 let lower
= a_lower
.saturating_add(b_lower
);
183 let upper
= match (a_upper
, b_upper
) {
184 (Some(x
), Some(y
)) => x
.checked_add(y
),
190 ChainState
::Front
=> self.a
.size_hint(),
191 ChainState
::Back
=> self.b
.size_hint(),
196 #[stable(feature = "rust1", since = "1.0.0")]
197 impl<A
, B
> DoubleEndedIterator
for Chain
<A
, B
> where
198 A
: DoubleEndedIterator
,
199 B
: DoubleEndedIterator
<Item
=A
::Item
>,
202 fn next_back(&mut self) -> Option
<A
::Item
> {
204 ChainState
::Both
=> match self.b
.next_back() {
205 elt @
Some(..) => elt
,
207 self.state
= ChainState
::Front
;
211 ChainState
::Front
=> self.a
.next_back(),
212 ChainState
::Back
=> self.b
.next_back(),
217 fn nth_back(&mut self, mut n
: usize) -> Option
<A
::Item
> {
219 ChainState
::Both
| ChainState
::Back
=> {
220 for x
in self.b
.by_ref().rev() {
226 if let ChainState
::Both
= self.state
{
227 self.state
= ChainState
::Front
;
230 ChainState
::Front
=> {}
232 if let ChainState
::Front
= self.state
{
239 fn try_rfold
<Acc
, F
, R
>(&mut self, init
: Acc
, mut f
: F
) -> R
where
240 Self: Sized
, F
: FnMut(Acc
, Self::Item
) -> R
, R
: Try
<Ok
=Acc
>
242 let mut accum
= init
;
244 ChainState
::Both
| ChainState
::Back
=> {
245 accum
= self.b
.try_rfold(accum
, &mut f
)?
;
246 if let ChainState
::Both
= self.state
{
247 self.state
= ChainState
::Front
;
252 if let ChainState
::Front
= self.state
{
253 accum
= self.a
.try_rfold(accum
, &mut f
)?
;
258 fn rfold
<Acc
, F
>(self, init
: Acc
, mut f
: F
) -> Acc
259 where F
: FnMut(Acc
, Self::Item
) -> Acc
,
261 let mut accum
= init
;
263 ChainState
::Both
| ChainState
::Back
=> {
264 accum
= self.b
.rfold(accum
, &mut f
);
269 ChainState
::Both
| ChainState
::Front
=> {
270 accum
= self.a
.rfold(accum
, &mut f
);
279 // Note: *both* must be fused to handle double-ended iterators.
280 #[stable(feature = "fused", since = "1.26.0")]
281 impl<A
, B
> FusedIterator
for Chain
<A
, B
>
282 where A
: FusedIterator
,
283 B
: FusedIterator
<Item
=A
::Item
>,
286 #[unstable(feature = "trusted_len", issue = "37572")]
287 unsafe impl<A
, B
> TrustedLen
for Chain
<A
, B
>
288 where A
: TrustedLen
, B
: TrustedLen
<Item
=A
::Item
>,