core/iter/adapters/
cloned.rs

1use core::num::NonZero;
2
3use crate::cmp::Ordering;
4use crate::iter::adapters::zip::try_get_unchecked;
5use crate::iter::adapters::{SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
6use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen, UncheckedIterator};
7use crate::ops::Try;
8
9/// An iterator that clones the elements of an underlying iterator.
10///
11/// This `struct` is created by the [`cloned`] method on [`Iterator`]. See its
12/// documentation for more.
13///
14/// [`cloned`]: Iterator::cloned
15/// [`Iterator`]: trait.Iterator.html
16#[stable(feature = "iter_cloned", since = "1.1.0")]
17#[must_use = "iterators are lazy and do nothing unless consumed"]
18#[derive(Clone, Debug)]
19pub struct Cloned<I> {
20    it: I,
21}
22
23impl<I> Cloned<I> {
24    pub(in crate::iter) fn new(it: I) -> Cloned<I> {
25        Cloned { it }
26    }
27}
28
29fn clone_try_fold<T: Clone, Acc, R>(mut f: impl FnMut(Acc, T) -> R) -> impl FnMut(Acc, &T) -> R {
30    move |acc, elt| f(acc, elt.clone())
31}
32
33#[stable(feature = "iter_cloned", since = "1.1.0")]
34impl<'a, I, T: 'a> Iterator for Cloned<I>
35where
36    I: Iterator<Item = &'a T>,
37    T: Clone,
38{
39    type Item = T;
40
41    fn next(&mut self) -> Option<T> {
42        self.it.next().cloned()
43    }
44
45    #[inline]
46    fn size_hint(&self) -> (usize, Option<usize>) {
47        self.it.size_hint()
48    }
49
50    #[inline]
51    fn count(self) -> usize {
52        self.it.count()
53    }
54
55    fn last(self) -> Option<T> {
56        self.it.last().cloned()
57    }
58
59    #[inline]
60    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
61        self.it.advance_by(n)
62    }
63
64    fn nth(&mut self, n: usize) -> Option<T> {
65        self.it.nth(n).cloned()
66    }
67
68    fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
69    where
70        F: FnMut(B, Self::Item) -> R,
71        R: Try<Output = B>,
72    {
73        self.it.try_fold(init, clone_try_fold(f))
74    }
75
76    fn fold<Acc, F>(self, init: Acc, f: F) -> Acc
77    where
78        F: FnMut(Acc, Self::Item) -> Acc,
79    {
80        self.it.map(T::clone).fold(init, f)
81    }
82
83    fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item>
84    where
85        P: FnMut(&Self::Item) -> bool,
86    {
87        self.it.find(move |x| predicate(&x)).cloned()
88    }
89
90    fn max_by<F>(self, mut compare: F) -> Option<Self::Item>
91    where
92        F: FnMut(&Self::Item, &Self::Item) -> Ordering,
93    {
94        self.it.max_by(move |&x, &y| compare(x, y)).cloned()
95    }
96
97    fn min_by<F>(self, mut compare: F) -> Option<Self::Item>
98    where
99        F: FnMut(&Self::Item, &Self::Item) -> Ordering,
100    {
101        self.it.min_by(move |&x, &y| compare(x, y)).cloned()
102    }
103
104    fn cmp<O>(self, other: O) -> Ordering
105    where
106        O: IntoIterator<Item = Self::Item>,
107        Self::Item: Ord,
108    {
109        self.it.cmp_by(other, |x, y| x.cmp(&y))
110    }
111
112    fn partial_cmp<O>(self, other: O) -> Option<Ordering>
113    where
114        O: IntoIterator,
115        Self::Item: PartialOrd<O::Item>,
116    {
117        self.it.partial_cmp_by(other, |x, y| x.partial_cmp(&y))
118    }
119
120    fn eq<O>(self, other: O) -> bool
121    where
122        O: IntoIterator,
123        Self::Item: PartialEq<O::Item>,
124    {
125        self.it.eq_by(other, |x, y| x == &y)
126    }
127
128    fn is_sorted_by<F>(self, mut compare: F) -> bool
129    where
130        F: FnMut(&Self::Item, &Self::Item) -> bool,
131    {
132        self.it.is_sorted_by(move |&x, &y| compare(x, y))
133    }
134
135    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
136    where
137        Self: TrustedRandomAccessNoCoerce,
138    {
139        // SAFETY: the caller must uphold the contract for
140        // `Iterator::__iterator_get_unchecked`.
141        unsafe { try_get_unchecked(&mut self.it, idx).clone() }
142    }
143}
144
145#[stable(feature = "iter_cloned", since = "1.1.0")]
146impl<'a, I, T: 'a> DoubleEndedIterator for Cloned<I>
147where
148    I: DoubleEndedIterator<Item = &'a T>,
149    T: Clone,
150{
151    fn next_back(&mut self) -> Option<T> {
152        self.it.next_back().cloned()
153    }
154
155    #[inline]
156    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
157        self.it.advance_back_by(n)
158    }
159
160    fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
161    where
162        F: FnMut(B, Self::Item) -> R,
163        R: Try<Output = B>,
164    {
165        self.it.try_rfold(init, clone_try_fold(f))
166    }
167
168    fn rfold<Acc, F>(self, init: Acc, f: F) -> Acc
169    where
170        F: FnMut(Acc, Self::Item) -> Acc,
171    {
172        self.it.map(T::clone).rfold(init, f)
173    }
174
175    fn rfind<P>(&mut self, mut predicate: P) -> Option<Self::Item>
176    where
177        P: FnMut(&Self::Item) -> bool,
178    {
179        self.it.rfind(move |x| predicate(&x)).cloned()
180    }
181}
182
183#[stable(feature = "iter_cloned", since = "1.1.0")]
184impl<'a, I, T: 'a> ExactSizeIterator for Cloned<I>
185where
186    I: ExactSizeIterator<Item = &'a T>,
187    T: Clone,
188{
189    #[inline]
190    fn len(&self) -> usize {
191        self.it.len()
192    }
193
194    #[inline]
195    fn is_empty(&self) -> bool {
196        self.it.is_empty()
197    }
198}
199
200#[stable(feature = "fused", since = "1.26.0")]
201impl<'a, I, T: 'a> FusedIterator for Cloned<I>
202where
203    I: FusedIterator<Item = &'a T>,
204    T: Clone,
205{
206}
207
208#[doc(hidden)]
209#[unstable(feature = "trusted_random_access", issue = "none")]
210unsafe impl<I> TrustedRandomAccess for Cloned<I> where I: TrustedRandomAccess {}
211
212#[doc(hidden)]
213#[unstable(feature = "trusted_random_access", issue = "none")]
214unsafe impl<I> TrustedRandomAccessNoCoerce for Cloned<I>
215where
216    I: TrustedRandomAccessNoCoerce,
217{
218    const MAY_HAVE_SIDE_EFFECT: bool = true;
219}
220
221#[unstable(feature = "trusted_len", issue = "37572")]
222unsafe impl<'a, I, T: 'a> TrustedLen for Cloned<I>
223where
224    I: TrustedLen<Item = &'a T>,
225    T: Clone,
226{
227}
228
229impl<'a, I, T: 'a> UncheckedIterator for Cloned<I>
230where
231    I: UncheckedIterator<Item = &'a T>,
232    T: Clone,
233{
234    unsafe fn next_unchecked(&mut self) -> T {
235        // SAFETY: `Cloned` is 1:1 with the inner iterator, so if the caller promised
236        // that there's an element left, the inner iterator has one too.
237        let item = unsafe { self.it.next_unchecked() };
238        item.clone()
239    }
240}
241
242#[stable(feature = "default_iters", since = "1.70.0")]
243impl<I: Default> Default for Cloned<I> {
244    /// Creates a `Cloned` iterator from the default value of `I`
245    /// ```
246    /// # use core::slice;
247    /// # use core::iter::Cloned;
248    /// let iter: Cloned<slice::Iter<'_, u8>> = Default::default();
249    /// assert_eq!(iter.len(), 0);
250    /// ```
251    fn default() -> Self {
252        Self::new(Default::default())
253    }
254}
255
256#[unstable(issue = "none", feature = "inplace_iteration")]
257unsafe impl<I> SourceIter for Cloned<I>
258where
259    I: SourceIter,
260{
261    type Source = I::Source;
262
263    #[inline]
264    unsafe fn as_inner(&mut self) -> &mut I::Source {
265        // SAFETY: unsafe function forwarding to unsafe function with the same requirements
266        unsafe { SourceIter::as_inner(&mut self.it) }
267    }
268}
269
270#[unstable(issue = "none", feature = "inplace_iteration")]
271unsafe impl<I: InPlaceIterable> InPlaceIterable for Cloned<I> {
272    const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
273    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
274}