Coverage Report

Created: 2025-07-18 06:49

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