1use crate::iter::InPlaceIterable;
2use crate::num::NonZero;
3use crate::ops::{ChangeOutputType, ControlFlow, FromResidual, Residual, Try};
4
5mod array_chunks;
6mod by_ref_sized;
7mod chain;
8mod cloned;
9mod copied;
10mod cycle;
11mod enumerate;
12mod filter;
13mod filter_map;
14mod flatten;
15mod fuse;
16mod inspect;
17mod intersperse;
18mod map;
19mod map_while;
20mod map_windows;
21mod peekable;
22mod rev;
23mod scan;
24mod skip;
25mod skip_while;
26mod step_by;
27mod take;
28mod take_while;
29mod zip;
30
31#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
32pub use self::array_chunks::ArrayChunks;
33#[unstable(feature = "std_internals", issue = "none")]
34pub use self::by_ref_sized::ByRefSized;
35#[unstable(feature = "iter_chain", reason = "recently added", issue = "125964")]
36pub use self::chain::chain;
37#[stable(feature = "iter_cloned", since = "1.1.0")]
38pub use self::cloned::Cloned;
39#[stable(feature = "iter_copied", since = "1.36.0")]
40pub use self::copied::Copied;
41#[stable(feature = "iterator_flatten", since = "1.29.0")]
42pub use self::flatten::Flatten;
43#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
44pub use self::intersperse::{Intersperse, IntersperseWith};
45#[stable(feature = "iter_map_while", since = "1.57.0")]
46pub use self::map_while::MapWhile;
47#[unstable(feature = "iter_map_windows", reason = "recently added", issue = "87155")]
48pub use self::map_windows::MapWindows;
49#[stable(feature = "iterator_step_by", since = "1.28.0")]
50pub use self::step_by::StepBy;
51#[unstable(feature = "trusted_random_access", issue = "none")]
52pub use self::zip::TrustedRandomAccess;
53#[unstable(feature = "trusted_random_access", issue = "none")]
54pub use self::zip::TrustedRandomAccessNoCoerce;
55#[stable(feature = "iter_zip", since = "1.59.0")]
56pub use self::zip::zip;
57#[stable(feature = "rust1", since = "1.0.0")]
58pub use self::{
59    chain::Chain, cycle::Cycle, enumerate::Enumerate, filter::Filter, filter_map::FilterMap,
60    flatten::FlatMap, fuse::Fuse, inspect::Inspect, map::Map, peekable::Peekable, rev::Rev,
61    scan::Scan, skip::Skip, skip_while::SkipWhile, take::Take, take_while::TakeWhile, zip::Zip,
62};
63
64#[unstable(issue = "none", feature = "inplace_iteration")]
103#[doc(hidden)]
104#[rustc_specialization_trait]
105pub unsafe trait SourceIter {
106    type Source;
108
109    unsafe fn as_inner(&mut self) -> &mut Self::Source;
137}
138
139pub(crate) struct GenericShunt<'a, I, R> {
145    iter: I,
146    residual: &'a mut Option<R>,
147}
148
149pub(crate) fn try_process<I, T, R, F, U>(iter: I, mut f: F) -> ChangeOutputType<I::Item, U>
153where
154    I: Iterator<Item: Try<Output = T, Residual = R>>,
155    for<'a> F: FnMut(GenericShunt<'a, I, R>) -> U,
156    R: Residual<U>,
157{
158    let mut residual = None;
159    let shunt = GenericShunt { iter, residual: &mut residual };
160    let value = f(shunt);
161    match residual {
162        Some(r) => FromResidual::from_residual(r),
163        None => Try::from_output(value),
164    }
165}
166
167impl<I, R> Iterator for GenericShunt<'_, I, R>
168where
169    I: Iterator<Item: Try<Residual = R>>,
170{
171    type Item = <I::Item as Try>::Output;
172
173    fn next(&mut self) -> Option<Self::Item> {
174        self.try_for_each(ControlFlow::Break).break_value()
175    }
176
177    fn size_hint(&self) -> (usize, Option<usize>) {
178        if self.residual.is_some() {
179            (0, Some(0))
180        } else {
181            let (_, upper) = self.iter.size_hint();
182            (0, upper)
183        }
184    }
185
186    fn try_fold<B, F, T>(&mut self, init: B, mut f: F) -> T
187    where
188        F: FnMut(B, Self::Item) -> T,
189        T: Try<Output = B>,
190    {
191        self.iter
192            .try_fold(init, |acc, x| match Try::branch(x) {
193                ControlFlow::Continue(x) => ControlFlow::from_try(f(acc, x)),
194                ControlFlow::Break(r) => {
195                    *self.residual = Some(r);
196                    ControlFlow::Break(try { acc })
197                }
198            })
199            .into_try()
200    }
201
202    impl_fold_via_try_fold! { fold -> try_fold }
203}
204
205#[unstable(issue = "none", feature = "inplace_iteration")]
206unsafe impl<I, R> SourceIter for GenericShunt<'_, I, R>
207where
208    I: SourceIter,
209{
210    type Source = I::Source;
211
212    #[inline]
213    unsafe fn as_inner(&mut self) -> &mut Self::Source {
214        unsafe { SourceIter::as_inner(&mut self.iter) }
216    }
217}
218
219#[unstable(issue = "none", feature = "inplace_iteration")]
223unsafe impl<I, R> InPlaceIterable for GenericShunt<'_, I, R>
224where
225    I: InPlaceIterable,
226{
227    const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
228    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
229}