Coverage Report

Created: 2026-01-19 07:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rayon-1.11.0/src/slice/chunks.rs
Line
Count
Source
1
use crate::iter::plumbing::*;
2
use crate::iter::*;
3
4
/// Parallel iterator over immutable non-overlapping chunks of a slice
5
#[derive(Debug)]
6
pub struct Chunks<'data, T> {
7
    chunk_size: usize,
8
    slice: &'data [T],
9
}
10
11
impl<'data, T> Chunks<'data, T> {
12
0
    pub(super) fn new(chunk_size: usize, slice: &'data [T]) -> Self {
13
0
        Self { chunk_size, slice }
14
0
    }
15
}
16
17
impl<T> Clone for Chunks<'_, T> {
18
0
    fn clone(&self) -> Self {
19
0
        Chunks { ..*self }
20
0
    }
21
}
22
23
impl<'data, T: Sync> ParallelIterator for Chunks<'data, T> {
24
    type Item = &'data [T];
25
26
0
    fn drive_unindexed<C>(self, consumer: C) -> C::Result
27
0
    where
28
0
        C: UnindexedConsumer<Self::Item>,
29
    {
30
0
        bridge(self, consumer)
31
0
    }
32
33
0
    fn opt_len(&self) -> Option<usize> {
34
0
        Some(self.len())
35
0
    }
36
}
37
38
impl<T: Sync> IndexedParallelIterator for Chunks<'_, T> {
39
0
    fn drive<C>(self, consumer: C) -> C::Result
40
0
    where
41
0
        C: Consumer<Self::Item>,
42
    {
43
0
        bridge(self, consumer)
44
0
    }
45
46
0
    fn len(&self) -> usize {
47
0
        self.slice.len().div_ceil(self.chunk_size)
48
0
    }
49
50
0
    fn with_producer<CB>(self, callback: CB) -> CB::Output
51
0
    where
52
0
        CB: ProducerCallback<Self::Item>,
53
    {
54
0
        callback.callback(ChunksProducer {
55
0
            chunk_size: self.chunk_size,
56
0
            slice: self.slice,
57
0
        })
58
0
    }
59
}
60
61
struct ChunksProducer<'data, T: Sync> {
62
    chunk_size: usize,
63
    slice: &'data [T],
64
}
65
66
impl<'data, T: 'data + Sync> Producer for ChunksProducer<'data, T> {
67
    type Item = &'data [T];
68
    type IntoIter = ::std::slice::Chunks<'data, T>;
69
70
0
    fn into_iter(self) -> Self::IntoIter {
71
0
        self.slice.chunks(self.chunk_size)
72
0
    }
73
74
0
    fn split_at(self, index: usize) -> (Self, Self) {
75
0
        let elem_index = Ord::min(index * self.chunk_size, self.slice.len());
76
0
        let (left, right) = self.slice.split_at(elem_index);
77
0
        (
78
0
            ChunksProducer {
79
0
                chunk_size: self.chunk_size,
80
0
                slice: left,
81
0
            },
82
0
            ChunksProducer {
83
0
                chunk_size: self.chunk_size,
84
0
                slice: right,
85
0
            },
86
0
        )
87
0
    }
88
}
89
90
/// Parallel iterator over immutable non-overlapping chunks of a slice
91
#[derive(Debug)]
92
pub struct ChunksExact<'data, T> {
93
    chunk_size: usize,
94
    slice: &'data [T],
95
    rem: &'data [T],
96
}
97
98
impl<'data, T> ChunksExact<'data, T> {
99
0
    pub(super) fn new(chunk_size: usize, slice: &'data [T]) -> Self {
100
0
        let rem_len = slice.len() % chunk_size;
101
0
        let len = slice.len() - rem_len;
102
0
        let (slice, rem) = slice.split_at(len);
103
0
        Self {
104
0
            chunk_size,
105
0
            slice,
106
0
            rem,
107
0
        }
108
0
    }
109
110
    /// Return the remainder of the original slice that is not going to be
111
    /// returned by the iterator. The returned slice has at most `chunk_size-1`
112
    /// elements.
113
0
    pub fn remainder(&self) -> &'data [T] {
114
0
        self.rem
115
0
    }
116
}
117
118
impl<T> Clone for ChunksExact<'_, T> {
119
0
    fn clone(&self) -> Self {
120
0
        ChunksExact { ..*self }
121
0
    }
122
}
123
124
impl<'data, T: Sync> ParallelIterator for ChunksExact<'data, T> {
125
    type Item = &'data [T];
126
127
0
    fn drive_unindexed<C>(self, consumer: C) -> C::Result
128
0
    where
129
0
        C: UnindexedConsumer<Self::Item>,
130
    {
131
0
        bridge(self, consumer)
132
0
    }
133
134
0
    fn opt_len(&self) -> Option<usize> {
135
0
        Some(self.len())
136
0
    }
137
}
138
139
impl<T: Sync> IndexedParallelIterator for ChunksExact<'_, T> {
140
0
    fn drive<C>(self, consumer: C) -> C::Result
141
0
    where
142
0
        C: Consumer<Self::Item>,
143
    {
144
0
        bridge(self, consumer)
145
0
    }
146
147
0
    fn len(&self) -> usize {
148
0
        self.slice.len() / self.chunk_size
149
0
    }
150
151
0
    fn with_producer<CB>(self, callback: CB) -> CB::Output
152
0
    where
153
0
        CB: ProducerCallback<Self::Item>,
154
    {
155
0
        callback.callback(ChunksExactProducer {
156
0
            chunk_size: self.chunk_size,
157
0
            slice: self.slice,
158
0
        })
159
0
    }
160
}
161
162
struct ChunksExactProducer<'data, T: Sync> {
163
    chunk_size: usize,
164
    slice: &'data [T],
165
}
166
167
impl<'data, T: 'data + Sync> Producer for ChunksExactProducer<'data, T> {
168
    type Item = &'data [T];
169
    type IntoIter = ::std::slice::ChunksExact<'data, T>;
170
171
0
    fn into_iter(self) -> Self::IntoIter {
172
0
        self.slice.chunks_exact(self.chunk_size)
173
0
    }
174
175
0
    fn split_at(self, index: usize) -> (Self, Self) {
176
0
        let elem_index = index * self.chunk_size;
177
0
        let (left, right) = self.slice.split_at(elem_index);
178
0
        (
179
0
            ChunksExactProducer {
180
0
                chunk_size: self.chunk_size,
181
0
                slice: left,
182
0
            },
183
0
            ChunksExactProducer {
184
0
                chunk_size: self.chunk_size,
185
0
                slice: right,
186
0
            },
187
0
        )
188
0
    }
189
}
190
191
/// Parallel iterator over mutable non-overlapping chunks of a slice
192
#[derive(Debug)]
193
pub struct ChunksMut<'data, T> {
194
    chunk_size: usize,
195
    slice: &'data mut [T],
196
}
197
198
impl<'data, T> ChunksMut<'data, T> {
199
0
    pub(super) fn new(chunk_size: usize, slice: &'data mut [T]) -> Self {
200
0
        Self { chunk_size, slice }
201
0
    }
202
}
203
204
impl<'data, T: Send> ParallelIterator for ChunksMut<'data, T> {
205
    type Item = &'data mut [T];
206
207
0
    fn drive_unindexed<C>(self, consumer: C) -> C::Result
208
0
    where
209
0
        C: UnindexedConsumer<Self::Item>,
210
    {
211
0
        bridge(self, consumer)
212
0
    }
213
214
0
    fn opt_len(&self) -> Option<usize> {
215
0
        Some(self.len())
216
0
    }
217
}
218
219
impl<T: Send> IndexedParallelIterator for ChunksMut<'_, T> {
220
0
    fn drive<C>(self, consumer: C) -> C::Result
221
0
    where
222
0
        C: Consumer<Self::Item>,
223
    {
224
0
        bridge(self, consumer)
225
0
    }
226
227
0
    fn len(&self) -> usize {
228
0
        self.slice.len().div_ceil(self.chunk_size)
229
0
    }
230
231
0
    fn with_producer<CB>(self, callback: CB) -> CB::Output
232
0
    where
233
0
        CB: ProducerCallback<Self::Item>,
234
    {
235
0
        callback.callback(ChunksMutProducer {
236
0
            chunk_size: self.chunk_size,
237
0
            slice: self.slice,
238
0
        })
239
0
    }
240
}
241
242
struct ChunksMutProducer<'data, T: Send> {
243
    chunk_size: usize,
244
    slice: &'data mut [T],
245
}
246
247
impl<'data, T: 'data + Send> Producer for ChunksMutProducer<'data, T> {
248
    type Item = &'data mut [T];
249
    type IntoIter = ::std::slice::ChunksMut<'data, T>;
250
251
0
    fn into_iter(self) -> Self::IntoIter {
252
0
        self.slice.chunks_mut(self.chunk_size)
253
0
    }
254
255
0
    fn split_at(self, index: usize) -> (Self, Self) {
256
0
        let elem_index = Ord::min(index * self.chunk_size, self.slice.len());
257
0
        let (left, right) = self.slice.split_at_mut(elem_index);
258
0
        (
259
0
            ChunksMutProducer {
260
0
                chunk_size: self.chunk_size,
261
0
                slice: left,
262
0
            },
263
0
            ChunksMutProducer {
264
0
                chunk_size: self.chunk_size,
265
0
                slice: right,
266
0
            },
267
0
        )
268
0
    }
269
}
270
271
/// Parallel iterator over mutable non-overlapping chunks of a slice
272
#[derive(Debug)]
273
pub struct ChunksExactMut<'data, T> {
274
    chunk_size: usize,
275
    slice: &'data mut [T],
276
    rem: &'data mut [T],
277
}
278
279
impl<'data, T> ChunksExactMut<'data, T> {
280
0
    pub(super) fn new(chunk_size: usize, slice: &'data mut [T]) -> Self {
281
0
        let rem_len = slice.len() % chunk_size;
282
0
        let len = slice.len() - rem_len;
283
0
        let (slice, rem) = slice.split_at_mut(len);
284
0
        Self {
285
0
            chunk_size,
286
0
            slice,
287
0
            rem,
288
0
        }
289
0
    }
290
291
    /// Return the remainder of the original slice that is not going to be
292
    /// returned by the iterator. The returned slice has at most `chunk_size-1`
293
    /// elements.
294
    ///
295
    /// Note that this has to consume `self` to return the original lifetime of
296
    /// the data, which prevents this from actually being used as a parallel
297
    /// iterator since that also consumes. This method is provided for parity
298
    /// with `std::iter::ChunksExactMut`, but consider calling `remainder()` or
299
    /// `take_remainder()` as alternatives.
300
0
    pub fn into_remainder(self) -> &'data mut [T] {
301
0
        self.rem
302
0
    }
303
304
    /// Return the remainder of the original slice that is not going to be
305
    /// returned by the iterator. The returned slice has at most `chunk_size-1`
306
    /// elements.
307
    ///
308
    /// Consider `take_remainder()` if you need access to the data with its
309
    /// original lifetime, rather than borrowing through `&mut self` here.
310
0
    pub fn remainder(&mut self) -> &mut [T] {
311
0
        self.rem
312
0
    }
313
314
    /// Return the remainder of the original slice that is not going to be
315
    /// returned by the iterator. The returned slice has at most `chunk_size-1`
316
    /// elements. Subsequent calls will return an empty slice.
317
0
    pub fn take_remainder(&mut self) -> &'data mut [T] {
318
0
        std::mem::take(&mut self.rem)
319
0
    }
320
}
321
322
impl<'data, T: Send> ParallelIterator for ChunksExactMut<'data, T> {
323
    type Item = &'data mut [T];
324
325
0
    fn drive_unindexed<C>(self, consumer: C) -> C::Result
326
0
    where
327
0
        C: UnindexedConsumer<Self::Item>,
328
    {
329
0
        bridge(self, consumer)
330
0
    }
331
332
0
    fn opt_len(&self) -> Option<usize> {
333
0
        Some(self.len())
334
0
    }
335
}
336
337
impl<T: Send> IndexedParallelIterator for ChunksExactMut<'_, T> {
338
0
    fn drive<C>(self, consumer: C) -> C::Result
339
0
    where
340
0
        C: Consumer<Self::Item>,
341
    {
342
0
        bridge(self, consumer)
343
0
    }
344
345
0
    fn len(&self) -> usize {
346
0
        self.slice.len() / self.chunk_size
347
0
    }
348
349
0
    fn with_producer<CB>(self, callback: CB) -> CB::Output
350
0
    where
351
0
        CB: ProducerCallback<Self::Item>,
352
    {
353
0
        callback.callback(ChunksExactMutProducer {
354
0
            chunk_size: self.chunk_size,
355
0
            slice: self.slice,
356
0
        })
357
0
    }
358
}
359
360
struct ChunksExactMutProducer<'data, T: Send> {
361
    chunk_size: usize,
362
    slice: &'data mut [T],
363
}
364
365
impl<'data, T: 'data + Send> Producer for ChunksExactMutProducer<'data, T> {
366
    type Item = &'data mut [T];
367
    type IntoIter = ::std::slice::ChunksExactMut<'data, T>;
368
369
0
    fn into_iter(self) -> Self::IntoIter {
370
0
        self.slice.chunks_exact_mut(self.chunk_size)
371
0
    }
372
373
0
    fn split_at(self, index: usize) -> (Self, Self) {
374
0
        let elem_index = index * self.chunk_size;
375
0
        let (left, right) = self.slice.split_at_mut(elem_index);
376
0
        (
377
0
            ChunksExactMutProducer {
378
0
                chunk_size: self.chunk_size,
379
0
                slice: left,
380
0
            },
381
0
            ChunksExactMutProducer {
382
0
                chunk_size: self.chunk_size,
383
0
                slice: right,
384
0
            },
385
0
        )
386
0
    }
387
}