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