rayon/iter/
repeat.rs

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