1use core::num::NonZeroUsize;
2
3use crate::VectorReadUnion;
4
5use super::UnionVector;
6
7fn div_ceil(lhs: usize, rhs: usize) -> usize {
8 let d = lhs / rhs;
9 let r = lhs % rhs;
10 if r > 0 && rhs > 0 {
11 d + 1
12 } else {
13 d
14 }
15}
16
17pub struct Iter<'buf, T> {
21 v: UnionVector<'buf, T>,
22}
23
24impl<'buf, T: VectorReadUnion<'buf> + core::fmt::Debug> core::fmt::Debug for Iter<'buf, T> {
25 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
26 f.debug_struct("Iter").field("v", &self.v).finish()
27 }
28}
29
30impl<T> Clone for Iter<'_, T> {
31 #[inline]
32 fn clone(&self) -> Self {
33 Self { v: self.v }
34 }
35}
36
37impl<'buf, T: VectorReadUnion<'buf>> Iter<'buf, T> {
38 #[inline]
39 pub(crate) fn new(v: UnionVector<'buf, T>) -> Self {
40 Self { v }
41 }
42}
43
44impl<'buf, T: VectorReadUnion<'buf>> Iterator for Iter<'buf, T> {
45 type Item = crate::Result<T>;
46
47 #[inline]
48 fn next(&mut self) -> Option<crate::Result<T>> {
49 if let Some((first, remaining)) = self.v.split_first() {
50 self.v = remaining;
51 Some(first)
52 } else {
53 None
54 }
55 }
56
57 #[inline]
58 fn nth(&mut self, n: usize) -> Option<Self::Item> {
59 self.v = self.v.get(n..).unwrap_or_else(|| UnionVector::new_empty());
60 self.next()
61 }
62
63 #[inline]
64 fn size_hint(&self) -> (usize, Option<usize>) {
65 let len = self.len();
66 (len, Some(len))
67 }
68
69 #[inline]
70 fn count(self) -> usize {
71 self.len()
72 }
73
74 #[inline]
75 fn last(self) -> Option<Self::Item> {
76 self.v.last()
77 }
78}
79
80impl<'buf, T: VectorReadUnion<'buf>> core::iter::DoubleEndedIterator for Iter<'buf, T> {
81 #[inline]
82 fn next_back(&mut self) -> Option<Self::Item> {
83 if let Some((last, remaining)) = self.v.split_last() {
84 self.v = remaining;
85 Some(last)
86 } else {
87 None
88 }
89 }
90
91 #[inline]
92 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
93 self.v = unsafe { self.v.get_unchecked(..self.v.len().saturating_sub(n)) };
94 self.next_back()
95 }
96}
97
98impl<'buf, T: VectorReadUnion<'buf>> core::iter::ExactSizeIterator for Iter<'buf, T> {
99 #[inline]
100 fn len(&self) -> usize {
101 self.v.len()
102 }
103}
104
105impl<'buf, T: VectorReadUnion<'buf>> core::iter::FusedIterator for Iter<'buf, T> {}
106
107pub struct Chunks<'buf, T> {
115 v: UnionVector<'buf, T>,
116 chunk_size: NonZeroUsize,
117}
118
119impl<'buf, T: VectorReadUnion<'buf> + core::fmt::Debug> core::fmt::Debug for Chunks<'buf, T> {
120 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
121 f.debug_struct("Chunks")
122 .field("v", &self.v)
123 .field("chunk_size", &self.chunk_size)
124 .finish()
125 }
126}
127
128impl<T> Clone for Chunks<'_, T> {
129 #[inline]
130 fn clone(&self) -> Self {
131 Self {
132 v: self.v,
133 chunk_size: self.chunk_size,
134 }
135 }
136}
137
138impl<'buf, T: VectorReadUnion<'buf>> Chunks<'buf, T> {
139 #[inline]
140 pub(crate) fn new(v: UnionVector<'buf, T>, chunk_size: NonZeroUsize) -> Self {
141 Self { v, chunk_size }
142 }
143}
144
145impl<'buf, T: VectorReadUnion<'buf>> Iterator for Chunks<'buf, T> {
146 type Item = UnionVector<'buf, T>;
147
148 #[inline]
149 fn next(&mut self) -> Option<UnionVector<'buf, T>> {
150 if self.v.is_empty() {
151 None
152 } else if let Some((first, remaining)) = self.v.split_at(self.chunk_size.get()) {
153 self.v = remaining;
154 Some(first)
155 } else {
156 Some(core::mem::replace(&mut self.v, UnionVector::new_empty()))
157 }
158 }
159
160 #[inline]
161 fn nth(&mut self, n: usize) -> Option<Self::Item> {
162 let skip = n.saturating_mul(self.chunk_size.get());
163 self.v = self
164 .v
165 .get(skip..)
166 .unwrap_or_else(|| UnionVector::new_empty());
167 self.next()
168 }
169
170 #[inline]
171 fn size_hint(&self) -> (usize, Option<usize>) {
172 let len = self.len();
173 (len, Some(len))
174 }
175
176 #[inline]
177 fn count(self) -> usize {
178 self.len()
179 }
180
181 #[inline]
182 fn last(mut self) -> Option<Self::Item> {
183 self.next_back()
184 }
185}
186
187impl<'buf, T: VectorReadUnion<'buf>> core::iter::DoubleEndedIterator for Chunks<'buf, T> {
188 #[inline]
189 fn next_back(&mut self) -> Option<Self::Item> {
190 if self.v.is_empty() {
191 None
192 } else {
193 let split_point = (self.v.len() - 1) / self.chunk_size * self.chunk_size.get();
194 let (remaining, last) = unsafe { self.v.split_at_unchecked(split_point) };
195 self.v = remaining;
196 Some(last)
197 }
198 }
199
200 #[inline]
201 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
202 if n > 0 {
203 let new_chunk_count = self.len().saturating_sub(n);
205 self.v = unsafe {
208 self.v
209 .get_unchecked(..new_chunk_count * self.chunk_size.get())
210 };
211 }
212 self.next_back()
213 }
214}
215
216impl<'buf, T: VectorReadUnion<'buf>> core::iter::ExactSizeIterator for Chunks<'buf, T> {
217 #[inline]
218 fn len(&self) -> usize {
219 let len = self.v.len();
220 div_ceil(len, self.chunk_size.get())
221 }
222}
223
224impl<'buf, T: VectorReadUnion<'buf>> core::iter::FusedIterator for Chunks<'buf, T> {}
225
226pub struct RChunks<'buf, T> {
234 v: UnionVector<'buf, T>,
235 chunk_size: NonZeroUsize,
236}
237
238impl<'buf, T: VectorReadUnion<'buf> + core::fmt::Debug> core::fmt::Debug for RChunks<'buf, T> {
239 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
240 f.debug_struct("RChunks")
241 .field("v", &self.v)
242 .field("chunk_size", &self.chunk_size)
243 .finish()
244 }
245}
246
247impl<T> Clone for RChunks<'_, T> {
248 #[inline]
249 fn clone(&self) -> Self {
250 Self {
251 v: self.v,
252 chunk_size: self.chunk_size,
253 }
254 }
255}
256
257impl<'buf, T: VectorReadUnion<'buf>> RChunks<'buf, T> {
258 #[inline]
259 pub(crate) fn new(v: UnionVector<'buf, T>, chunk_size: NonZeroUsize) -> Self {
260 Self { v, chunk_size }
261 }
262}
263
264impl<'buf, T: VectorReadUnion<'buf>> Iterator for RChunks<'buf, T> {
265 type Item = UnionVector<'buf, T>;
266
267 #[inline]
268 fn next(&mut self) -> Option<UnionVector<'buf, T>> {
269 if self.v.is_empty() {
270 None
271 } else {
272 let (remaining, cur) = unsafe {
273 self.v
274 .split_at_unchecked(self.v.len().saturating_sub(self.chunk_size.get()))
275 };
276 self.v = remaining;
277 Some(cur)
278 }
279 }
280
281 #[inline]
282 fn nth(&mut self, n: usize) -> Option<Self::Item> {
283 self.v = unsafe {
284 self.v.get_unchecked(
285 ..self
286 .v
287 .len()
288 .saturating_sub(n.saturating_mul(self.chunk_size.get())),
289 )
290 };
291 self.next()
292 }
293
294 #[inline]
295 fn size_hint(&self) -> (usize, Option<usize>) {
296 let len = self.len();
297 (len, Some(len))
298 }
299
300 #[inline]
301 fn count(self) -> usize {
302 self.len()
303 }
304
305 #[inline]
306 fn last(mut self) -> Option<Self::Item> {
307 self.next_back()
308 }
309}
310
311impl<'buf, T: VectorReadUnion<'buf>> core::iter::DoubleEndedIterator for RChunks<'buf, T> {
312 #[inline]
313 fn next_back(&mut self) -> Option<Self::Item> {
314 if self.v.is_empty() {
315 None
316 } else {
317 let mid = ((self.v.len() - 1) % self.chunk_size) + 1;
318 let (start, remaining) = unsafe { self.v.split_at_unchecked(mid) };
319 self.v = remaining;
320 Some(start)
321 }
322 }
323
324 #[inline]
325 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
326 if n > 0 {
327 let new_chunk_count = self.len().saturating_sub(n);
329 self.v = unsafe {
332 self.v
333 .get_unchecked(self.v.len() - (new_chunk_count * self.chunk_size.get())..)
334 };
335 }
336 self.next_back()
337 }
338}
339
340impl<'buf, T: VectorReadUnion<'buf>> core::iter::ExactSizeIterator for RChunks<'buf, T> {
341 #[inline]
342 fn len(&self) -> usize {
343 div_ceil(self.v.len(), self.chunk_size.get())
344 }
345}
346
347impl<'buf, T: VectorReadUnion<'buf>> core::iter::FusedIterator for RChunks<'buf, T> {}
348
349pub struct ChunksExact<'buf, T> {
361 v: UnionVector<'buf, T>,
362 rem: UnionVector<'buf, T>,
363 chunk_size: NonZeroUsize,
364}
365
366impl<'buf, T: VectorReadUnion<'buf> + core::fmt::Debug> core::fmt::Debug for ChunksExact<'buf, T> {
367 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
368 f.debug_struct("ChunksExact")
369 .field("v", &self.v)
370 .field("rem", &self.rem)
371 .field("chunk_size", &self.chunk_size)
372 .finish()
373 }
374}
375
376impl<T> Clone for ChunksExact<'_, T> {
377 #[inline]
378 fn clone(&self) -> Self {
379 Self {
380 v: self.v,
381 rem: self.rem,
382 chunk_size: self.chunk_size,
383 }
384 }
385}
386
387impl<'buf, T: VectorReadUnion<'buf>> ChunksExact<'buf, T> {
388 #[inline]
389 pub(crate) fn new(v: UnionVector<'buf, T>, chunk_size: NonZeroUsize) -> Self {
390 let len = v.len() / chunk_size.get() * chunk_size.get();
391 let (v, rem) = unsafe { v.split_at_unchecked(len) };
392 Self { v, rem, chunk_size }
393 }
394
395 #[inline]
399 #[must_use]
400 pub fn remainder(&self) -> UnionVector<'buf, T> {
401 self.rem
402 }
403}
404
405impl<'buf, T: VectorReadUnion<'buf>> Iterator for ChunksExact<'buf, T> {
406 type Item = UnionVector<'buf, T>;
407
408 #[inline]
409 fn next(&mut self) -> Option<UnionVector<'buf, T>> {
410 debug_assert!(self.v.len() % self.chunk_size == 0);
411 if self.v.is_empty() {
412 None
413 } else {
414 let (first, remaining) = unsafe { self.v.split_at_unchecked(self.chunk_size.get()) };
415 self.v = remaining;
416 Some(first)
417 }
418 }
419
420 #[inline]
421 fn nth(&mut self, n: usize) -> Option<Self::Item> {
422 let skip = n.saturating_mul(self.chunk_size.get());
423 self.v = self
424 .v
425 .get(skip..)
426 .unwrap_or_else(|| UnionVector::new_empty());
427 self.next()
428 }
429
430 #[inline]
431 fn size_hint(&self) -> (usize, Option<usize>) {
432 let len = self.len();
433 (len, Some(len))
434 }
435
436 #[inline]
437 fn count(self) -> usize {
438 self.len()
439 }
440
441 #[inline]
442 fn last(mut self) -> Option<Self::Item> {
443 self.next_back()
444 }
445}
446
447impl<'buf, T: VectorReadUnion<'buf>> core::iter::DoubleEndedIterator for ChunksExact<'buf, T> {
448 #[inline]
449 fn next_back(&mut self) -> Option<Self::Item> {
450 debug_assert!(self.v.len() % self.chunk_size == 0);
451 if self.v.is_empty() {
452 None
453 } else {
454 let (remaining, last) = unsafe {
455 self.v
456 .split_at_unchecked(self.v.len() - self.chunk_size.get())
457 };
458 self.v = remaining;
459 Some(last)
460 }
461 }
462
463 #[inline]
464 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
465 self.v = unsafe {
466 self.v.get_unchecked(
467 ..self
468 .v
469 .len()
470 .saturating_sub(n.saturating_mul(self.chunk_size.get())),
471 )
472 };
473 self.next_back()
474 }
475}
476
477impl<'buf, T: VectorReadUnion<'buf>> core::iter::ExactSizeIterator for ChunksExact<'buf, T> {
478 #[inline]
479 fn len(&self) -> usize {
480 self.v.len() / self.chunk_size
481 }
482}
483
484impl<'buf, T: VectorReadUnion<'buf>> core::iter::FusedIterator for ChunksExact<'buf, T> {}
485
486pub struct RChunksExact<'buf, T> {
498 v: UnionVector<'buf, T>,
499 rem: UnionVector<'buf, T>,
500 chunk_size: NonZeroUsize,
501}
502
503impl<'buf, T: VectorReadUnion<'buf> + core::fmt::Debug> core::fmt::Debug for RChunksExact<'buf, T> {
504 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
505 f.debug_struct("RChunksExact")
506 .field("v", &self.v)
507 .field("rem", &self.rem)
508 .field("chunk_size", &self.chunk_size)
509 .finish()
510 }
511}
512
513impl<T> Clone for RChunksExact<'_, T> {
514 #[inline]
515 fn clone(&self) -> Self {
516 Self {
517 v: self.v,
518 rem: self.rem,
519 chunk_size: self.chunk_size,
520 }
521 }
522}
523
524impl<'buf, T: VectorReadUnion<'buf>> RChunksExact<'buf, T> {
525 #[inline]
526 pub(crate) fn new(v: UnionVector<'buf, T>, chunk_size: NonZeroUsize) -> Self {
527 let rem_size = v.len() % chunk_size;
528 let (rem, v) = unsafe { v.split_at_unchecked(rem_size) };
529 Self { v, rem, chunk_size }
530 }
531
532 #[inline]
536 #[must_use]
537 pub fn remainder(&self) -> UnionVector<'buf, T> {
538 self.rem
539 }
540}
541
542impl<'buf, T: VectorReadUnion<'buf>> Iterator for RChunksExact<'buf, T> {
543 type Item = UnionVector<'buf, T>;
544
545 #[inline]
546 fn next(&mut self) -> Option<UnionVector<'buf, T>> {
547 debug_assert!(self.v.len() % self.chunk_size == 0);
548 if self.v.is_empty() {
549 None
550 } else {
551 let (remaining, last) = unsafe {
552 self.v
553 .split_at_unchecked(self.v.len() - self.chunk_size.get())
554 };
555 self.v = remaining;
556 Some(last)
557 }
558 }
559
560 #[inline]
561 fn nth(&mut self, n: usize) -> Option<Self::Item> {
562 self.v = unsafe {
563 self.v.get_unchecked(
564 ..self
565 .v
566 .len()
567 .saturating_sub(n.saturating_mul(self.chunk_size.get())),
568 )
569 };
570 self.next()
571 }
572
573 #[inline]
574 fn size_hint(&self) -> (usize, Option<usize>) {
575 let len = self.len();
576 (len, Some(len))
577 }
578
579 #[inline]
580 fn count(self) -> usize {
581 self.len()
582 }
583
584 #[inline]
585 fn last(mut self) -> Option<Self::Item> {
586 self.next_back()
587 }
588}
589
590impl<'buf, T: VectorReadUnion<'buf>> core::iter::DoubleEndedIterator for RChunksExact<'buf, T> {
591 #[inline]
592 fn next_back(&mut self) -> Option<Self::Item> {
593 debug_assert!(self.v.len() % self.chunk_size == 0);
594 if self.v.is_empty() {
595 None
596 } else {
597 let (first, remaining) = unsafe { self.v.split_at_unchecked(self.chunk_size.get()) };
598 self.v = remaining;
599 Some(first)
600 }
601 }
602
603 #[inline]
604 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
605 let skip = n.saturating_mul(self.chunk_size.get());
606 self.v = self
607 .v
608 .get(skip..)
609 .unwrap_or_else(|| UnionVector::new_empty());
610 self.next_back()
611 }
612}
613
614impl<'buf, T: VectorReadUnion<'buf>> core::iter::ExactSizeIterator for RChunksExact<'buf, T> {
615 #[inline]
616 fn len(&self) -> usize {
617 self.v.len() / self.chunk_size
618 }
619}
620
621impl<'buf, T: VectorReadUnion<'buf>> core::iter::FusedIterator for RChunksExact<'buf, T> {}
622
623pub struct Windows<'buf, T> {
629 v: UnionVector<'buf, T>,
630 size: NonZeroUsize,
631}
632
633impl<'buf, T: VectorReadUnion<'buf> + core::fmt::Debug> core::fmt::Debug for Windows<'buf, T> {
634 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
635 f.debug_struct("Windows")
636 .field("v", &self.v)
637 .field("size", &self.size)
638 .finish()
639 }
640}
641
642impl<T> Clone for Windows<'_, T> {
643 #[inline]
644 fn clone(&self) -> Self {
645 Self {
646 v: self.v,
647 size: self.size,
648 }
649 }
650}
651
652impl<'buf, T: VectorReadUnion<'buf>> Windows<'buf, T> {
653 #[inline]
654 pub(crate) fn new(v: UnionVector<'buf, T>, size: NonZeroUsize) -> Self {
655 Self { v, size }
656 }
657}
658
659impl<'buf, T: VectorReadUnion<'buf>> Iterator for Windows<'buf, T> {
660 type Item = UnionVector<'buf, T>;
661
662 #[inline]
663 fn next(&mut self) -> Option<UnionVector<'buf, T>> {
664 let window = self.v.get(..self.size.get())?;
665 self.v = unsafe { self.v.get_unchecked(1..) };
666 Some(window)
667 }
668
669 #[inline]
670 fn nth(&mut self, n: usize) -> Option<Self::Item> {
671 self.v = self.v.get(n..).unwrap_or_else(|| UnionVector::new_empty());
672 self.next()
673 }
674
675 #[inline]
676 fn size_hint(&self) -> (usize, Option<usize>) {
677 let len = self.len();
678 (len, Some(len))
679 }
680
681 #[inline]
682 fn count(self) -> usize {
683 self.len()
684 }
685
686 #[inline]
687 fn last(mut self) -> Option<Self::Item> {
688 self.next_back()
689 }
690}
691
692impl<'buf, T: VectorReadUnion<'buf>> core::iter::DoubleEndedIterator for Windows<'buf, T> {
693 #[inline]
694 fn next_back(&mut self) -> Option<Self::Item> {
695 let index = self.v.len().checked_sub(self.size.get())?;
696 let window = unsafe { self.v.get_unchecked(index..) };
697 self.v = unsafe { self.v.get_unchecked(..self.v.len() - 1) };
698 Some(window)
699 }
700
701 #[inline]
702 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
703 self.v = unsafe { self.v.get_unchecked(..self.v.len().saturating_sub(n)) };
704 self.next_back()
705 }
706}
707
708impl<'buf, T: VectorReadUnion<'buf>> core::iter::ExactSizeIterator for Windows<'buf, T> {
709 #[inline]
710 fn len(&self) -> usize {
711 self.v.len().saturating_sub(self.size.get() - 1)
712 }
713}
714
715impl<'buf, T: VectorReadUnion<'buf>> core::iter::FusedIterator for Windows<'buf, T> {}