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}
242