]>
Commit | Line | Data |
---|---|---|
e74abb32 XL |
1 | use super::plumbing::*; |
2 | use super::*; | |
3 | ||
4 | use std::iter; | |
5 | ||
6 | /// `Copied` is an iterator that copies the elements of an underlying iterator. | |
7 | /// | |
8 | /// This struct is created by the [`copied()`] method on [`ParallelIterator`] | |
9 | /// | |
10 | /// [`copied()`]: trait.ParallelIterator.html#method.copied | |
11 | /// [`ParallelIterator`]: trait.ParallelIterator.html | |
12 | #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] | |
13 | #[derive(Debug, Clone)] | |
14 | pub struct Copied<I: ParallelIterator> { | |
15 | base: I, | |
16 | } | |
17 | ||
18 | impl<I> Copied<I> | |
19 | where | |
20 | I: ParallelIterator, | |
21 | { | |
923072b8 | 22 | /// Creates a new `Copied` iterator. |
e74abb32 XL |
23 | pub(super) fn new(base: I) -> Self { |
24 | Copied { base } | |
25 | } | |
26 | } | |
27 | ||
28 | impl<'a, T, I> ParallelIterator for Copied<I> | |
29 | where | |
30 | I: ParallelIterator<Item = &'a T>, | |
31 | T: 'a + Copy + Send + Sync, | |
32 | { | |
33 | type Item = T; | |
34 | ||
35 | fn drive_unindexed<C>(self, consumer: C) -> C::Result | |
36 | where | |
37 | C: UnindexedConsumer<Self::Item>, | |
38 | { | |
39 | let consumer1 = CopiedConsumer::new(consumer); | |
40 | self.base.drive_unindexed(consumer1) | |
41 | } | |
42 | ||
43 | fn opt_len(&self) -> Option<usize> { | |
44 | self.base.opt_len() | |
45 | } | |
46 | } | |
47 | ||
48 | impl<'a, T, I> IndexedParallelIterator for Copied<I> | |
49 | where | |
50 | I: IndexedParallelIterator<Item = &'a T>, | |
51 | T: 'a + Copy + Send + Sync, | |
52 | { | |
53 | fn drive<C>(self, consumer: C) -> C::Result | |
54 | where | |
55 | C: Consumer<Self::Item>, | |
56 | { | |
57 | let consumer1 = CopiedConsumer::new(consumer); | |
58 | self.base.drive(consumer1) | |
59 | } | |
60 | ||
61 | fn len(&self) -> usize { | |
62 | self.base.len() | |
63 | } | |
64 | ||
65 | fn with_producer<CB>(self, callback: CB) -> CB::Output | |
66 | where | |
67 | CB: ProducerCallback<Self::Item>, | |
68 | { | |
69 | return self.base.with_producer(Callback { callback }); | |
70 | ||
71 | struct Callback<CB> { | |
72 | callback: CB, | |
73 | } | |
74 | ||
75 | impl<'a, T, CB> ProducerCallback<&'a T> for Callback<CB> | |
76 | where | |
77 | CB: ProducerCallback<T>, | |
78 | T: 'a + Copy + Send, | |
79 | { | |
80 | type Output = CB::Output; | |
81 | ||
82 | fn callback<P>(self, base: P) -> CB::Output | |
83 | where | |
84 | P: Producer<Item = &'a T>, | |
85 | { | |
86 | let producer = CopiedProducer { base }; | |
87 | self.callback.callback(producer) | |
88 | } | |
89 | } | |
90 | } | |
91 | } | |
92 | ||
93 | /// //////////////////////////////////////////////////////////////////////// | |
94 | ||
95 | struct CopiedProducer<P> { | |
96 | base: P, | |
97 | } | |
98 | ||
99 | impl<'a, T, P> Producer for CopiedProducer<P> | |
100 | where | |
101 | P: Producer<Item = &'a T>, | |
102 | T: 'a + Copy, | |
103 | { | |
104 | type Item = T; | |
923072b8 | 105 | type IntoIter = iter::Copied<P::IntoIter>; |
e74abb32 XL |
106 | |
107 | fn into_iter(self) -> Self::IntoIter { | |
923072b8 | 108 | self.base.into_iter().copied() |
e74abb32 XL |
109 | } |
110 | ||
111 | fn min_len(&self) -> usize { | |
112 | self.base.min_len() | |
113 | } | |
114 | ||
115 | fn max_len(&self) -> usize { | |
116 | self.base.max_len() | |
117 | } | |
118 | ||
119 | fn split_at(self, index: usize) -> (Self, Self) { | |
120 | let (left, right) = self.base.split_at(index); | |
121 | ( | |
122 | CopiedProducer { base: left }, | |
123 | CopiedProducer { base: right }, | |
124 | ) | |
125 | } | |
126 | ||
127 | fn fold_with<F>(self, folder: F) -> F | |
128 | where | |
129 | F: Folder<Self::Item>, | |
130 | { | |
131 | self.base.fold_with(CopiedFolder { base: folder }).base | |
132 | } | |
133 | } | |
134 | ||
135 | /// //////////////////////////////////////////////////////////////////////// | |
136 | /// Consumer implementation | |
137 | ||
138 | struct CopiedConsumer<C> { | |
139 | base: C, | |
140 | } | |
141 | ||
142 | impl<C> CopiedConsumer<C> { | |
143 | fn new(base: C) -> Self { | |
144 | CopiedConsumer { base } | |
145 | } | |
146 | } | |
147 | ||
148 | impl<'a, T, C> Consumer<&'a T> for CopiedConsumer<C> | |
149 | where | |
150 | C: Consumer<T>, | |
151 | T: 'a + Copy, | |
152 | { | |
153 | type Folder = CopiedFolder<C::Folder>; | |
154 | type Reducer = C::Reducer; | |
155 | type Result = C::Result; | |
156 | ||
157 | fn split_at(self, index: usize) -> (Self, Self, Self::Reducer) { | |
158 | let (left, right, reducer) = self.base.split_at(index); | |
159 | ( | |
160 | CopiedConsumer::new(left), | |
161 | CopiedConsumer::new(right), | |
162 | reducer, | |
163 | ) | |
164 | } | |
165 | ||
166 | fn into_folder(self) -> Self::Folder { | |
167 | CopiedFolder { | |
168 | base: self.base.into_folder(), | |
169 | } | |
170 | } | |
171 | ||
172 | fn full(&self) -> bool { | |
173 | self.base.full() | |
174 | } | |
175 | } | |
176 | ||
177 | impl<'a, T, C> UnindexedConsumer<&'a T> for CopiedConsumer<C> | |
178 | where | |
179 | C: UnindexedConsumer<T>, | |
180 | T: 'a + Copy, | |
181 | { | |
182 | fn split_off_left(&self) -> Self { | |
183 | CopiedConsumer::new(self.base.split_off_left()) | |
184 | } | |
185 | ||
186 | fn to_reducer(&self) -> Self::Reducer { | |
187 | self.base.to_reducer() | |
188 | } | |
189 | } | |
190 | ||
191 | struct CopiedFolder<F> { | |
192 | base: F, | |
193 | } | |
194 | ||
195 | impl<'a, T, F> Folder<&'a T> for CopiedFolder<F> | |
196 | where | |
197 | F: Folder<T>, | |
198 | T: 'a + Copy, | |
199 | { | |
200 | type Result = F::Result; | |
201 | ||
202 | fn consume(self, &item: &'a T) -> Self { | |
203 | CopiedFolder { | |
204 | base: self.base.consume(item), | |
205 | } | |
206 | } | |
207 | ||
208 | fn consume_iter<I>(mut self, iter: I) -> Self | |
209 | where | |
210 | I: IntoIterator<Item = &'a T>, | |
211 | { | |
923072b8 | 212 | self.base = self.base.consume_iter(iter.into_iter().copied()); |
e74abb32 XL |
213 | self |
214 | } | |
215 | ||
216 | fn complete(self) -> F::Result { | |
217 | self.base.complete() | |
218 | } | |
219 | ||
220 | fn full(&self) -> bool { | |
221 | self.base.full() | |
222 | } | |
223 | } |