]> git.lizzy.rs Git - rust.git/blob - library/core/src/iter/adapters/copied.rs
Rollup merge of #79293 - Havvy:test-eval-order-compound-assign, r=Mark-Simulacrum
[rust.git] / library / core / src / iter / adapters / copied.rs
1 use crate::iter::adapters::{zip::try_get_unchecked, TrustedRandomAccess};
2 use crate::iter::{FusedIterator, TrustedLen};
3 use crate::ops::Try;
4
5 /// An iterator that copies the elements of an underlying iterator.
6 ///
7 /// This `struct` is created by the [`copied`] method on [`Iterator`]. See its
8 /// documentation for more.
9 ///
10 /// [`copied`]: Iterator::copied
11 /// [`Iterator`]: trait.Iterator.html
12 #[stable(feature = "iter_copied", since = "1.36.0")]
13 #[must_use = "iterators are lazy and do nothing unless consumed"]
14 #[derive(Clone, Debug)]
15 pub struct Copied<I> {
16     it: I,
17 }
18
19 impl<I> Copied<I> {
20     pub(in crate::iter) fn new(it: I) -> Copied<I> {
21         Copied { it }
22     }
23 }
24
25 fn copy_fold<T: Copy, Acc>(mut f: impl FnMut(Acc, T) -> Acc) -> impl FnMut(Acc, &T) -> Acc {
26     move |acc, &elt| f(acc, elt)
27 }
28
29 fn copy_try_fold<T: Copy, Acc, R>(mut f: impl FnMut(Acc, T) -> R) -> impl FnMut(Acc, &T) -> R {
30     move |acc, &elt| f(acc, elt)
31 }
32
33 #[stable(feature = "iter_copied", since = "1.36.0")]
34 impl<'a, I, T: 'a> Iterator for Copied<I>
35 where
36     I: Iterator<Item = &'a T>,
37     T: Copy,
38 {
39     type Item = T;
40
41     fn next(&mut self) -> Option<T> {
42         self.it.next().copied()
43     }
44
45     fn size_hint(&self) -> (usize, Option<usize>) {
46         self.it.size_hint()
47     }
48
49     fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
50     where
51         Self: Sized,
52         F: FnMut(B, Self::Item) -> R,
53         R: Try<Ok = B>,
54     {
55         self.it.try_fold(init, copy_try_fold(f))
56     }
57
58     fn fold<Acc, F>(self, init: Acc, f: F) -> Acc
59     where
60         F: FnMut(Acc, Self::Item) -> Acc,
61     {
62         self.it.fold(init, copy_fold(f))
63     }
64
65     fn nth(&mut self, n: usize) -> Option<T> {
66         self.it.nth(n).copied()
67     }
68
69     fn last(self) -> Option<T> {
70         self.it.last().copied()
71     }
72
73     fn count(self) -> usize {
74         self.it.count()
75     }
76
77     unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
78     where
79         Self: TrustedRandomAccess,
80     {
81         // SAFETY: the caller must uphold the contract for
82         // `Iterator::__iterator_get_unchecked`.
83         *unsafe { try_get_unchecked(&mut self.it, idx) }
84     }
85 }
86
87 #[stable(feature = "iter_copied", since = "1.36.0")]
88 impl<'a, I, T: 'a> DoubleEndedIterator for Copied<I>
89 where
90     I: DoubleEndedIterator<Item = &'a T>,
91     T: Copy,
92 {
93     fn next_back(&mut self) -> Option<T> {
94         self.it.next_back().copied()
95     }
96
97     fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
98     where
99         Self: Sized,
100         F: FnMut(B, Self::Item) -> R,
101         R: Try<Ok = B>,
102     {
103         self.it.try_rfold(init, copy_try_fold(f))
104     }
105
106     fn rfold<Acc, F>(self, init: Acc, f: F) -> Acc
107     where
108         F: FnMut(Acc, Self::Item) -> Acc,
109     {
110         self.it.rfold(init, copy_fold(f))
111     }
112 }
113
114 #[stable(feature = "iter_copied", since = "1.36.0")]
115 impl<'a, I, T: 'a> ExactSizeIterator for Copied<I>
116 where
117     I: ExactSizeIterator<Item = &'a T>,
118     T: Copy,
119 {
120     fn len(&self) -> usize {
121         self.it.len()
122     }
123
124     fn is_empty(&self) -> bool {
125         self.it.is_empty()
126     }
127 }
128
129 #[stable(feature = "iter_copied", since = "1.36.0")]
130 impl<'a, I, T: 'a> FusedIterator for Copied<I>
131 where
132     I: FusedIterator<Item = &'a T>,
133     T: Copy,
134 {
135 }
136
137 #[doc(hidden)]
138 #[unstable(feature = "trusted_random_access", issue = "none")]
139 unsafe impl<I> TrustedRandomAccess for Copied<I>
140 where
141     I: TrustedRandomAccess,
142 {
143     #[inline]
144     fn may_have_side_effect() -> bool {
145         I::may_have_side_effect()
146     }
147 }
148
149 #[stable(feature = "iter_copied", since = "1.36.0")]
150 unsafe impl<'a, I, T: 'a> TrustedLen for Copied<I>
151 where
152     I: TrustedLen<Item = &'a T>,
153     T: Copy,
154 {
155 }