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