1use crate::fmt;
2use crate::iter::adapters::{
3 zip::try_get_unchecked, SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
4};
5use crate::iter::{FusedIterator, InPlaceIterable, TrustedFused, TrustedLen, UncheckedIterator};
6use crate::num::NonZero;
7use crate::ops::Try;
8
9/// An iterator that maps the values of `iter` with `f`.
10///
11/// This `struct` is created by the [`map`] method on [`Iterator`]. See its
12/// documentation for more.
13///
14/// [`map`]: Iterator::map
15/// [`Iterator`]: trait.Iterator.html
16///
17/// # Notes about side effects
18///
19/// The [`map`] iterator implements [`DoubleEndedIterator`], meaning that
20/// you can also [`map`] backwards:
21///
22/// ```rust
23/// let v: Vec<i32> = [1, 2, 3].into_iter().map(|x| x + 1).rev().collect();
24///
25/// assert_eq!(v, [4, 3, 2]);
26/// ```
27///
28/// [`DoubleEndedIterator`]: trait.DoubleEndedIterator.html
29///
30/// But if your closure has state, iterating backwards may act in a way you do
31/// not expect. Let's go through an example. First, in the forward direction:
32///
33/// ```rust
34/// let mut c = 0;
35///
36/// for pair in ['a', 'b', 'c'].into_iter()
37/// .map(|letter| { c += 1; (letter, c) }) {
38/// println!("{pair:?}");
39/// }
40/// ```
41///
42/// This will print `('a', 1), ('b', 2), ('c', 3)`.
43///
44/// Now consider this twist where we add a call to `rev`. This version will
45/// print `('c', 1), ('b', 2), ('a', 3)`. Note that the letters are reversed,
46/// but the values of the counter still go in order. This is because `map()` is
47/// still being called lazily on each item, but we are popping items off the
48/// back of the vector now, instead of shifting them from the front.
49///
50/// ```rust
51/// let mut c = 0;
52///
53/// for pair in ['a', 'b', 'c'].into_iter()
54/// .map(|letter| { c += 1; (letter, c) })
55/// .rev() {
56/// println!("{pair:?}");
57/// }
58/// ```
59#[must_use = "iterators are lazy and do nothing unless consumed"]
60#[stable(feature = "rust1", since = "1.0.0")]
61#[derive(Clone)]
62pub struct Map<I, F> {
63 // Used for `SplitWhitespace` and `SplitAsciiWhitespace` `as_str` methods
64 pub(crate) iter: I,
65 f: F,
66}
67
68impl<I, F> Map<I, F> {
69 pub(in crate::iter) fn new(iter: I, f: F) -> Map<I, F> {
70 Map { iter, f }
71 }
72
73 pub(crate) fn into_inner(self) -> I {
74 self.iter
75 }
76}
77
78#[stable(feature = "core_impl_debug", since = "1.9.0")]
79impl<I: fmt::Debug, F> fmt::Debug for Map<I, F> {
80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81 f.debug_struct("Map").field(name:"iter", &self.iter).finish()
82 }
83}
84
85fn map_fold<T, B, Acc>(
86 mut f: impl FnMut(T) -> B,
87 mut g: impl FnMut(Acc, B) -> Acc,
88) -> impl FnMut(Acc, T) -> Acc {
89 move |acc: Acc, elt: T| g(acc, f(elt))
90}
91
92fn map_try_fold<'a, T, B, Acc, R>(
93 f: &'a mut impl FnMut(T) -> B,
94 mut g: impl FnMut(Acc, B) -> R + 'a,
95) -> impl FnMut(Acc, T) -> R + 'a {
96 move |acc: Acc, elt: T| g(acc, f(elt))
97}
98
99#[stable(feature = "rust1", since = "1.0.0")]
100impl<B, I: Iterator, F> Iterator for Map<I, F>
101where
102 F: FnMut(I::Item) -> B,
103{
104 type Item = B;
105
106 #[inline]
107 fn next(&mut self) -> Option<B> {
108 self.iter.next().map(&mut self.f)
109 }
110
111 #[inline]
112 fn size_hint(&self) -> (usize, Option<usize>) {
113 self.iter.size_hint()
114 }
115
116 fn try_fold<Acc, G, R>(&mut self, init: Acc, g: G) -> R
117 where
118 Self: Sized,
119 G: FnMut(Acc, Self::Item) -> R,
120 R: Try<Output = Acc>,
121 {
122 self.iter.try_fold(init, map_try_fold(&mut self.f, g))
123 }
124
125 fn fold<Acc, G>(self, init: Acc, g: G) -> Acc
126 where
127 G: FnMut(Acc, Self::Item) -> Acc,
128 {
129 self.iter.fold(init, map_fold(self.f, g))
130 }
131
132 #[inline]
133 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> B
134 where
135 Self: TrustedRandomAccessNoCoerce,
136 {
137 // SAFETY: the caller must uphold the contract for
138 // `Iterator::__iterator_get_unchecked`.
139 unsafe { (self.f)(try_get_unchecked(&mut self.iter, idx)) }
140 }
141}
142
143#[stable(feature = "rust1", since = "1.0.0")]
144impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for Map<I, F>
145where
146 F: FnMut(I::Item) -> B,
147{
148 #[inline]
149 fn next_back(&mut self) -> Option<B> {
150 self.iter.next_back().map(&mut self.f)
151 }
152
153 fn try_rfold<Acc, G, R>(&mut self, init: Acc, g: G) -> R
154 where
155 Self: Sized,
156 G: FnMut(Acc, Self::Item) -> R,
157 R: Try<Output = Acc>,
158 {
159 self.iter.try_rfold(init, f:map_try_fold(&mut self.f, g))
160 }
161
162 fn rfold<Acc, G>(self, init: Acc, g: G) -> Acc
163 where
164 G: FnMut(Acc, Self::Item) -> Acc,
165 {
166 self.iter.rfold(init, f:map_fold(self.f, g))
167 }
168}
169
170#[stable(feature = "rust1", since = "1.0.0")]
171impl<B, I: ExactSizeIterator, F> ExactSizeIterator for Map<I, F>
172where
173 F: FnMut(I::Item) -> B,
174{
175 fn len(&self) -> usize {
176 self.iter.len()
177 }
178
179 fn is_empty(&self) -> bool {
180 self.iter.is_empty()
181 }
182}
183
184#[stable(feature = "fused", since = "1.26.0")]
185impl<B, I: FusedIterator, F> FusedIterator for Map<I, F> where F: FnMut(I::Item) -> B {}
186
187#[unstable(issue = "none", feature = "trusted_fused")]
188unsafe impl<I: TrustedFused, F> TrustedFused for Map<I, F> {}
189
190#[unstable(feature = "trusted_len", issue = "37572")]
191unsafe impl<B, I, F> TrustedLen for Map<I, F>
192where
193 I: TrustedLen,
194 F: FnMut(I::Item) -> B,
195{
196}
197
198impl<B, I, F> UncheckedIterator for Map<I, F>
199where
200 I: UncheckedIterator,
201 F: FnMut(I::Item) -> B,
202{
203 unsafe fn next_unchecked(&mut self) -> B {
204 // SAFETY: `Map` is 1:1 with the inner iterator, so if the caller promised
205 // that there's an element left, the inner iterator has one too.
206 let item: ::Item = unsafe { self.iter.next_unchecked() };
207 (self.f)(item)
208 }
209}
210
211#[doc(hidden)]
212#[unstable(feature = "trusted_random_access", issue = "none")]
213unsafe impl<I, F> TrustedRandomAccess for Map<I, F> where I: TrustedRandomAccess {}
214
215#[doc(hidden)]
216#[unstable(feature = "trusted_random_access", issue = "none")]
217unsafe impl<I, F> TrustedRandomAccessNoCoerce for Map<I, F>
218where
219 I: TrustedRandomAccessNoCoerce,
220{
221 const MAY_HAVE_SIDE_EFFECT: bool = true;
222}
223
224#[unstable(issue = "none", feature = "inplace_iteration")]
225unsafe impl<I, F> SourceIter for Map<I, F>
226where
227 I: SourceIter,
228{
229 type Source = I::Source;
230
231 #[inline]
232 unsafe fn as_inner(&mut self) -> &mut I::Source {
233 // SAFETY: unsafe function forwarding to unsafe function with the same requirements
234 unsafe { SourceIter::as_inner(&mut self.iter) }
235 }
236}
237
238#[unstable(issue = "none", feature = "inplace_iteration")]
239unsafe impl<I: InPlaceIterable, F> InPlaceIterable for Map<I, F> {
240 const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
241 const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
242}
243