Coverage Report

Created: 2025-02-21 07:11

/rust/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.10.0/src/slice/rchunks.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, starting at the end.
6
#[derive(Debug)]
7
pub struct RChunks<'data, T: Sync> {
8
    chunk_size: usize,
9
    slice: &'data [T],
10
}
11
12
impl<'data, T: Sync> RChunks<'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 RChunks<'data, T> {
19
0
    fn clone(&self) -> Self {
20
0
        RChunks { ..*self }
21
0
    }
22
}
23
24
impl<'data, T: Sync + 'data> ParallelIterator for RChunks<'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 RChunks<'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(RChunksProducer {
56
0
            chunk_size: self.chunk_size,
57
0
            slice: self.slice,
58
0
        })
59
0
    }
60
}
61
62
struct RChunksProducer<'data, T: Sync> {
63
    chunk_size: usize,
64
    slice: &'data [T],
65
}
66
67
impl<'data, T: 'data + Sync> Producer for RChunksProducer<'data, T> {
68
    type Item = &'data [T];
69
    type IntoIter = ::std::slice::RChunks<'data, T>;
70
71
0
    fn into_iter(self) -> Self::IntoIter {
72
0
        self.slice.rchunks(self.chunk_size)
73
0
    }
74
75
0
    fn split_at(self, index: usize) -> (Self, Self) {
76
0
        let elem_index = self.slice.len().saturating_sub(index * self.chunk_size);
77
0
        let (left, right) = self.slice.split_at(elem_index);
78
0
        (
79
0
            RChunksProducer {
80
0
                chunk_size: self.chunk_size,
81
0
                slice: right,
82
0
            },
83
0
            RChunksProducer {
84
0
                chunk_size: self.chunk_size,
85
0
                slice: left,
86
0
            },
87
0
        )
88
0
    }
89
}
90
91
/// Parallel iterator over immutable non-overlapping chunks of a slice, starting at the end.
92
#[derive(Debug)]
93
pub struct RChunksExact<'data, T: Sync> {
94
    chunk_size: usize,
95
    slice: &'data [T],
96
    rem: &'data [T],
97
}
98
99
impl<'data, T: Sync> RChunksExact<'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 (rem, slice) = slice.split_at(rem_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<'data, T: Sync> Clone for RChunksExact<'data, T> {
119
0
    fn clone(&self) -> Self {
120
0
        RChunksExact { ..*self }
121
0
    }
122
}
123
124
impl<'data, T: Sync + 'data> ParallelIterator for RChunksExact<'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
0
    {
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<'data, T: Sync + 'data> IndexedParallelIterator for RChunksExact<'data, T> {
140
0
    fn drive<C>(self, consumer: C) -> C::Result
141
0
    where
142
0
        C: Consumer<Self::Item>,
143
0
    {
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
0
    {
155
0
        callback.callback(RChunksExactProducer {
156
0
            chunk_size: self.chunk_size,
157
0
            slice: self.slice,
158
0
        })
159
0
    }
160
}
161
162
struct RChunksExactProducer<'data, T: Sync> {
163
    chunk_size: usize,
164
    slice: &'data [T],
165
}
166
167
impl<'data, T: 'data + Sync> Producer for RChunksExactProducer<'data, T> {
168
    type Item = &'data [T];
169
    type IntoIter = ::std::slice::RChunksExact<'data, T>;
170
171
0
    fn into_iter(self) -> Self::IntoIter {
172
0
        self.slice.rchunks_exact(self.chunk_size)
173
0
    }
174
175
0
    fn split_at(self, index: usize) -> (Self, Self) {
176
0
        let elem_index = self.slice.len() - index * self.chunk_size;
177
0
        let (left, right) = self.slice.split_at(elem_index);
178
0
        (
179
0
            RChunksExactProducer {
180
0
                chunk_size: self.chunk_size,
181
0
                slice: right,
182
0
            },
183
0
            RChunksExactProducer {
184
0
                chunk_size: self.chunk_size,
185
0
                slice: left,
186
0
            },
187
0
        )
188
0
    }
189
}
190
191
/// Parallel iterator over mutable non-overlapping chunks of a slice, starting at the end.
192
#[derive(Debug)]
193
pub struct RChunksMut<'data, T: Send> {
194
    chunk_size: usize,
195
    slice: &'data mut [T],
196
}
197
198
impl<'data, T: Send> RChunksMut<'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 + 'data> ParallelIterator for RChunksMut<'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
0
    {
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<'data, T: Send + 'data> IndexedParallelIterator for RChunksMut<'data, T> {
220
0
    fn drive<C>(self, consumer: C) -> C::Result
221
0
    where
222
0
        C: Consumer<Self::Item>,
223
0
    {
224
0
        bridge(self, consumer)
225
0
    }
226
227
0
    fn len(&self) -> usize {
228
0
        div_round_up(self.slice.len(), 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
0
    {
235
0
        callback.callback(RChunksMutProducer {
236
0
            chunk_size: self.chunk_size,
237
0
            slice: self.slice,
238
0
        })
239
0
    }
240
}
241
242
struct RChunksMutProducer<'data, T: Send> {
243
    chunk_size: usize,
244
    slice: &'data mut [T],
245
}
246
247
impl<'data, T: 'data + Send> Producer for RChunksMutProducer<'data, T> {
248
    type Item = &'data mut [T];
249
    type IntoIter = ::std::slice::RChunksMut<'data, T>;
250
251
0
    fn into_iter(self) -> Self::IntoIter {
252
0
        self.slice.rchunks_mut(self.chunk_size)
253
0
    }
254
255
0
    fn split_at(self, index: usize) -> (Self, Self) {
256
0
        let elem_index = self.slice.len().saturating_sub(index * self.chunk_size);
257
0
        let (left, right) = self.slice.split_at_mut(elem_index);
258
0
        (
259
0
            RChunksMutProducer {
260
0
                chunk_size: self.chunk_size,
261
0
                slice: right,
262
0
            },
263
0
            RChunksMutProducer {
264
0
                chunk_size: self.chunk_size,
265
0
                slice: left,
266
0
            },
267
0
        )
268
0
    }
269
}
270
271
/// Parallel iterator over mutable non-overlapping chunks of a slice, starting at the end.
272
#[derive(Debug)]
273
pub struct RChunksExactMut<'data, T: Send> {
274
    chunk_size: usize,
275
    slice: &'data mut [T],
276
    rem: &'data mut [T],
277
}
278
279
impl<'data, T: Send> RChunksExactMut<'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 (rem, slice) = slice.split_at_mut(rem_len);
283
0
        Self {
284
0
            chunk_size,
285
0
            slice,
286
0
            rem,
287
0
        }
288
0
    }
289
290
    /// Return the remainder of the original slice that is not going to be
291
    /// returned by the iterator. The returned slice has at most `chunk_size-1`
292
    /// elements.
293
    ///
294
    /// Note that this has to consume `self` to return the original lifetime of
295
    /// the data, which prevents this from actually being used as a parallel
296
    /// iterator since that also consumes. This method is provided for parity
297
    /// with `std::iter::RChunksExactMut`, but consider calling `remainder()` or
298
    /// `take_remainder()` as alternatives.
299
0
    pub fn into_remainder(self) -> &'data mut [T] {
300
0
        self.rem
301
0
    }
302
303
    /// Return the remainder of the original slice that is not going to be
304
    /// returned by the iterator. The returned slice has at most `chunk_size-1`
305
    /// elements.
306
    ///
307
    /// Consider `take_remainder()` if you need access to the data with its
308
    /// original lifetime, rather than borrowing through `&mut self` here.
309
0
    pub fn remainder(&mut self) -> &mut [T] {
310
0
        self.rem
311
0
    }
312
313
    /// Return the remainder of the original slice that is not going to be
314
    /// returned by the iterator. The returned slice has at most `chunk_size-1`
315
    /// elements. Subsequent calls will return an empty slice.
316
0
    pub fn take_remainder(&mut self) -> &'data mut [T] {
317
0
        std::mem::take(&mut self.rem)
318
0
    }
319
}
320
321
impl<'data, T: Send + 'data> ParallelIterator for RChunksExactMut<'data, T> {
322
    type Item = &'data mut [T];
323
324
0
    fn drive_unindexed<C>(self, consumer: C) -> C::Result
325
0
    where
326
0
        C: UnindexedConsumer<Self::Item>,
327
0
    {
328
0
        bridge(self, consumer)
329
0
    }
330
331
0
    fn opt_len(&self) -> Option<usize> {
332
0
        Some(self.len())
333
0
    }
334
}
335
336
impl<'data, T: Send + 'data> IndexedParallelIterator for RChunksExactMut<'data, T> {
337
0
    fn drive<C>(self, consumer: C) -> C::Result
338
0
    where
339
0
        C: Consumer<Self::Item>,
340
0
    {
341
0
        bridge(self, consumer)
342
0
    }
343
344
0
    fn len(&self) -> usize {
345
0
        self.slice.len() / self.chunk_size
346
0
    }
347
348
0
    fn with_producer<CB>(self, callback: CB) -> CB::Output
349
0
    where
350
0
        CB: ProducerCallback<Self::Item>,
351
0
    {
352
0
        callback.callback(RChunksExactMutProducer {
353
0
            chunk_size: self.chunk_size,
354
0
            slice: self.slice,
355
0
        })
356
0
    }
357
}
358
359
struct RChunksExactMutProducer<'data, T: Send> {
360
    chunk_size: usize,
361
    slice: &'data mut [T],
362
}
363
364
impl<'data, T: 'data + Send> Producer for RChunksExactMutProducer<'data, T> {
365
    type Item = &'data mut [T];
366
    type IntoIter = ::std::slice::RChunksExactMut<'data, T>;
367
368
0
    fn into_iter(self) -> Self::IntoIter {
369
0
        self.slice.rchunks_exact_mut(self.chunk_size)
370
0
    }
371
372
0
    fn split_at(self, index: usize) -> (Self, Self) {
373
0
        let elem_index = self.slice.len() - index * self.chunk_size;
374
0
        let (left, right) = self.slice.split_at_mut(elem_index);
375
0
        (
376
0
            RChunksExactMutProducer {
377
0
                chunk_size: self.chunk_size,
378
0
                slice: right,
379
0
            },
380
0
            RChunksExactMutProducer {
381
0
                chunk_size: self.chunk_size,
382
0
                slice: left,
383
0
            },
384
0
        )
385
0
    }
386
}