1 use crate::iter::{InPlaceIterable, Iterator};
2 use crate::ops::{ControlFlow, Try};
3 
4 mod chain;
5 mod cloned;
6 mod copied;
7 mod cycle;
8 mod enumerate;
9 mod filter;
10 mod filter_map;
11 mod flatten;
12 mod fuse;
13 mod inspect;
14 mod intersperse;
15 mod map;
16 mod map_while;
17 mod peekable;
18 mod rev;
19 mod scan;
20 mod skip;
21 mod skip_while;
22 mod step_by;
23 mod take;
24 mod take_while;
25 mod zip;
26 
27 pub use self::{
28     chain::Chain, cycle::Cycle, enumerate::Enumerate, filter::Filter, filter_map::FilterMap,
29     flatten::FlatMap, fuse::Fuse, inspect::Inspect, map::Map, peekable::Peekable, rev::Rev,
30     scan::Scan, skip::Skip, skip_while::SkipWhile, take::Take, take_while::TakeWhile, zip::Zip,
31 };
32 
33 #[stable(feature = "iter_cloned", since = "1.1.0")]
34 pub use self::cloned::Cloned;
35 
36 #[stable(feature = "iterator_step_by", since = "1.28.0")]
37 pub use self::step_by::StepBy;
38 
39 #[stable(feature = "iterator_flatten", since = "1.29.0")]
40 pub use self::flatten::Flatten;
41 
42 #[stable(feature = "iter_copied", since = "1.36.0")]
43 pub use self::copied::Copied;
44 
45 #[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
46 pub use self::intersperse::{Intersperse, IntersperseWith};
47 
48 #[stable(feature = "iter_map_while", since = "1.57.0")]
49 pub use self::map_while::MapWhile;
50 
51 #[unstable(feature = "trusted_random_access", issue = "none")]
52 pub use self::zip::TrustedRandomAccess;
53 
54 #[unstable(feature = "trusted_random_access", issue = "none")]
55 pub use self::zip::TrustedRandomAccessNoCoerce;
56 
57 #[unstable(feature = "iter_zip", issue = "83574")]
58 pub use self::zip::zip;
59 
60 /// This trait provides transitive access to source-stage in an iterator-adapter pipeline
61 /// under the conditions that
62 /// * the iterator source `S` itself implements `SourceIter<Source = S>`
63 /// * there is a delegating implementation of this trait for each adapter in the pipeline between
64 ///   the source and the pipeline consumer.
65 ///
66 /// When the source is an owning iterator struct (commonly called `IntoIter`) then
67 /// this can be useful for specializing [`FromIterator`] implementations or recovering the
68 /// remaining elements after an iterator has been partially exhausted.
69 ///
70 /// Note that implementations do not necessarily have to provide access to the inner-most
71 /// source of a pipeline. A stateful intermediate adapter might eagerly evaluate a part
72 /// of the pipeline and expose its internal storage as source.
73 ///
74 /// The trait is unsafe because implementers must uphold additional safety properties.
75 /// See [`as_inner`] for details.
76 ///
77 /// # Examples
78 ///
79 /// Retrieving a partially consumed source:
80 ///
81 /// ```
82 /// # #![feature(inplace_iteration)]
83 /// # use std::iter::SourceIter;
84 ///
85 /// let mut iter = vec![9, 9, 9].into_iter().map(|i| i * i);
86 /// let _ = iter.next();
87 /// let mut remainder = std::mem::replace(unsafe { iter.as_inner() }, Vec::new().into_iter());
88 /// println!("n = {} elements remaining", remainder.len());
89 /// ```
90 ///
91 /// [`FromIterator`]: crate::iter::FromIterator
92 /// [`as_inner`]: SourceIter::as_inner
93 #[unstable(issue = "none", feature = "inplace_iteration")]
94 #[doc(hidden)]
95 #[rustc_specialization_trait]
96 pub unsafe trait SourceIter {
97     /// A source stage in an iterator pipeline.
98     type Source;
99 
100     /// Retrieve the source of an iterator pipeline.
101     ///
102     /// # Safety
103     ///
104     /// Implementations of must return the same mutable reference for their lifetime, unless
105     /// replaced by a caller.
106     /// Callers may only replace the reference when they stopped iteration and drop the
107     /// iterator pipeline after extracting the source.
108     ///
109     /// This means iterator adapters can rely on the source not changing during
110     /// iteration but they cannot rely on it in their Drop implementations.
111     ///
112     /// Implementing this method means adapters relinquish private-only access to their
113     /// source and can only rely on guarantees made based on method receiver types.
114     /// The lack of restricted access also requires that adapters must uphold the source's
115     /// public API even when they have access to its internals.
116     ///
117     /// Callers in turn must expect the source to be in any state that is consistent with
118     /// its public API since adapters sitting between it and the source have the same
119     /// access. In particular an adapter may have consumed more elements than strictly necessary.
120     ///
121     /// The overall goal of these requirements is to let the consumer of a pipeline use
122     /// * whatever remains in the source after iteration has stopped
123     /// * the memory that has become unused by advancing a consuming iterator
124     ///
125     /// [`next()`]: Iterator::next()
as_inner(&mut self) -> &mut Self::Source126     unsafe fn as_inner(&mut self) -> &mut Self::Source;
127 }
128 
129 /// An iterator adapter that produces output as long as the underlying
130 /// iterator produces `Result::Ok` values.
131 ///
132 /// If an error is encountered, the iterator stops and the error is
133 /// stored.
134 pub(crate) struct ResultShunt<'a, I, E> {
135     iter: I,
136     error: &'a mut Result<(), E>,
137 }
138 
139 /// Process the given iterator as if it yielded a `T` instead of a
140 /// `Result<T, _>`. Any errors will stop the inner iterator and
141 /// the overall result will be an error.
process_results<I, T, E, F, U>(iter: I, mut f: F) -> Result<U, E> where I: Iterator<Item = Result<T, E>>, for<'a> F: FnMut(ResultShunt<'a, I, E>) -> U,142 pub(crate) fn process_results<I, T, E, F, U>(iter: I, mut f: F) -> Result<U, E>
143 where
144     I: Iterator<Item = Result<T, E>>,
145     for<'a> F: FnMut(ResultShunt<'a, I, E>) -> U,
146 {
147     let mut error = Ok(());
148     let shunt = ResultShunt { iter, error: &mut error };
149     let value = f(shunt);
150     error.map(|()| value)
151 }
152 
153 impl<I, T, E> Iterator for ResultShunt<'_, I, E>
154 where
155     I: Iterator<Item = Result<T, E>>,
156 {
157     type Item = T;
158 
next(&mut self) -> Option<Self::Item>159     fn next(&mut self) -> Option<Self::Item> {
160         self.find(|_| true)
161     }
162 
size_hint(&self) -> (usize, Option<usize>)163     fn size_hint(&self) -> (usize, Option<usize>) {
164         if self.error.is_err() {
165             (0, Some(0))
166         } else {
167             let (_, upper) = self.iter.size_hint();
168             (0, upper)
169         }
170     }
171 
try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where F: FnMut(B, Self::Item) -> R, R: Try<Output = B>,172     fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
173     where
174         F: FnMut(B, Self::Item) -> R,
175         R: Try<Output = B>,
176     {
177         let error = &mut *self.error;
178         self.iter
179             .try_fold(init, |acc, x| match x {
180                 Ok(x) => ControlFlow::from_try(f(acc, x)),
181                 Err(e) => {
182                     *error = Err(e);
183                     ControlFlow::Break(try { acc })
184                 }
185             })
186             .into_try()
187     }
188 
fold<B, F>(mut self, init: B, fold: F) -> B where Self: Sized, F: FnMut(B, Self::Item) -> B,189     fn fold<B, F>(mut self, init: B, fold: F) -> B
190     where
191         Self: Sized,
192         F: FnMut(B, Self::Item) -> B,
193     {
194         #[inline]
195         fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
196             move |acc, x| Ok(f(acc, x))
197         }
198 
199         self.try_fold(init, ok(fold)).unwrap()
200     }
201 }
202 
203 #[unstable(issue = "none", feature = "inplace_iteration")]
204 unsafe impl<I, E> SourceIter for ResultShunt<'_, I, E>
205 where
206     I: SourceIter,
207 {
208     type Source = I::Source;
209 
210     #[inline]
as_inner(&mut self) -> &mut Self::Source211     unsafe fn as_inner(&mut self) -> &mut Self::Source {
212         // SAFETY: unsafe function forwarding to unsafe function with the same requirements
213         unsafe { SourceIter::as_inner(&mut self.iter) }
214     }
215 }
216 
217 // SAFETY: ResultShunt::next calls I::find, which has to advance `iter` in order to
218 // return `Some(_)`. Since `iter` has type `I: InPlaceIterable` it's guaranteed that
219 // at least one item will be moved out from the underlying source.
220 #[unstable(issue = "none", feature = "inplace_iteration")]
221 unsafe impl<I, T, E> InPlaceIterable for ResultShunt<'_, I, E> where
222     I: Iterator<Item = Result<T, E>> + InPlaceIterable
223 {
224 }
225