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