]>
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, | |
17df50a5 | 53 | R: Try<Output = B>, |
fc512014 XL |
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 | ||
136023e0 | 77 | #[doc(hidden)] |
fc512014 XL |
78 | unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T |
79 | where | |
80 | Self: TrustedRandomAccess, | |
81 | { | |
82 | // SAFETY: the caller must uphold the contract for | |
83 | // `Iterator::__iterator_get_unchecked`. | |
84 | *unsafe { try_get_unchecked(&mut self.it, idx) } | |
85 | } | |
86 | } | |
87 | ||
88 | #[stable(feature = "iter_copied", since = "1.36.0")] | |
89 | impl<'a, I, T: 'a> DoubleEndedIterator for Copied<I> | |
90 | where | |
91 | I: DoubleEndedIterator<Item = &'a T>, | |
92 | T: Copy, | |
93 | { | |
94 | fn next_back(&mut self) -> Option<T> { | |
95 | self.it.next_back().copied() | |
96 | } | |
97 | ||
98 | fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R | |
99 | where | |
100 | Self: Sized, | |
101 | F: FnMut(B, Self::Item) -> R, | |
17df50a5 | 102 | R: Try<Output = B>, |
fc512014 XL |
103 | { |
104 | self.it.try_rfold(init, copy_try_fold(f)) | |
105 | } | |
106 | ||
107 | fn rfold<Acc, F>(self, init: Acc, f: F) -> Acc | |
108 | where | |
109 | F: FnMut(Acc, Self::Item) -> Acc, | |
110 | { | |
111 | self.it.rfold(init, copy_fold(f)) | |
112 | } | |
113 | } | |
114 | ||
115 | #[stable(feature = "iter_copied", since = "1.36.0")] | |
116 | impl<'a, I, T: 'a> ExactSizeIterator for Copied<I> | |
117 | where | |
118 | I: ExactSizeIterator<Item = &'a T>, | |
119 | T: Copy, | |
120 | { | |
121 | fn len(&self) -> usize { | |
122 | self.it.len() | |
123 | } | |
124 | ||
125 | fn is_empty(&self) -> bool { | |
126 | self.it.is_empty() | |
127 | } | |
128 | } | |
129 | ||
130 | #[stable(feature = "iter_copied", since = "1.36.0")] | |
131 | impl<'a, I, T: 'a> FusedIterator for Copied<I> | |
132 | where | |
133 | I: FusedIterator<Item = &'a T>, | |
134 | T: Copy, | |
135 | { | |
136 | } | |
137 | ||
138 | #[doc(hidden)] | |
139 | #[unstable(feature = "trusted_random_access", issue = "none")] | |
140 | unsafe impl<I> TrustedRandomAccess for Copied<I> | |
141 | where | |
142 | I: TrustedRandomAccess, | |
143 | { | |
6a06907d | 144 | const MAY_HAVE_SIDE_EFFECT: bool = I::MAY_HAVE_SIDE_EFFECT; |
fc512014 XL |
145 | } |
146 | ||
147 | #[stable(feature = "iter_copied", since = "1.36.0")] | |
148 | unsafe impl<'a, I, T: 'a> TrustedLen for Copied<I> | |
149 | where | |
150 | I: TrustedLen<Item = &'a T>, | |
151 | T: Copy, | |
152 | { | |
153 | } |