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