Coverage Report

Created: 2025-02-25 06:39

/rust/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.10.0/src/iter/repeat.rs
Line
Count
Source (jump to first uncovered line)
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
0
pub fn repeat<T: Clone + Send>(elt: T) -> Repeat<T> {
27
0
    Repeat { element: elt }
28
0
}
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
0
    pub fn take(self, n: usize) -> RepeatN<T> {
40
0
        repeatn(self.element, n)
41
0
    }
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
0
    pub fn zip<Z>(self, zip_op: Z) -> Zip<RepeatN<T>, Z::Iter>
47
0
    where
48
0
        Z: IntoParallelIterator,
49
0
        Z::Iter: IndexedParallelIterator,
50
0
    {
51
0
        let z = zip_op.into_par_iter();
52
0
        let n = z.len();
53
0
        self.take(n).zip(z)
54
0
    }
55
}
56
57
impl<T> ParallelIterator for Repeat<T>
58
where
59
    T: Clone + Send,
60
{
61
    type Item = T;
62
63
0
    fn drive_unindexed<C>(self, consumer: C) -> C::Result
64
0
    where
65
0
        C: UnindexedConsumer<Self::Item>,
66
0
    {
67
0
        let producer = RepeatProducer {
68
0
            element: self.element,
69
0
        };
70
0
        bridge_unindexed(producer, consumer)
71
0
    }
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
0
    fn split(self) -> (Self, Option<Self>) {
83
0
        (
84
0
            RepeatProducer {
85
0
                element: self.element.clone(),
86
0
            },
87
0
            Some(RepeatProducer {
88
0
                element: self.element,
89
0
            }),
90
0
        )
91
0
    }
92
93
0
    fn fold_with<F>(self, folder: F) -> F
94
0
    where
95
0
        F: Folder<T>,
96
0
    {
97
0
        folder.consume_iter(iter::repeat(self.element))
98
0
    }
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
0
pub fn repeatn<T: Clone + Send>(elt: T, n: usize) -> RepeatN<T> {
120
0
    RepeatN {
121
0
        element: elt,
122
0
        count: n,
123
0
    }
124
0
}
125
126
impl<T> ParallelIterator for RepeatN<T>
127
where
128
    T: Clone + Send,
129
{
130
    type Item = T;
131
132
0
    fn drive_unindexed<C>(self, consumer: C) -> C::Result
133
0
    where
134
0
        C: UnindexedConsumer<Self::Item>,
135
0
    {
136
0
        bridge(self, consumer)
137
0
    }
138
139
0
    fn opt_len(&self) -> Option<usize> {
140
0
        Some(self.count)
141
0
    }
142
}
143
144
impl<T> IndexedParallelIterator for RepeatN<T>
145
where
146
    T: Clone + Send,
147
{
148
0
    fn drive<C>(self, consumer: C) -> C::Result
149
0
    where
150
0
        C: Consumer<Self::Item>,
151
0
    {
152
0
        bridge(self, consumer)
153
0
    }
154
155
0
    fn with_producer<CB>(self, callback: CB) -> CB::Output
156
0
    where
157
0
        CB: ProducerCallback<Self::Item>,
158
0
    {
159
0
        callback.callback(RepeatNProducer {
160
0
            element: self.element,
161
0
            count: self.count,
162
0
        })
163
0
    }
164
165
0
    fn len(&self) -> usize {
166
0
        self.count
167
0
    }
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
0
    fn into_iter(self) -> Self::IntoIter {
181
0
        Iter {
182
0
            element: self.element,
183
0
            count: self.count,
184
0
        }
185
0
    }
186
187
0
    fn split_at(self, index: usize) -> (Self, Self) {
188
0
        (
189
0
            RepeatNProducer {
190
0
                element: self.element.clone(),
191
0
                count: index,
192
0
            },
193
0
            RepeatNProducer {
194
0
                element: self.element,
195
0
                count: self.count - index,
196
0
            },
197
0
        )
198
0
    }
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
0
    fn next(&mut self) -> Option<T> {
215
0
        if self.count > 0 {
216
0
            self.count -= 1;
217
0
            Some(self.element.clone())
218
        } else {
219
0
            None
220
        }
221
0
    }
222
223
    #[inline]
224
0
    fn size_hint(&self) -> (usize, Option<usize>) {
225
0
        (self.count, Some(self.count))
226
0
    }
227
}
228
229
impl<T: Clone> DoubleEndedIterator for Iter<T> {
230
    #[inline]
231
0
    fn next_back(&mut self) -> Option<T> {
232
0
        self.next()
233
0
    }
234
}
235
236
impl<T: Clone> ExactSizeIterator for Iter<T> {
237
    #[inline]
238
0
    fn len(&self) -> usize {
239
0
        self.count
240
0
    }
241
}