]> git.proxmox.com Git - rustc.git/blame - library/core/src/iter/adapters/cloned.rs
New upstream version 1.52.0~beta.3+dfsg1
[rustc.git] / library / core / src / iter / adapters / cloned.rs
CommitLineData
fc512014
XL
1use crate::iter::adapters::{zip::try_get_unchecked, TrustedRandomAccess};
2use crate::iter::{FusedIterator, TrustedLen};
3use crate::ops::Try;
4
5/// An iterator that clones the elements of an underlying iterator.
6///
7/// This `struct` is created by the [`cloned`] method on [`Iterator`]. See its
8/// documentation for more.
9///
10/// [`cloned`]: Iterator::cloned
11/// [`Iterator`]: trait.Iterator.html
12#[stable(feature = "iter_cloned", since = "1.1.0")]
13#[must_use = "iterators are lazy and do nothing unless consumed"]
14#[derive(Clone, Debug)]
15pub struct Cloned<I> {
16 it: I,
17}
18
19impl<I> Cloned<I> {
20 pub(in crate::iter) fn new(it: I) -> Cloned<I> {
21 Cloned { it }
22 }
23}
24
25fn clone_try_fold<T: Clone, Acc, R>(mut f: impl FnMut(Acc, T) -> R) -> impl FnMut(Acc, &T) -> R {
26 move |acc, elt| f(acc, elt.clone())
27}
28
29#[stable(feature = "iter_cloned", since = "1.1.0")]
30impl<'a, I, T: 'a> Iterator for Cloned<I>
31where
32 I: Iterator<Item = &'a T>,
33 T: Clone,
34{
35 type Item = T;
36
37 fn next(&mut self) -> Option<T> {
38 self.it.next().cloned()
39 }
40
41 fn size_hint(&self) -> (usize, Option<usize>) {
42 self.it.size_hint()
43 }
44
45 fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
46 where
47 Self: Sized,
48 F: FnMut(B, Self::Item) -> R,
49 R: Try<Ok = B>,
50 {
51 self.it.try_fold(init, clone_try_fold(f))
52 }
53
54 fn fold<Acc, F>(self, init: Acc, f: F) -> Acc
55 where
56 F: FnMut(Acc, Self::Item) -> Acc,
57 {
58 self.it.map(T::clone).fold(init, f)
59 }
60
61 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
62 where
63 Self: TrustedRandomAccess,
64 {
65 // SAFETY: the caller must uphold the contract for
66 // `Iterator::__iterator_get_unchecked`.
67 unsafe { try_get_unchecked(&mut self.it, idx).clone() }
68 }
69}
70
71#[stable(feature = "iter_cloned", since = "1.1.0")]
72impl<'a, I, T: 'a> DoubleEndedIterator for Cloned<I>
73where
74 I: DoubleEndedIterator<Item = &'a T>,
75 T: Clone,
76{
77 fn next_back(&mut self) -> Option<T> {
78 self.it.next_back().cloned()
79 }
80
81 fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
82 where
83 Self: Sized,
84 F: FnMut(B, Self::Item) -> R,
85 R: Try<Ok = B>,
86 {
87 self.it.try_rfold(init, clone_try_fold(f))
88 }
89
90 fn rfold<Acc, F>(self, init: Acc, f: F) -> Acc
91 where
92 F: FnMut(Acc, Self::Item) -> Acc,
93 {
94 self.it.map(T::clone).rfold(init, f)
95 }
96}
97
98#[stable(feature = "iter_cloned", since = "1.1.0")]
99impl<'a, I, T: 'a> ExactSizeIterator for Cloned<I>
100where
101 I: ExactSizeIterator<Item = &'a T>,
102 T: Clone,
103{
104 fn len(&self) -> usize {
105 self.it.len()
106 }
107
108 fn is_empty(&self) -> bool {
109 self.it.is_empty()
110 }
111}
112
113#[stable(feature = "fused", since = "1.26.0")]
114impl<'a, I, T: 'a> FusedIterator for Cloned<I>
115where
116 I: FusedIterator<Item = &'a T>,
117 T: Clone,
118{
119}
120
121#[doc(hidden)]
122#[unstable(feature = "trusted_random_access", issue = "none")]
123unsafe impl<I> TrustedRandomAccess for Cloned<I>
124where
125 I: TrustedRandomAccess,
126{
6a06907d 127 const MAY_HAVE_SIDE_EFFECT: bool = true;
fc512014
XL
128}
129
130#[unstable(feature = "trusted_len", issue = "37572")]
131unsafe impl<'a, I, T: 'a> TrustedLen for Cloned<I>
132where
133 I: TrustedLen<Item = &'a T>,
134 T: Clone,
135{
136}