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}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy