1#[cfg(not(feature = "ferrocene_certified"))]
2use core::num::NonZero;
3
4#[cfg(not(feature = "ferrocene_certified"))]
5use crate::iter::adapters::zip::try_get_unchecked;
6#[cfg(not(feature = "ferrocene_certified"))]
7use crate::iter::adapters::{SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
8#[cfg(not(feature = "ferrocene_certified"))]
9use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen, UncheckedIterator};
10use crate::ops::Try;
11
12#[cfg(feature = "ferrocene_certified")]
14#[rustfmt::skip]
15use crate::iter::{TrustedLen, UncheckedIterator};
16
17#[stable(feature = "iter_cloned", since = "1.1.0")]
25#[must_use = "iterators are lazy and do nothing unless consumed"]
26#[cfg_attr(not(feature = "ferrocene_certified"), derive(Clone, Debug))]
27#[cfg_attr(feature = "ferrocene_certified", derive(Clone))]
28pub struct Cloned<I> {
29 it: I,
30}
31
32impl<I> Cloned<I> {
33 pub(in crate::iter) fn new(it: I) -> Cloned<I> {
34 Cloned { it }
35 }
36}
37
38fn clone_try_fold<T: Clone, Acc, R>(mut f: impl FnMut(Acc, T) -> R) -> impl FnMut(Acc, &T) -> R {
39 move |acc, elt| f(acc, elt.clone())
40}
41
42#[stable(feature = "iter_cloned", since = "1.1.0")]
43impl<'a, I, T: 'a> Iterator for Cloned<I>
44where
45 I: Iterator<Item = &'a T>,
46 T: Clone,
47{
48 type Item = T;
49
50 fn next(&mut self) -> Option<T> {
51 self.it.next().cloned()
52 }
53
54 fn size_hint(&self) -> (usize, Option<usize>) {
55 self.it.size_hint()
56 }
57
58 fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
59 where
60 Self: Sized,
61 F: FnMut(B, Self::Item) -> R,
62 R: Try<Output = B>,
63 {
64 self.it.try_fold(init, clone_try_fold(f))
65 }
66
67 fn fold<Acc, F>(self, init: Acc, f: F) -> Acc
68 where
69 F: FnMut(Acc, Self::Item) -> Acc,
70 {
71 self.it.map(T::clone).fold(init, f)
72 }
73
74 #[cfg(not(feature = "ferrocene_certified"))]
75 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
76 where
77 Self: TrustedRandomAccessNoCoerce,
78 {
79 unsafe { try_get_unchecked(&mut self.it, idx).clone() }
82 }
83}
84
85#[stable(feature = "iter_cloned", since = "1.1.0")]
86#[cfg(not(feature = "ferrocene_certified"))]
87impl<'a, I, T: 'a> DoubleEndedIterator for Cloned<I>
88where
89 I: DoubleEndedIterator<Item = &'a T>,
90 T: Clone,
91{
92 fn next_back(&mut self) -> Option<T> {
93 self.it.next_back().cloned()
94 }
95
96 fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
97 where
98 Self: Sized,
99 F: FnMut(B, Self::Item) -> R,
100 R: Try<Output = B>,
101 {
102 self.it.try_rfold(init, clone_try_fold(f))
103 }
104
105 fn rfold<Acc, F>(self, init: Acc, f: F) -> Acc
106 where
107 F: FnMut(Acc, Self::Item) -> Acc,
108 {
109 self.it.map(T::clone).rfold(init, f)
110 }
111}
112
113#[stable(feature = "iter_cloned", since = "1.1.0")]
114#[cfg(not(feature = "ferrocene_certified"))]
115impl<'a, I, T: 'a> ExactSizeIterator for Cloned<I>
116where
117 I: ExactSizeIterator<Item = &'a T>,
118 T: Clone,
119{
120 fn len(&self) -> usize {
121 self.it.len()
122 }
123
124 fn is_empty(&self) -> bool {
125 self.it.is_empty()
126 }
127}
128
129#[stable(feature = "fused", since = "1.26.0")]
130#[cfg(not(feature = "ferrocene_certified"))]
131impl<'a, I, T: 'a> FusedIterator for Cloned<I>
132where
133 I: FusedIterator<Item = &'a T>,
134 T: Clone,
135{
136}
137
138#[doc(hidden)]
139#[unstable(feature = "trusted_random_access", issue = "none")]
140#[cfg(not(feature = "ferrocene_certified"))]
141unsafe impl<I> TrustedRandomAccess for Cloned<I> where I: TrustedRandomAccess {}
142
143#[doc(hidden)]
144#[unstable(feature = "trusted_random_access", issue = "none")]
145#[cfg(not(feature = "ferrocene_certified"))]
146unsafe impl<I> TrustedRandomAccessNoCoerce for Cloned<I>
147where
148 I: TrustedRandomAccessNoCoerce,
149{
150 const MAY_HAVE_SIDE_EFFECT: bool = true;
151}
152
153#[unstable(feature = "trusted_len", issue = "37572")]
154unsafe impl<'a, I, T: 'a> TrustedLen for Cloned<I>
155where
156 I: TrustedLen<Item = &'a T>,
157 T: Clone,
158{
159}
160
161impl<'a, I, T: 'a> UncheckedIterator for Cloned<I>
162where
163 I: UncheckedIterator<Item = &'a T>,
164 T: Clone,
165{
166 unsafe fn next_unchecked(&mut self) -> T {
167 let item = unsafe { self.it.next_unchecked() };
170 item.clone()
171 }
172}
173
174#[stable(feature = "default_iters", since = "1.70.0")]
175#[cfg(not(feature = "ferrocene_certified"))]
176impl<I: Default> Default for Cloned<I> {
177 fn default() -> Self {
185 Self::new(Default::default())
186 }
187}
188
189#[unstable(issue = "none", feature = "inplace_iteration")]
190#[cfg(not(feature = "ferrocene_certified"))]
191unsafe impl<I> SourceIter for Cloned<I>
192where
193 I: SourceIter,
194{
195 type Source = I::Source;
196
197 #[inline]
198 unsafe fn as_inner(&mut self) -> &mut I::Source {
199 unsafe { SourceIter::as_inner(&mut self.it) }
201 }
202}
203
204#[unstable(issue = "none", feature = "inplace_iteration")]
205#[cfg(not(feature = "ferrocene_certified"))]
206unsafe impl<I: InPlaceIterable> InPlaceIterable for Cloned<I> {
207 const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
208 const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
209}