1use crate::{
2 iter::{plumbing::*, *},
3 math::div_round_up,
4};
5
6#[derive(Debug)]
9pub struct RChunks<'data, T: Sync> {
10 chunk_size: usize,
11 slice: &'data [T],
12}
13
14impl<'data, T: Sync> RChunks<'data, T> {
15 pub(super) fn new(chunk_size: usize, slice: &'data [T]) -> Self {
16 Self { chunk_size, slice }
17 }
18}
19
20impl<'data, T: Sync> Clone for RChunks<'data, T> {
21 fn clone(&self) -> Self {
22 RChunks { ..*self }
23 }
24}
25
26impl<'data, T: Sync + 'data> ParallelIterator for RChunks<'data, T> {
27 type Item = &'data [T];
28
29 fn drive_unindexed<C>(self, consumer: C) -> C::Result
30 where
31 C: UnindexedConsumer<Self::Item>,
32 {
33 bridge(self, consumer)
34 }
35
36 fn opt_len(&self) -> Option<usize> {
37 Some(self.len())
38 }
39}
40
41impl<'data, T: Sync + 'data> IndexedParallelIterator for RChunks<'data, T> {
42 fn drive<C>(self, consumer: C) -> C::Result
43 where
44 C: Consumer<Self::Item>,
45 {
46 bridge(self, consumer)
47 }
48
49 fn len(&self) -> usize {
50 div_round_up(self.slice.len(), self.chunk_size)
51 }
52
53 fn with_producer<CB>(self, callback: CB) -> CB::Output
54 where
55 CB: ProducerCallback<Self::Item>,
56 {
57 callback.callback(RChunksProducer {
58 chunk_size: self.chunk_size,
59 slice: self.slice,
60 })
61 }
62}
63
64struct RChunksProducer<'data, T: Sync> {
65 chunk_size: usize,
66 slice: &'data [T],
67}
68
69impl<'data, T: 'data + Sync> Producer for RChunksProducer<'data, T> {
70 type IntoIter = ::std::slice::RChunks<'data, T>;
71 type Item = &'data [T];
72
73 fn into_iter(self) -> Self::IntoIter {
74 self.slice.rchunks(self.chunk_size)
75 }
76
77 fn split_at(self, index: usize) -> (Self, Self) {
78 let elem_index = self.slice.len().saturating_sub(index * self.chunk_size);
79 let (left, right) = self.slice.split_at(elem_index);
80 (
81 RChunksProducer {
82 chunk_size: self.chunk_size,
83 slice: right,
84 },
85 RChunksProducer {
86 chunk_size: self.chunk_size,
87 slice: left,
88 },
89 )
90 }
91}
92
93#[derive(Debug)]
96pub struct RChunksExact<'data, T: Sync> {
97 chunk_size: usize,
98 slice: &'data [T],
99 rem: &'data [T],
100}
101
102impl<'data, T: Sync> RChunksExact<'data, T> {
103 pub(super) fn new(chunk_size: usize, slice: &'data [T]) -> Self {
104 let rem_len = slice.len() % chunk_size;
105 let (rem, slice) = slice.split_at(rem_len);
106 Self {
107 chunk_size,
108 slice,
109 rem,
110 }
111 }
112
113 pub fn remainder(&self) -> &'data [T] {
117 self.rem
118 }
119}
120
121impl<'data, T: Sync> Clone for RChunksExact<'data, T> {
122 fn clone(&self) -> Self {
123 RChunksExact { ..*self }
124 }
125}
126
127impl<'data, T: Sync + 'data> ParallelIterator for RChunksExact<'data, T> {
128 type Item = &'data [T];
129
130 fn drive_unindexed<C>(self, consumer: C) -> C::Result
131 where
132 C: UnindexedConsumer<Self::Item>,
133 {
134 bridge(self, consumer)
135 }
136
137 fn opt_len(&self) -> Option<usize> {
138 Some(self.len())
139 }
140}
141
142impl<'data, T: Sync + 'data> IndexedParallelIterator for RChunksExact<'data, T> {
143 fn drive<C>(self, consumer: C) -> C::Result
144 where
145 C: Consumer<Self::Item>,
146 {
147 bridge(self, consumer)
148 }
149
150 fn len(&self) -> usize {
151 self.slice.len() / self.chunk_size
152 }
153
154 fn with_producer<CB>(self, callback: CB) -> CB::Output
155 where
156 CB: ProducerCallback<Self::Item>,
157 {
158 callback.callback(RChunksExactProducer {
159 chunk_size: self.chunk_size,
160 slice: self.slice,
161 })
162 }
163}
164
165struct RChunksExactProducer<'data, T: Sync> {
166 chunk_size: usize,
167 slice: &'data [T],
168}
169
170impl<'data, T: 'data + Sync> Producer for RChunksExactProducer<'data, T> {
171 type IntoIter = ::std::slice::RChunksExact<'data, T>;
172 type Item = &'data [T];
173
174 fn into_iter(self) -> Self::IntoIter {
175 self.slice.rchunks_exact(self.chunk_size)
176 }
177
178 fn split_at(self, index: usize) -> (Self, Self) {
179 let elem_index = self.slice.len() - index * self.chunk_size;
180 let (left, right) = self.slice.split_at(elem_index);
181 (
182 RChunksExactProducer {
183 chunk_size: self.chunk_size,
184 slice: right,
185 },
186 RChunksExactProducer {
187 chunk_size: self.chunk_size,
188 slice: left,
189 },
190 )
191 }
192}
193
194#[derive(Debug)]
197pub struct RChunksMut<'data, T: Send> {
198 chunk_size: usize,
199 slice: &'data mut [T],
200}
201
202impl<'data, T: Send> RChunksMut<'data, T> {
203 pub(super) fn new(chunk_size: usize, slice: &'data mut [T]) -> Self {
204 Self { chunk_size, slice }
205 }
206}
207
208impl<'data, T: Send + 'data> ParallelIterator for RChunksMut<'data, T> {
209 type Item = &'data mut [T];
210
211 fn drive_unindexed<C>(self, consumer: C) -> C::Result
212 where
213 C: UnindexedConsumer<Self::Item>,
214 {
215 bridge(self, consumer)
216 }
217
218 fn opt_len(&self) -> Option<usize> {
219 Some(self.len())
220 }
221}
222
223impl<'data, T: Send + 'data> IndexedParallelIterator for RChunksMut<'data, T> {
224 fn drive<C>(self, consumer: C) -> C::Result
225 where
226 C: Consumer<Self::Item>,
227 {
228 bridge(self, consumer)
229 }
230
231 fn len(&self) -> usize {
232 div_round_up(self.slice.len(), self.chunk_size)
233 }
234
235 fn with_producer<CB>(self, callback: CB) -> CB::Output
236 where
237 CB: ProducerCallback<Self::Item>,
238 {
239 callback.callback(RChunksMutProducer {
240 chunk_size: self.chunk_size,
241 slice: self.slice,
242 })
243 }
244}
245
246struct RChunksMutProducer<'data, T: Send> {
247 chunk_size: usize,
248 slice: &'data mut [T],
249}
250
251impl<'data, T: 'data + Send> Producer for RChunksMutProducer<'data, T> {
252 type IntoIter = ::std::slice::RChunksMut<'data, T>;
253 type Item = &'data mut [T];
254
255 fn into_iter(self) -> Self::IntoIter {
256 self.slice.rchunks_mut(self.chunk_size)
257 }
258
259 fn split_at(self, index: usize) -> (Self, Self) {
260 let elem_index = self.slice.len().saturating_sub(index * self.chunk_size);
261 let (left, right) = self.slice.split_at_mut(elem_index);
262 (
263 RChunksMutProducer {
264 chunk_size: self.chunk_size,
265 slice: right,
266 },
267 RChunksMutProducer {
268 chunk_size: self.chunk_size,
269 slice: left,
270 },
271 )
272 }
273}
274
275#[derive(Debug)]
278pub struct RChunksExactMut<'data, T: Send> {
279 chunk_size: usize,
280 slice: &'data mut [T],
281 rem: &'data mut [T],
282}
283
284impl<'data, T: Send> RChunksExactMut<'data, T> {
285 pub(super) fn new(chunk_size: usize, slice: &'data mut [T]) -> Self {
286 let rem_len = slice.len() % chunk_size;
287 let (rem, slice) = slice.split_at_mut(rem_len);
288 Self {
289 chunk_size,
290 slice,
291 rem,
292 }
293 }
294
295 pub fn into_remainder(self) -> &'data mut [T] {
305 self.rem
306 }
307
308 pub fn remainder(&mut self) -> &mut [T] {
315 self.rem
316 }
317
318 pub fn take_remainder(&mut self) -> &'data mut [T] {
322 std::mem::take(&mut self.rem)
323 }
324}
325
326impl<'data, T: Send + 'data> ParallelIterator for RChunksExactMut<'data, T> {
327 type Item = &'data mut [T];
328
329 fn drive_unindexed<C>(self, consumer: C) -> C::Result
330 where
331 C: UnindexedConsumer<Self::Item>,
332 {
333 bridge(self, consumer)
334 }
335
336 fn opt_len(&self) -> Option<usize> {
337 Some(self.len())
338 }
339}
340
341impl<'data, T: Send + 'data> IndexedParallelIterator for RChunksExactMut<'data, T> {
342 fn drive<C>(self, consumer: C) -> C::Result
343 where
344 C: Consumer<Self::Item>,
345 {
346 bridge(self, consumer)
347 }
348
349 fn len(&self) -> usize {
350 self.slice.len() / self.chunk_size
351 }
352
353 fn with_producer<CB>(self, callback: CB) -> CB::Output
354 where
355 CB: ProducerCallback<Self::Item>,
356 {
357 callback.callback(RChunksExactMutProducer {
358 chunk_size: self.chunk_size,
359 slice: self.slice,
360 })
361 }
362}
363
364struct RChunksExactMutProducer<'data, T: Send> {
365 chunk_size: usize,
366 slice: &'data mut [T],
367}
368
369impl<'data, T: 'data + Send> Producer for RChunksExactMutProducer<'data, T> {
370 type IntoIter = ::std::slice::RChunksExactMut<'data, T>;
371 type Item = &'data mut [T];
372
373 fn into_iter(self) -> Self::IntoIter {
374 self.slice.rchunks_exact_mut(self.chunk_size)
375 }
376
377 fn split_at(self, index: usize) -> (Self, Self) {
378 let elem_index = self.slice.len() - index * self.chunk_size;
379 let (left, right) = self.slice.split_at_mut(elem_index);
380 (
381 RChunksExactMutProducer {
382 chunk_size: self.chunk_size,
383 slice: right,
384 },
385 RChunksExactMutProducer {
386 chunk_size: self.chunk_size,
387 slice: left,
388 },
389 )
390 }
391}