1 use super::plumbing::*;
2 use super::*;
3 use std::iter;
4 use std::usize;
5 
6 /// Iterator adaptor for [the `repeat()` function](fn.repeat.html).
7 #[derive(Debug, Clone)]
8 pub 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 /// ```
repeat<T: Clone + Send>(elt: T) -> Repeat<T>26 pub fn repeat<T: Clone + Send>(elt: T) -> Repeat<T> {
27     Repeat { element: elt }
28 }
29 
30 impl<T> Repeat<T>
31 where
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.
take(self, n: usize) -> RepeatN<T>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).
zip<Z>(self, zip_op: Z) -> Zip<RepeatN<T>, Z::Iter> where Z: IntoParallelIterator, Z::Iter: IndexedParallelIterator,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 
57 impl<T> ParallelIterator for Repeat<T>
58 where
59     T: Clone + Send,
60 {
61     type Item = T;
62 
drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,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`.
75 struct RepeatProducer<T: Clone + Send> {
76     element: T,
77 }
78 
79 impl<T: Clone + Send> UnindexedProducer for RepeatProducer<T> {
80     type Item = T;
81 
split(self) -> (Self, Option<Self>)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 
fold_with<F>(self, folder: F) -> F where F: Folder<T>,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)]
103 pub 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 /// ```
repeatn<T: Clone + Send>(elt: T, n: usize) -> RepeatN<T>119 pub fn repeatn<T: Clone + Send>(elt: T, n: usize) -> RepeatN<T> {
120     RepeatN {
121         element: elt,
122         count: n,
123     }
124 }
125 
126 impl<T> ParallelIterator for RepeatN<T>
127 where
128     T: Clone + Send,
129 {
130     type Item = T;
131 
drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,132     fn drive_unindexed<C>(self, consumer: C) -> C::Result
133     where
134         C: UnindexedConsumer<Self::Item>,
135     {
136         bridge(self, consumer)
137     }
138 
opt_len(&self) -> Option<usize>139     fn opt_len(&self) -> Option<usize> {
140         Some(self.count)
141     }
142 }
143 
144 impl<T> IndexedParallelIterator for RepeatN<T>
145 where
146     T: Clone + Send,
147 {
drive<C>(self, consumer: C) -> C::Result where C: Consumer<Self::Item>,148     fn drive<C>(self, consumer: C) -> C::Result
149     where
150         C: Consumer<Self::Item>,
151     {
152         bridge(self, consumer)
153     }
154 
with_producer<CB>(self, callback: CB) -> CB::Output where CB: ProducerCallback<Self::Item>,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 
len(&self) -> usize165     fn len(&self) -> usize {
166         self.count
167     }
168 }
169 
170 /// Producer for `RepeatN`.
171 struct RepeatNProducer<T: Clone + Send> {
172     element: T,
173     count: usize,
174 }
175 
176 impl<T: Clone + Send> Producer for RepeatNProducer<T> {
177     type Item = T;
178     type IntoIter = Iter<T>;
179 
into_iter(self) -> Self::IntoIter180     fn into_iter(self) -> Self::IntoIter {
181         Iter {
182             element: self.element,
183             count: self.count,
184         }
185     }
186 
split_at(self, index: usize) -> (Self, Self)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`.
205 struct Iter<T: Clone> {
206     element: T,
207     count: usize,
208 }
209 
210 impl<T: Clone> Iterator for Iter<T> {
211     type Item = T;
212 
213     #[inline]
next(&mut self) -> Option<T>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]
size_hint(&self) -> (usize, Option<usize>)224     fn size_hint(&self) -> (usize, Option<usize>) {
225         (self.count, Some(self.count))
226     }
227 }
228 
229 impl<T: Clone> DoubleEndedIterator for Iter<T> {
230     #[inline]
next_back(&mut self) -> Option<T>231     fn next_back(&mut self) -> Option<T> {
232         self.next()
233     }
234 }
235 
236 impl<T: Clone> ExactSizeIterator for Iter<T> {
237     #[inline]
len(&self) -> usize238     fn len(&self) -> usize {
239         self.count
240     }
241 }
242