1use super::plumbing::*;
2use super::*;
3use std::iter;
4use std::usize;
5
6#[derive(Debug, Clone)]
8pub struct Repeat<T: Clone + Send> {
9 element: T,
10}
11
12pub fn repeat<T: Clone + Send>(elt: T) -> Repeat<T> {
27 Repeat { element: elt }
28}
29
30impl<T> Repeat<T>
31where
32 T: Clone + Send,
33{
34 pub fn take(self, n: usize) -> RepeatN<T> {
40 repeatn(self.element, n)
41 }
42
43 pub fn zip<Z>(self, zip_op: Z) -> Zip<RepeatN<T>, Z::Iter>
47 where
48 Z: IntoParallelIterator,
49 Z::Iter: IndexedParallelIterator,
50 {
51 let z = zip_op.into_par_iter();
52 let n = z.len();
53 self.take(n).zip(z)
54 }
55}
56
57impl<T> ParallelIterator for Repeat<T>
58where
59 T: Clone + Send,
60{
61 type Item = T;
62
63 fn drive_unindexed<C>(self, consumer: C) -> C::Result
64 where
65 C: UnindexedConsumer<Self::Item>,
66 {
67 let producer = RepeatProducer {
68 element: self.element,
69 };
70 bridge_unindexed(producer, consumer)
71 }
72}
73
74struct RepeatProducer<T: Clone + Send> {
76 element: T,
77}
78
79impl<T: Clone + Send> UnindexedProducer for RepeatProducer<T> {
80 type Item = T;
81
82 fn split(self) -> (Self, Option<Self>) {
83 (
84 RepeatProducer {
85 element: self.element.clone(),
86 },
87 Some(RepeatProducer {
88 element: self.element,
89 }),
90 )
91 }
92
93 fn fold_with<F>(self, folder: F) -> F
94 where
95 F: Folder<T>,
96 {
97 folder.consume_iter(iter::repeat(self.element))
98 }
99}
100
101#[derive(Debug, Clone)]
103pub struct RepeatN<T: Clone + Send> {
104 element: T,
105 count: usize,
106}
107
108pub fn repeatn<T: Clone + Send>(elt: T, n: usize) -> RepeatN<T> {
120 RepeatN {
121 element: elt,
122 count: n,
123 }
124}
125
126impl<T> ParallelIterator for RepeatN<T>
127where
128 T: Clone + Send,
129{
130 type Item = T;
131
132 fn drive_unindexed<C>(self, consumer: C) -> C::Result
133 where
134 C: UnindexedConsumer<Self::Item>,
135 {
136 bridge(self, consumer)
137 }
138
139 fn opt_len(&self) -> Option<usize> {
140 Some(self.count)
141 }
142}
143
144impl<T> IndexedParallelIterator for RepeatN<T>
145where
146 T: Clone + Send,
147{
148 fn drive<C>(self, consumer: C) -> C::Result
149 where
150 C: Consumer<Self::Item>,
151 {
152 bridge(self, consumer)
153 }
154
155 fn with_producer<CB>(self, callback: CB) -> CB::Output
156 where
157 CB: ProducerCallback<Self::Item>,
158 {
159 callback.callback(RepeatNProducer {
160 element: self.element,
161 count: self.count,
162 })
163 }
164
165 fn len(&self) -> usize {
166 self.count
167 }
168}
169
170struct RepeatNProducer<T: Clone + Send> {
172 element: T,
173 count: usize,
174}
175
176impl<T: Clone + Send> Producer for RepeatNProducer<T> {
177 type Item = T;
178 type IntoIter = Iter<T>;
179
180 fn into_iter(self) -> Self::IntoIter {
181 Iter {
182 element: self.element,
183 count: self.count,
184 }
185 }
186
187 fn split_at(self, index: usize) -> (Self, Self) {
188 (
189 RepeatNProducer {
190 element: self.element.clone(),
191 count: index,
192 },
193 RepeatNProducer {
194 element: self.element,
195 count: self.count - index,
196 },
197 )
198 }
199}
200
201struct Iter<T: Clone> {
206 element: T,
207 count: usize,
208}
209
210impl<T: Clone> Iterator for Iter<T> {
211 type Item = T;
212
213 #[inline]
214 fn next(&mut self) -> Option<T> {
215 if self.count > 0 {
216 self.count -= 1;
217 Some(self.element.clone())
218 } else {
219 None
220 }
221 }
222
223 #[inline]
224 fn size_hint(&self) -> (usize, Option<usize>) {
225 (self.count, Some(self.count))
226 }
227}
228
229impl<T: Clone> DoubleEndedIterator for Iter<T> {
230 #[inline]
231 fn next_back(&mut self) -> Option<T> {
232 self.next()
233 }
234}
235
236impl<T: Clone> ExactSizeIterator for Iter<T> {
237 #[inline]
238 fn len(&self) -> usize {
239 self.count
240 }
241}