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}