Coverage Report

Created: 2025-11-24 07:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rayon-1.11.0/src/iter/repeat.rs
Line
Count
Source
1
use super::plumbing::*;
2
use super::*;
3
use std::num::NonZeroUsize;
4
use std::{fmt, iter, mem};
5
6
/// Iterator adaptor for [the `repeat()` function].
7
///
8
/// [the `repeat()` function]: repeat()
9
#[derive(Debug, Clone)]
10
pub struct Repeat<T> {
11
    element: T,
12
}
13
14
/// Creates a parallel iterator that endlessly repeats `element` (by
15
/// cloning it). Note that this iterator has "infinite" length, so
16
/// typically you would want to use `zip` or `take` or some other
17
/// means to shorten it, or consider using
18
/// [the `repeat_n()` function] instead.
19
///
20
/// [the `repeat_n()` function]: repeat_n()
21
///
22
/// # Examples
23
///
24
/// ```
25
/// use rayon::prelude::*;
26
/// use rayon::iter::repeat;
27
/// let x: Vec<(i32, i32)> = repeat(22).zip(0..3).collect();
28
/// assert_eq!(x, vec![(22, 0), (22, 1), (22, 2)]);
29
/// ```
30
0
pub fn repeat<T: Clone + Send>(element: T) -> Repeat<T> {
31
0
    Repeat { element }
32
0
}
33
34
impl<T> Repeat<T>
35
where
36
    T: Clone + Send,
37
{
38
    /// Takes only `n` repeats of the element, similar to the general
39
    /// [`take()`].
40
    ///
41
    /// The resulting `RepeatN` is an `IndexedParallelIterator`, allowing
42
    /// more functionality than `Repeat` alone.
43
    ///
44
    /// [`take()`]: IndexedParallelIterator::take()
45
0
    pub fn take(self, n: usize) -> RepeatN<T> {
46
0
        repeat_n(self.element, n)
47
0
    }
48
49
    /// Iterates tuples, repeating the element with items from another
50
    /// iterator, similar to the general [`zip()`].
51
    ///
52
    /// [`zip()`]: IndexedParallelIterator::zip()
53
0
    pub fn zip<Z>(self, zip_op: Z) -> Zip<RepeatN<T>, Z::Iter>
54
0
    where
55
0
        Z: IntoParallelIterator<Iter: IndexedParallelIterator>,
56
    {
57
0
        let z = zip_op.into_par_iter();
58
0
        let n = z.len();
59
0
        self.take(n).zip(z)
60
0
    }
61
}
62
63
impl<T> ParallelIterator for Repeat<T>
64
where
65
    T: Clone + Send,
66
{
67
    type Item = T;
68
69
0
    fn drive_unindexed<C>(self, consumer: C) -> C::Result
70
0
    where
71
0
        C: UnindexedConsumer<Self::Item>,
72
    {
73
0
        let producer = RepeatProducer {
74
0
            element: self.element,
75
0
        };
76
0
        bridge_unindexed(producer, consumer)
77
0
    }
78
}
79
80
/// Unindexed producer for `Repeat`.
81
struct RepeatProducer<T: Clone + Send> {
82
    element: T,
83
}
84
85
impl<T: Clone + Send> UnindexedProducer for RepeatProducer<T> {
86
    type Item = T;
87
88
0
    fn split(self) -> (Self, Option<Self>) {
89
0
        (
90
0
            RepeatProducer {
91
0
                element: self.element.clone(),
92
0
            },
93
0
            Some(RepeatProducer {
94
0
                element: self.element,
95
0
            }),
96
0
        )
97
0
    }
98
99
0
    fn fold_with<F>(self, folder: F) -> F
100
0
    where
101
0
        F: Folder<T>,
102
    {
103
0
        folder.consume_iter(iter::repeat(self.element))
104
0
    }
105
}
106
107
/// Iterator adaptor for [the `repeat_n()` function].
108
///
109
/// [the `repeat_n()` function]: repeat_n()
110
#[derive(Clone)]
111
pub struct RepeatN<T> {
112
    inner: RepeatNProducer<T>,
113
}
114
115
/// Creates a parallel iterator that produces `n` repeats of `element`
116
/// (by cloning it).
117
///
118
/// # Examples
119
///
120
/// ```
121
/// use rayon::prelude::*;
122
/// use rayon::iter::repeat_n;
123
/// let x: Vec<(i32, i32)> = repeat_n(22, 3).zip(0..3).collect();
124
/// assert_eq!(x, vec![(22, 0), (22, 1), (22, 2)]);
125
/// ```
126
0
pub fn repeat_n<T: Clone + Send>(element: T, n: usize) -> RepeatN<T> {
127
0
    let inner = match NonZeroUsize::new(n) {
128
0
        Some(count) => RepeatNProducer::Repeats(element, count),
129
0
        None => RepeatNProducer::Empty,
130
    };
131
0
    RepeatN { inner }
132
0
}
133
134
/// Creates a parallel iterator that produces `n` repeats of `element`
135
/// (by cloning it).
136
///
137
/// Deprecated in favor of [`repeat_n`] for consistency with the standard library.
138
#[deprecated(note = "use `repeat_n`")]
139
0
pub fn repeatn<T: Clone + Send>(element: T, n: usize) -> RepeatN<T> {
140
0
    repeat_n(element, n)
141
0
}
142
143
impl<T: fmt::Debug> fmt::Debug for RepeatN<T> {
144
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
145
0
        let mut dbg = f.debug_struct("RepeatN");
146
0
        if let RepeatNProducer::Repeats(element, count) = &self.inner {
147
0
            dbg.field("count", &count.get())
148
0
                .field("element", element)
149
0
                .finish()
150
        } else {
151
0
            dbg.field("count", &0usize).finish_non_exhaustive()
152
        }
153
0
    }
154
}
155
156
impl<T> ParallelIterator for RepeatN<T>
157
where
158
    T: Clone + Send,
159
{
160
    type Item = T;
161
162
0
    fn drive_unindexed<C>(self, consumer: C) -> C::Result
163
0
    where
164
0
        C: UnindexedConsumer<Self::Item>,
165
    {
166
0
        bridge(self, consumer)
167
0
    }
168
169
0
    fn opt_len(&self) -> Option<usize> {
170
0
        Some(self.inner.len())
171
0
    }
172
}
173
174
impl<T> IndexedParallelIterator for RepeatN<T>
175
where
176
    T: Clone + Send,
177
{
178
0
    fn drive<C>(self, consumer: C) -> C::Result
179
0
    where
180
0
        C: Consumer<Self::Item>,
181
    {
182
0
        bridge(self, consumer)
183
0
    }
184
185
0
    fn with_producer<CB>(self, callback: CB) -> CB::Output
186
0
    where
187
0
        CB: ProducerCallback<Self::Item>,
188
    {
189
0
        callback.callback(self.inner)
190
0
    }
191
192
0
    fn len(&self) -> usize {
193
0
        self.inner.len()
194
0
    }
195
}
196
197
/// Producer for `RepeatN`.
198
#[derive(Clone)]
199
enum RepeatNProducer<T> {
200
    Repeats(T, NonZeroUsize),
201
    Empty,
202
}
203
204
impl<T: Clone + Send> Producer for RepeatNProducer<T> {
205
    type Item = T;
206
    type IntoIter = Self;
207
208
0
    fn into_iter(self) -> Self::IntoIter {
209
        // We could potentially use `std::iter::RepeatN` with MSRV 1.82, but we have no way to
210
        // create an empty instance without a value in hand, like `repeat_n(value, 0)`.
211
0
        self
212
0
    }
213
214
0
    fn split_at(self, index: usize) -> (Self, Self) {
215
0
        if let Self::Repeats(element, count) = self {
216
0
            assert!(index <= count.get());
217
            match (
218
0
                NonZeroUsize::new(index),
219
0
                NonZeroUsize::new(count.get() - index),
220
            ) {
221
0
                (Some(left), Some(right)) => (
222
0
                    Self::Repeats(element.clone(), left),
223
0
                    Self::Repeats(element, right),
224
0
                ),
225
0
                (Some(left), None) => (Self::Repeats(element, left), Self::Empty),
226
0
                (None, Some(right)) => (Self::Empty, Self::Repeats(element, right)),
227
0
                (None, None) => unreachable!(),
228
            }
229
        } else {
230
0
            assert!(index == 0);
231
0
            (Self::Empty, Self::Empty)
232
        }
233
0
    }
234
}
235
236
impl<T: Clone> Iterator for RepeatNProducer<T> {
237
    type Item = T;
238
239
    #[inline]
240
0
    fn next(&mut self) -> Option<T> {
241
0
        if let Self::Repeats(element, count) = self {
242
0
            if let Some(rem) = NonZeroUsize::new(count.get() - 1) {
243
0
                *count = rem;
244
0
                Some(element.clone())
245
            } else {
246
0
                match mem::replace(self, Self::Empty) {
247
0
                    Self::Repeats(element, _) => Some(element),
248
0
                    Self::Empty => unreachable!(),
249
                }
250
            }
251
        } else {
252
0
            None
253
        }
254
0
    }
255
256
    #[inline]
257
0
    fn nth(&mut self, n: usize) -> Option<T> {
258
0
        if let Self::Repeats(_, count) = self {
259
0
            if let Some(rem) = NonZeroUsize::new(count.get().saturating_sub(n)) {
260
0
                *count = rem;
261
0
                return self.next();
262
0
            }
263
0
            *self = Self::Empty;
264
0
        }
265
0
        None
266
0
    }
267
268
    #[inline]
269
0
    fn size_hint(&self) -> (usize, Option<usize>) {
270
0
        let len = self.len();
271
0
        (len, Some(len))
272
0
    }
273
}
274
275
impl<T: Clone> DoubleEndedIterator for RepeatNProducer<T> {
276
    #[inline]
277
0
    fn next_back(&mut self) -> Option<T> {
278
0
        self.next()
279
0
    }
280
281
    #[inline]
282
0
    fn nth_back(&mut self, n: usize) -> Option<T> {
283
0
        self.nth(n)
284
0
    }
285
}
286
287
impl<T: Clone> ExactSizeIterator for RepeatNProducer<T> {
288
    #[inline]
289
0
    fn len(&self) -> usize {
290
0
        match self {
291
0
            Self::Repeats(_, count) => count.get(),
292
0
            Self::Empty => 0,
293
        }
294
0
    }
295
}