par_iter/iter/
repeat.rs

1use std::iter;
2
3use super::{plumbing::*, *};
4
5/// Iterator adaptor for [the `repeat()` function](fn.repeat.html).
6#[derive(Debug, Clone)]
7pub struct Repeat<T: Clone + Send> {
8    element: T,
9}
10
11/// Creates a parallel iterator that endlessly repeats `elt` (by
12/// cloning it). Note that this iterator has "infinite" length, so
13/// typically you would want to use `zip` or `take` or some other
14/// means to shorten it, or consider using
15/// [the `repeatn()` function](fn.repeatn.html) instead.
16///
17/// # Examples
18///
19/// ```
20/// use par_iter::prelude::*;
21/// use par_iter::iter::repeat;
22/// let x: Vec<(i32, i32)> = repeat(22).zip(0..3).collect();
23/// assert_eq!(x, vec![(22, 0), (22, 1), (22, 2)]);
24/// ```
25pub 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    /// Takes only `n` repeats of the element, similar to the general
34    /// [`take()`](trait.IndexedParallelIterator.html#method.take).
35    ///
36    /// The resulting `RepeatN` is an `IndexedParallelIterator`, allowing
37    /// more functionality than `Repeat` alone.
38    pub fn take(self, n: usize) -> RepeatN<T> {
39        repeatn(self.element, n)
40    }
41
42    /// Iterates tuples, repeating the element with items from another
43    /// iterator, similar to the general
44    /// [`zip()`](trait.IndexedParallelIterator.html#method.zip).
45    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
73/// Unindexed producer for `Repeat`.
74struct 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/// Iterator adaptor for [the `repeatn()` function](fn.repeatn.html).
101#[derive(Debug, Clone)]
102pub struct RepeatN<T: Clone + Send> {
103    element: T,
104    count: usize,
105}
106
107/// Creates a parallel iterator that produces `n` repeats of `elt`
108/// (by cloning it).
109///
110/// # Examples
111///
112/// ```
113/// use par_iter::prelude::*;
114/// use par_iter::iter::repeatn;
115/// let x: Vec<(i32, i32)> = repeatn(22, 3).zip(0..3).collect();
116/// assert_eq!(x, vec![(22, 0), (22, 1), (22, 2)]);
117/// ```
118pub 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
169/// Producer for `RepeatN`.
170struct 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
200/// Iterator for `RepeatN`.
201///
202/// This is conceptually like `std::iter::Take<std::iter::Repeat<T>>`, but
203/// we need `DoubleEndedIterator` and unconditional `ExactSizeIterator`.
204struct 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}