]> git.proxmox.com Git - rustc.git/blob - vendor/rustc-rayon/src/iter/repeat.rs
New upstream version 1.63.0+dfsg1
[rustc.git] / vendor / rustc-rayon / src / iter / repeat.rs
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 /// ```
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.
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
57 impl<T> ParallelIterator for Repeat<T>
58 where
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`.
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
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)]
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 /// ```
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
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
144 impl<T> IndexedParallelIterator for RepeatN<T>
145 where
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`.
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
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`.
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]
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
229 impl<T: Clone> DoubleEndedIterator for Iter<T> {
230 #[inline]
231 fn next_back(&mut self) -> Option<T> {
232 self.next()
233 }
234 }
235
236 impl<T: Clone> ExactSizeIterator for Iter<T> {
237 #[inline]
238 fn len(&self) -> usize {
239 self.count
240 }
241 }