]>
Commit | Line | Data |
---|---|---|
fc512014 XL |
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 | { | |
6a06907d | 143 | const MAY_HAVE_SIDE_EFFECT: bool = I::MAY_HAVE_SIDE_EFFECT; |
fc512014 XL |
144 | } |
145 | ||
146 | #[stable(feature = "iter_copied", since = "1.36.0")] | |
147 | unsafe impl<'a, I, T: 'a> TrustedLen for Copied<I> | |
148 | where | |
149 | I: TrustedLen<Item = &'a T>, | |
150 | T: Copy, | |
151 | { | |
152 | } |