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