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