1use super::plumbing::*;
2use super::*;
3use std::num::NonZeroUsize;
4use std::{fmt, iter, mem};
5
6#[derive(Debug, Clone)]
10pub struct Repeat<T> {
11 element: T,
12}
13
14pub fn repeat<T: Clone + Send>(element: T) -> Repeat<T> {
31 Repeat { element }
32}
33
34impl<T> Repeat<T>
35where
36 T: Clone + Send,
37{
38 pub fn take(self, n: usize) -> RepeatN<T> {
46 repeat_n(self.element, n)
47 }
48
49 pub fn zip<Z>(self, zip_op: Z) -> Zip<RepeatN<T>, Z::Iter>
54 where
55 Z: IntoParallelIterator<Iter: IndexedParallelIterator>,
56 {
57 let z = zip_op.into_par_iter();
58 let n = z.len();
59 self.take(n).zip(z)
60 }
61}
62
63impl<T> ParallelIterator for Repeat<T>
64where
65 T: Clone + Send,
66{
67 type Item = T;
68
69 fn drive_unindexed<C>(self, consumer: C) -> C::Result
70 where
71 C: UnindexedConsumer<Self::Item>,
72 {
73 let producer = RepeatProducer {
74 element: self.element,
75 };
76 bridge_unindexed(producer, consumer)
77 }
78}
79
80struct RepeatProducer<T: Clone + Send> {
82 element: T,
83}
84
85impl<T: Clone + Send> UnindexedProducer for RepeatProducer<T> {
86 type Item = T;
87
88 fn split(self) -> (Self, Option<Self>) {
89 (
90 RepeatProducer {
91 element: self.element.clone(),
92 },
93 Some(RepeatProducer {
94 element: self.element,
95 }),
96 )
97 }
98
99 fn fold_with<F>(self, folder: F) -> F
100 where
101 F: Folder<T>,
102 {
103 folder.consume_iter(iter::repeat(self.element))
104 }
105}
106
107#[derive(Clone)]
111pub struct RepeatN<T> {
112 inner: RepeatNProducer<T>,
113}
114
115pub fn repeat_n<T: Clone + Send>(element: T, n: usize) -> RepeatN<T> {
127 let inner = match NonZeroUsize::new(n) {
128 Some(count) => RepeatNProducer::Repeats(element, count),
129 None => RepeatNProducer::Empty,
130 };
131 RepeatN { inner }
132}
133
134#[deprecated(note = "use `repeat_n`")]
139pub fn repeatn<T: Clone + Send>(element: T, n: usize) -> RepeatN<T> {
140 repeat_n(element, n)
141}
142
143impl<T: fmt::Debug> fmt::Debug for RepeatN<T> {
144 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
145 let mut dbg = f.debug_struct("RepeatN");
146 if let RepeatNProducer::Repeats(element, count) = &self.inner {
147 dbg.field("count", &count.get())
148 .field("element", element)
149 .finish()
150 } else {
151 dbg.field("count", &0usize).finish_non_exhaustive()
152 }
153 }
154}
155
156impl<T> ParallelIterator for RepeatN<T>
157where
158 T: Clone + Send,
159{
160 type Item = T;
161
162 fn drive_unindexed<C>(self, consumer: C) -> C::Result
163 where
164 C: UnindexedConsumer<Self::Item>,
165 {
166 bridge(self, consumer)
167 }
168
169 fn opt_len(&self) -> Option<usize> {
170 Some(self.inner.len())
171 }
172}
173
174impl<T> IndexedParallelIterator for RepeatN<T>
175where
176 T: Clone + Send,
177{
178 fn drive<C>(self, consumer: C) -> C::Result
179 where
180 C: Consumer<Self::Item>,
181 {
182 bridge(self, consumer)
183 }
184
185 fn with_producer<CB>(self, callback: CB) -> CB::Output
186 where
187 CB: ProducerCallback<Self::Item>,
188 {
189 callback.callback(self.inner)
190 }
191
192 fn len(&self) -> usize {
193 self.inner.len()
194 }
195}
196
197#[derive(Clone)]
199enum RepeatNProducer<T> {
200 Repeats(T, NonZeroUsize),
201 Empty,
202}
203
204impl<T: Clone + Send> Producer for RepeatNProducer<T> {
205 type Item = T;
206 type IntoIter = Self;
207
208 fn into_iter(self) -> Self::IntoIter {
209 self
212 }
213
214 fn split_at(self, index: usize) -> (Self, Self) {
215 if let Self::Repeats(element, count) = self {
216 assert!(index <= count.get());
217 match (
218 NonZeroUsize::new(index),
219 NonZeroUsize::new(count.get() - index),
220 ) {
221 (Some(left), Some(right)) => (
222 Self::Repeats(element.clone(), left),
223 Self::Repeats(element, right),
224 ),
225 (Some(left), None) => (Self::Repeats(element, left), Self::Empty),
226 (None, Some(right)) => (Self::Empty, Self::Repeats(element, right)),
227 (None, None) => unreachable!(),
228 }
229 } else {
230 assert!(index == 0);
231 (Self::Empty, Self::Empty)
232 }
233 }
234}
235
236impl<T: Clone> Iterator for RepeatNProducer<T> {
237 type Item = T;
238
239 #[inline]
240 fn next(&mut self) -> Option<T> {
241 if let Self::Repeats(element, count) = self {
242 if let Some(rem) = NonZeroUsize::new(count.get() - 1) {
243 *count = rem;
244 Some(element.clone())
245 } else {
246 match mem::replace(self, Self::Empty) {
247 Self::Repeats(element, _) => Some(element),
248 Self::Empty => unreachable!(),
249 }
250 }
251 } else {
252 None
253 }
254 }
255
256 #[inline]
257 fn nth(&mut self, n: usize) -> Option<T> {
258 if let Self::Repeats(_, count) = self {
259 if let Some(rem) = NonZeroUsize::new(count.get().saturating_sub(n)) {
260 *count = rem;
261 return self.next();
262 }
263 *self = Self::Empty;
264 }
265 None
266 }
267
268 #[inline]
269 fn size_hint(&self) -> (usize, Option<usize>) {
270 let len = self.len();
271 (len, Some(len))
272 }
273}
274
275impl<T: Clone> DoubleEndedIterator for RepeatNProducer<T> {
276 #[inline]
277 fn next_back(&mut self) -> Option<T> {
278 self.next()
279 }
280
281 #[inline]
282 fn nth_back(&mut self, n: usize) -> Option<T> {
283 self.nth(n)
284 }
285}
286
287impl<T: Clone> ExactSizeIterator for RepeatNProducer<T> {
288 #[inline]
289 fn len(&self) -> usize {
290 match self {
291 Self::Repeats(_, count) => count.get(),
292 Self::Empty => 0,
293 }
294 }
295}