core/iter/adapters/
cloned.rs

1use 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/// An iterator that clones the elements of an underlying iterator.
9///
10/// This `struct` is created by the [`cloned`] method on [`Iterator`]. See its
11/// documentation for more.
12///
13/// [`cloned`]: Iterator::cloned
14/// [`Iterator`]: trait.Iterator.html
15#[stable(feature = "iter_cloned", since = "1.1.0")]
16#[must_use = "iterators are lazy and do nothing unless consumed"]
17#[derive(Clone, Debug)]
18pub struct Cloned<I> {
19    it: I,
20}
21
22impl<I> Cloned<I> {
23    pub(in crate::iter) fn new(it: I) -> Cloned<I> {
24        Cloned { it }
25    }
26}
27
28fn clone_try_fold<T: Clone, Acc, R>(mut f: impl FnMut(Acc, T) -> R) -> impl FnMut(Acc, &T) -> R {
29    move |acc, elt| f(acc, elt.clone())
30}
31
32#[stable(feature = "iter_cloned", since = "1.1.0")]
33impl<'a, I, T: 'a> Iterator for Cloned<I>
34where
35    I: Iterator<Item = &'a T>,
36    T: Clone,
37{
38    type Item = T;
39
40    fn next(&mut self) -> Option<T> {
41        self.it.next().cloned()
42    }
43
44    fn size_hint(&self) -> (usize, Option<usize>) {
45        self.it.size_hint()
46    }
47
48    fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
49    where
50        Self: Sized,
51        F: FnMut(B, Self::Item) -> R,
52        R: Try<Output = B>,
53    {
54        self.it.try_fold(init, clone_try_fold(f))
55    }
56
57    fn fold<Acc, F>(self, init: Acc, f: F) -> Acc
58    where
59        F: FnMut(Acc, Self::Item) -> Acc,
60    {
61        self.it.map(T::clone).fold(init, f)
62    }
63
64    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
65    where
66        Self: TrustedRandomAccessNoCoerce,
67    {
68        // SAFETY: the caller must uphold the contract for
69        // `Iterator::__iterator_get_unchecked`.
70        unsafe { try_get_unchecked(&mut self.it, idx).clone() }
71    }
72}
73
74#[stable(feature = "iter_cloned", since = "1.1.0")]
75impl<'a, I, T: 'a> DoubleEndedIterator for Cloned<I>
76where
77    I: DoubleEndedIterator<Item = &'a T>,
78    T: Clone,
79{
80    fn next_back(&mut self) -> Option<T> {
81        self.it.next_back().cloned()
82    }
83
84    fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
85    where
86        Self: Sized,
87        F: FnMut(B, Self::Item) -> R,
88        R: Try<Output = B>,
89    {
90        self.it.try_rfold(init, clone_try_fold(f))
91    }
92
93    fn rfold<Acc, F>(self, init: Acc, f: F) -> Acc
94    where
95        F: FnMut(Acc, Self::Item) -> Acc,
96    {
97        self.it.map(T::clone).rfold(init, f)
98    }
99}
100
101#[stable(feature = "iter_cloned", since = "1.1.0")]
102impl<'a, I, T: 'a> ExactSizeIterator for Cloned<I>
103where
104    I: ExactSizeIterator<Item = &'a T>,
105    T: Clone,
106{
107    fn len(&self) -> usize {
108        self.it.len()
109    }
110
111    fn is_empty(&self) -> bool {
112        self.it.is_empty()
113    }
114}
115
116#[stable(feature = "fused", since = "1.26.0")]
117impl<'a, I, T: 'a> FusedIterator for Cloned<I>
118where
119    I: FusedIterator<Item = &'a T>,
120    T: Clone,
121{
122}
123
124#[doc(hidden)]
125#[unstable(feature = "trusted_random_access", issue = "none")]
126unsafe impl<I> TrustedRandomAccess for Cloned<I> where I: TrustedRandomAccess {}
127
128#[doc(hidden)]
129#[unstable(feature = "trusted_random_access", issue = "none")]
130unsafe impl<I> TrustedRandomAccessNoCoerce for Cloned<I>
131where
132    I: TrustedRandomAccessNoCoerce,
133{
134    const MAY_HAVE_SIDE_EFFECT: bool = true;
135}
136
137#[unstable(feature = "trusted_len", issue = "37572")]
138unsafe impl<'a, I, T: 'a> TrustedLen for Cloned<I>
139where
140    I: TrustedLen<Item = &'a T>,
141    T: Clone,
142{
143}
144
145impl<'a, I, T: 'a> UncheckedIterator for Cloned<I>
146where
147    I: UncheckedIterator<Item = &'a T>,
148    T: Clone,
149{
150    unsafe fn next_unchecked(&mut self) -> T {
151        // SAFETY: `Cloned` is 1:1 with the inner iterator, so if the caller promised
152        // that there's an element left, the inner iterator has one too.
153        let item = unsafe { self.it.next_unchecked() };
154        item.clone()
155    }
156}
157
158#[stable(feature = "default_iters", since = "1.70.0")]
159impl<I: Default> Default for Cloned<I> {
160    /// Creates a `Cloned` iterator from the default value of `I`
161    /// ```
162    /// # use core::slice;
163    /// # use core::iter::Cloned;
164    /// let iter: Cloned<slice::Iter<'_, u8>> = Default::default();
165    /// assert_eq!(iter.len(), 0);
166    /// ```
167    fn default() -> Self {
168        Self::new(Default::default())
169    }
170}
171
172#[unstable(issue = "none", feature = "inplace_iteration")]
173unsafe impl<I> SourceIter for Cloned<I>
174where
175    I: SourceIter,
176{
177    type Source = I::Source;
178
179    #[inline]
180    unsafe fn as_inner(&mut self) -> &mut I::Source {
181        // SAFETY: unsafe function forwarding to unsafe function with the same requirements
182        unsafe { SourceIter::as_inner(&mut self.it) }
183    }
184}
185
186#[unstable(issue = "none", feature = "inplace_iteration")]
187unsafe impl<I: InPlaceIterable> InPlaceIterable for Cloned<I> {
188    const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
189    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
190}