1#[cfg(not(feature = "ferrocene_certified"))]
2use crate::fmt;
3#[cfg(not(feature = "ferrocene_certified"))]
4use crate::iter::adapters::zip::try_get_unchecked;
5#[cfg(not(feature = "ferrocene_certified"))]
6use crate::iter::adapters::{SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
7#[cfg(not(feature = "ferrocene_certified"))]
8use crate::iter::{FusedIterator, InPlaceIterable, TrustedFused, TrustedLen, UncheckedIterator};
9#[cfg(not(feature = "ferrocene_certified"))]
10use crate::num::NonZero;
11#[cfg(not(feature = "ferrocene_certified"))]
12use crate::ops::Try;
13
14#[cfg(feature = "ferrocene_certified")]
16#[rustfmt::skip]
17use crate::iter::{TrustedLen, UncheckedIterator};
18
19#[must_use = "iterators are lazy and do nothing unless consumed"]
70#[stable(feature = "rust1", since = "1.0.0")]
71#[derive(Clone)]
72pub struct Map<I, F> {
73 pub(crate) iter: I,
75 f: F,
76}
77
78impl<I, F> Map<I, F> {
79 pub(in crate::iter) fn new(iter: I, f: F) -> Map<I, F> {
80 Map { iter, f }
81 }
82
83 #[cfg(not(feature = "ferrocene_certified"))]
84 pub(crate) fn into_inner(self) -> I {
85 self.iter
86 }
87}
88
89#[stable(feature = "core_impl_debug", since = "1.9.0")]
90#[cfg(not(feature = "ferrocene_certified"))]
91impl<I: fmt::Debug, F> fmt::Debug for Map<I, F> {
92 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93 f.debug_struct("Map").field("iter", &self.iter).finish()
94 }
95}
96
97#[cfg(not(feature = "ferrocene_certified"))]
98fn map_fold<T, B, Acc>(
99 mut f: impl FnMut(T) -> B,
100 mut g: impl FnMut(Acc, B) -> Acc,
101) -> impl FnMut(Acc, T) -> Acc {
102 move |acc, elt| g(acc, f(elt))
103}
104
105#[cfg(not(feature = "ferrocene_certified"))]
106fn map_try_fold<'a, T, B, Acc, R>(
107 f: &'a mut impl FnMut(T) -> B,
108 mut g: impl FnMut(Acc, B) -> R + 'a,
109) -> impl FnMut(Acc, T) -> R + 'a {
110 move |acc, elt| g(acc, f(elt))
111}
112
113#[stable(feature = "rust1", since = "1.0.0")]
114impl<B, I: Iterator, F> Iterator for Map<I, F>
115where
116 F: FnMut(I::Item) -> B,
117{
118 type Item = B;
119
120 #[inline]
121 fn next(&mut self) -> Option<B> {
122 self.iter.next().map(&mut self.f)
123 }
124
125 #[inline]
126 fn size_hint(&self) -> (usize, Option<usize>) {
127 self.iter.size_hint()
128 }
129
130 #[cfg(not(feature = "ferrocene_certified"))]
131 fn try_fold<Acc, G, R>(&mut self, init: Acc, g: G) -> R
132 where
133 Self: Sized,
134 G: FnMut(Acc, Self::Item) -> R,
135 R: Try<Output = Acc>,
136 {
137 self.iter.try_fold(init, map_try_fold(&mut self.f, g))
138 }
139
140 #[cfg(not(feature = "ferrocene_certified"))]
141 fn fold<Acc, G>(self, init: Acc, g: G) -> Acc
142 where
143 G: FnMut(Acc, Self::Item) -> Acc,
144 {
145 self.iter.fold(init, map_fold(self.f, g))
146 }
147
148 #[inline]
149 #[cfg(not(feature = "ferrocene_certified"))]
150 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> B
151 where
152 Self: TrustedRandomAccessNoCoerce,
153 {
154 unsafe { (self.f)(try_get_unchecked(&mut self.iter, idx)) }
157 }
158}
159
160#[stable(feature = "rust1", since = "1.0.0")]
161#[cfg(not(feature = "ferrocene_certified"))]
162impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for Map<I, F>
163where
164 F: FnMut(I::Item) -> B,
165{
166 #[inline]
167 fn next_back(&mut self) -> Option<B> {
168 self.iter.next_back().map(&mut self.f)
169 }
170
171 fn try_rfold<Acc, G, R>(&mut self, init: Acc, g: G) -> R
172 where
173 Self: Sized,
174 G: FnMut(Acc, Self::Item) -> R,
175 R: Try<Output = Acc>,
176 {
177 self.iter.try_rfold(init, map_try_fold(&mut self.f, g))
178 }
179
180 fn rfold<Acc, G>(self, init: Acc, g: G) -> Acc
181 where
182 G: FnMut(Acc, Self::Item) -> Acc,
183 {
184 self.iter.rfold(init, map_fold(self.f, g))
185 }
186}
187
188#[stable(feature = "rust1", since = "1.0.0")]
189#[cfg(not(feature = "ferrocene_certified"))]
190impl<B, I: ExactSizeIterator, F> ExactSizeIterator for Map<I, F>
191where
192 F: FnMut(I::Item) -> B,
193{
194 fn len(&self) -> usize {
195 self.iter.len()
196 }
197
198 fn is_empty(&self) -> bool {
199 self.iter.is_empty()
200 }
201}
202
203#[stable(feature = "fused", since = "1.26.0")]
204#[cfg(not(feature = "ferrocene_certified"))]
205impl<B, I: FusedIterator, F> FusedIterator for Map<I, F> where F: FnMut(I::Item) -> B {}
206
207#[unstable(issue = "none", feature = "trusted_fused")]
208#[cfg(not(feature = "ferrocene_certified"))]
209unsafe impl<I: TrustedFused, F> TrustedFused for Map<I, F> {}
210
211#[unstable(feature = "trusted_len", issue = "37572")]
212unsafe impl<B, I, F> TrustedLen for Map<I, F>
213where
214 I: TrustedLen,
215 F: FnMut(I::Item) -> B,
216{
217}
218
219impl<B, I, F> UncheckedIterator for Map<I, F>
220where
221 I: UncheckedIterator,
222 F: FnMut(I::Item) -> B,
223{
224 unsafe fn next_unchecked(&mut self) -> B {
225 let item = unsafe { self.iter.next_unchecked() };
228 (self.f)(item)
229 }
230}
231
232#[doc(hidden)]
233#[unstable(feature = "trusted_random_access", issue = "none")]
234#[cfg(not(feature = "ferrocene_certified"))]
235unsafe impl<I, F> TrustedRandomAccess for Map<I, F> where I: TrustedRandomAccess {}
236
237#[doc(hidden)]
238#[unstable(feature = "trusted_random_access", issue = "none")]
239#[cfg(not(feature = "ferrocene_certified"))]
240unsafe impl<I, F> TrustedRandomAccessNoCoerce for Map<I, F>
241where
242 I: TrustedRandomAccessNoCoerce,
243{
244 const MAY_HAVE_SIDE_EFFECT: bool = true;
245}
246
247#[unstable(issue = "none", feature = "inplace_iteration")]
248#[cfg(not(feature = "ferrocene_certified"))]
249unsafe impl<I, F> SourceIter for Map<I, F>
250where
251 I: SourceIter,
252{
253 type Source = I::Source;
254
255 #[inline]
256 unsafe fn as_inner(&mut self) -> &mut I::Source {
257 unsafe { SourceIter::as_inner(&mut self.iter) }
259 }
260}
261
262#[unstable(issue = "none", feature = "inplace_iteration")]
263#[cfg(not(feature = "ferrocene_certified"))]
264unsafe impl<I: InPlaceIterable, F> InPlaceIterable for Map<I, F> {
265 const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
266 const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
267}