my_ecs/ds/raw.rs
1use super::ptr::SendSyncPtr;
2use crate::util::macros::{
3 impl_into_iterator_for_parallel, impl_parallel_iterator, impl_unindexed_producer,
4};
5use rayon::iter::{plumbing::Producer, IntoParallelIterator};
6use std::{
7 iter,
8 marker::PhantomData,
9 num::NonZeroUsize,
10 ops::{Deref, DerefMut},
11 ptr::NonNull,
12 slice,
13};
14
15/// A trait to create type-erased iterators.
16///
17/// Type-erased iterator [`RawIter`] is commonly used in type-erased data
18/// containers. Also, the iterators can become parallel iterators that can be
19/// split over multiple CPU cores for parallel comuputing.
20pub trait AsRawIter {
21 /// Returns a new [`RawIter`].
22 ///
23 /// Give [`par_iter`](`AsRawIter::par_iter`) a try if you need CPU parallel
24 /// computing.
25 ///
26 /// # Examples
27 ///
28 /// ```
29 /// use my_ecs::{tinfo, ds::{AnyVec, AsRawIter}};
30 ///
31 /// // `AnyVec` implements `AsRawIter`.
32 /// let v = AnyVec::new(tinfo!(i32));
33 /// let iter = v.iter();
34 /// ```
35 fn iter(&self) -> RawIter;
36
37 /// Returns a new [`ParRawIter`].
38 ///
39 /// Unlike [`RawIter`], this iterator can be split over multiple CPU cores
40 /// then consumed at the same time for performance. But note that this is
41 /// not a silver bullet. It could be worse than sequential iterator
42 /// `RawIter` for a short iteration.
43 ///
44 /// # Examples
45 ///
46 /// ```
47 /// use my_ecs::{tinfo, ds::{AnyVec, AsRawIter}};
48 ///
49 /// // `AnyVec` implements `AsRawIter`.
50 /// let v = AnyVec::new(tinfo!(i32));
51 /// let iter = v.par_iter();
52 /// ```
53 #[inline]
54 fn par_iter(&self) -> ParRawIter {
55 ParRawIter(self.iter())
56 }
57
58 /// Returns a new iterator.
59 ///
60 /// # Safety
61 ///
62 /// The given type `T` must be proper type.
63 ///
64 /// # Examples
65 ///
66 /// ```
67 /// use my_ecs::{tinfo, ds::{AnyVec, AsRawIter}};
68 ///
69 /// // `AnyVec` implements `AsRawIter`.
70 /// let mut v = AnyVec::new(tinfo!(i32));
71 /// unsafe {
72 /// v.push(0_i32);
73 /// v.push(1_i32);
74 /// }
75 /// for v in unsafe { AsRawIter::iter_of::<i32>(&v) } {
76 /// println!("{v}");
77 /// }
78 /// ```
79 #[inline]
80 unsafe fn iter_of<T>(&self) -> Iter<'_, T> {
81 unsafe { Iter::new(self) }
82 }
83
84 /// Returns a new mutable iterator.
85 ///
86 /// # Safety
87 ///
88 /// The given type `T` must be proper type.
89 ///
90 /// # Examples
91 ///
92 /// ```
93 /// use my_ecs::{tinfo, ds::{AnyVec, AsRawIter}};
94 ///
95 /// // `AnyVec` implements `AsRawIter`.
96 /// let mut v = AnyVec::new(tinfo!(i32));
97 /// unsafe {
98 /// v.push(0_i32);
99 /// v.push(1_i32);
100 /// }
101 /// for v in unsafe { AsRawIter::iter_mut_of::<i32>(&mut v) } {
102 /// *v += 1;
103 /// println!("{v}");
104 /// }
105 /// ```
106 #[inline]
107 unsafe fn iter_mut_of<T>(&mut self) -> IterMut<'_, T> {
108 unsafe { IterMut::new(self) }
109 }
110
111 /// Returns a new parallel iterator.
112 ///
113 /// # Safety
114 ///
115 /// The given type `T` must be proper type.
116 ///
117 /// # Examples
118 ///
119 /// ```
120 /// use my_ecs::{tinfo, ds::{AnyVec, AsRawIter}};
121 ///
122 /// // `AnyVec` implements `AsRawIter`.
123 /// let mut v = AnyVec::new(tinfo!(i32));
124 /// unsafe {
125 /// v.push(0_i32);
126 /// v.push(1_i32);
127 /// }
128 /// for v in unsafe { AsRawIter::par_iter_of::<i32>(&v) } {
129 /// println!("{v}");
130 /// }
131 /// ```
132 #[inline]
133 unsafe fn par_iter_of<T>(&self) -> ParIter<'_, T> {
134 unsafe { ParIter::new(self) }
135 }
136
137 /// Returns a new parallel mutable iterator.
138 ///
139 /// # Safety
140 ///
141 /// The given type `T` must be proper type.
142 ///
143 /// # Examples
144 ///
145 /// ```
146 /// use my_ecs::{tinfo, ds::{AnyVec, AsRawIter}};
147 ///
148 /// // `AnyVec` implements `AsRawIter`.
149 /// let mut v = AnyVec::new(tinfo!(i32));
150 /// unsafe {
151 /// v.push(0_i32);
152 /// v.push(1_i32);
153 /// }
154 /// for v in unsafe { AsRawIter::par_iter_mut_of::<i32>(&mut v) } {
155 /// *v += 1;
156 /// println!("{v}");
157 /// }
158 /// ```
159 #[inline]
160 unsafe fn par_iter_mut_of<T>(&mut self) -> ParIterMut<'_, T> {
161 ParIterMut::new(self)
162 }
163}
164
165impl<T> AsRawIter for [T] {
166 fn iter(&self) -> RawIter {
167 let ptr = self.as_ptr();
168 let len = self.len();
169 unsafe {
170 // Safety: Infallible.
171 let ptr = NonNull::new_unchecked(ptr.cast_mut());
172
173 // Safety: Alignment must be at least 1.
174 let stride = NonZeroUsize::new_unchecked(size_of::<T>().max(align_of::<T>()));
175
176 // Safety: slice guarantees.
177 RawIter::new(ptr.cast(), len, stride)
178 }
179 }
180}
181
182/// A trait to create type-erased flatten iterators from nested types such as
183/// `Vec<Vec<T>>`.
184///
185/// Type-erased iterator [`FlatRawIter`] is commonly used in type-erased data
186/// containers. Also, the iterators can become parallel iterators that can be
187/// split over mupltiple CPU cores for parallel computing.
188pub trait AsFlatRawIter {
189 /// Returns a new [`FlatRawIter`].
190 ///
191 /// # Safety
192 ///
193 /// - The created iterator's lifetime must rely on the `&self`.
194 ///
195 /// # Examples
196 ///
197 /// ```
198 /// use my_ecs::{tinfo, ds::{ChunkAnyVec, AsFlatRawIter}};
199 ///
200 /// // `ChunkAnyVec` implements `AsFlatRawIter`.
201 /// let chunk_cap = 2;
202 /// let v = ChunkAnyVec::new(tinfo!(i32), chunk_cap);
203 /// let iter = unsafe { v.iter() };
204 /// ```
205 //
206 // Unlike `AsRawIter::iter`, this method need the container to be accessible
207 // even if the iterator yields poniters. That's why this method is unsafe.
208 unsafe fn iter(&self) -> FlatRawIter;
209
210 /// Returns a new [`ParFlatRawIter`].
211 ///
212 /// # Safety
213 ///
214 /// - The created iterator's lifetime must rely on the `&self`.
215 ///
216 /// # Examples
217 ///
218 /// ```
219 /// use my_ecs::{tinfo, ds::{ChunkAnyVec, AsFlatRawIter}};
220 ///
221 /// // `ChunkAnyVec` implements `AsFlatRawIter`.
222 /// let chunk_cap = 2;
223 /// let v = ChunkAnyVec::new(tinfo!(i32), chunk_cap);
224 /// let iter = unsafe { v.par_iter() };
225 /// ```
226 //
227 // Unlike `AsRawIter::par_iter`, this method need the container to be
228 // accessible even if the iterator yields poniters. That's why this method
229 // is unsafe.
230 unsafe fn par_iter(&self) -> ParFlatRawIter {
231 ParFlatRawIter(self.iter())
232 }
233
234 /// Returns a new iterator.
235 ///
236 /// # Safety
237 ///
238 /// The given type `T` must be proper type.
239 ///
240 /// # Examples
241 ///
242 /// ```
243 /// use my_ecs::{tinfo, ds::{ChunkAnyVec, AsFlatRawIter}};
244 ///
245 /// // `ChunkAnyVec` implements `AsFlatRawIter`.
246 /// let chunk_cap = 2;
247 /// let mut v = ChunkAnyVec::new(tinfo!(i32), chunk_cap);
248 /// unsafe {
249 /// v.push(0_i32);
250 /// v.push(1_i32);
251 /// }
252 /// for v in unsafe { AsFlatRawIter::iter_of::<i32>(&v) } {
253 /// println!("{v}");
254 /// }
255 /// ```
256 #[inline]
257 unsafe fn iter_of<T>(&self) -> FlatIter<'_, T> {
258 FlatIter::new(self)
259 }
260
261 /// Returns a new mutable iterator.
262 ///
263 /// # Safety
264 ///
265 /// The given type `T` must be proper type.
266 ///
267 /// # Examples
268 ///
269 /// ```
270 /// use my_ecs::{tinfo, ds::{ChunkAnyVec, AsFlatRawIter}};
271 ///
272 /// // `ChunkAnyVec` implements `AsFlatRawIter`.
273 /// let chunk_cap = 2;
274 /// let mut v = ChunkAnyVec::new(tinfo!(i32), chunk_cap);
275 /// unsafe {
276 /// v.push(0_i32);
277 /// v.push(1_i32);
278 /// }
279 /// for v in unsafe { AsFlatRawIter::iter_mut_of::<i32>(&mut v) } {
280 /// *v += 1;
281 /// println!("{v}");
282 /// }
283 /// ```
284 #[inline]
285 unsafe fn iter_mut_of<T>(&mut self) -> FlatIterMut<'_, T> {
286 FlatIterMut::new(self)
287 }
288
289 /// Returns a new parallel iterator.
290 ///
291 /// # Safety
292 ///
293 /// The given type `T` must be proper type.
294 ///
295 /// # Examples
296 ///
297 /// ```
298 /// use my_ecs::{tinfo, ds::{ChunkAnyVec, AsFlatRawIter}};
299 ///
300 /// // `ChunkAnyVec` implements `AsFlatRawIter`.
301 /// let chunk_cap = 2;
302 /// let mut v = ChunkAnyVec::new(tinfo!(i32), chunk_cap);
303 /// unsafe {
304 /// v.push(0_i32);
305 /// v.push(1_i32);
306 /// }
307 /// for v in unsafe { AsFlatRawIter::par_iter_of::<i32>(&v) } {
308 /// println!("{v}");
309 /// }
310 /// ```
311 #[inline]
312 unsafe fn par_iter_of<T>(&self) -> ParFlatIter<'_, T> {
313 ParFlatIter(self.iter_of())
314 }
315
316 /// Returns a new parallel mutable iterator.
317 ///
318 /// # Safety
319 ///
320 /// The given type `T` must be proper type.
321 ///
322 /// # Examples
323 ///
324 /// ```
325 /// use my_ecs::{tinfo, ds::{ChunkAnyVec, AsFlatRawIter}};
326 ///
327 /// // `ChunkAnyVec` implements `AsFlatRawIter`.
328 /// let chunk_cap = 2;
329 /// let mut v = ChunkAnyVec::new(tinfo!(i32), chunk_cap);
330 /// unsafe {
331 /// v.push(0_i32);
332 /// v.push(1_i32);
333 /// }
334 /// for v in unsafe { AsFlatRawIter::par_iter_mut_of::<i32>(&mut v) } {
335 /// *v += 1;
336 /// println!("{v}");
337 /// }
338 /// ```
339 #[inline]
340 unsafe fn par_iter_mut_of<T>(&mut self) -> ParFlatIterMut<'_, T> {
341 ParFlatIterMut(self.iter_mut_of())
342 }
343}
344
345/// A type-erased iterator of a slice.
346///
347/// This iterator yields type-erased raw pointer instead of concrete type. If
348/// you can, wrap this iterator in [`Iter`] which bounds concrete type and
349/// lifetime.
350///
351/// # Safety
352///
353/// The iterator includes raw pointers, but it implements [`Send`] ans [`Sync`].
354/// You must carefully send this iterator to another worker.
355#[derive(Debug, Clone, Copy)]
356pub struct RawIter {
357 cur: SendSyncPtr<u8>,
358 end: SendSyncPtr<u8>,
359 stride: NonZeroUsize,
360}
361
362impl RawIter {
363 /// Creates a new [`RawIter`] from start address, number of items, and
364 /// stride in bytes.
365 ///
366 /// # Safety
367 ///
368 /// `ptr + len * stride` must not exceed [`isize::MAX`].
369 ///
370 /// # Examples
371 ///
372 /// ```
373 /// use my_ecs::ds::RawIter;
374 /// use std::{ptr::NonNull, num::NonZeroUsize};
375 ///
376 /// let arr = [0, 1, 2];
377 /// let ptr = NonNull::new(arr.as_ptr().cast_mut()).unwrap();
378 /// let stride = NonZeroUsize::new(4).unwrap();
379 /// let iter = unsafe { RawIter::new(ptr.cast(), arr.len(), stride) };
380 /// ```
381 #[inline]
382 pub unsafe fn new(ptr: NonNull<u8>, len: usize, stride: NonZeroUsize) -> Self {
383 unsafe {
384 let end = ptr.add(len * stride.get());
385 Self::from_range(ptr, end, stride)
386 }
387 }
388
389 /// Creates a new [`RawIter`] from start address, end address, and stride
390 /// in bytes.
391 ///
392 /// # Safety
393 ///
394 /// - `start` address must be less than or equal to `end` address.
395 /// - `end` address must not exceed [`isize::MAX`].
396 /// - `end` address must be able to devided by `stride`.
397 ///
398 /// # Examples
399 ///
400 /// ```
401 /// use my_ecs::ds::RawIter;
402 /// use std::{ptr::NonNull, num::NonZeroUsize};
403 ///
404 /// let arr = [0, 1, 2];
405 /// let range = arr.as_ptr_range();
406 /// let start = NonNull::new(range.start.cast_mut()).unwrap();
407 /// let end = NonNull::new(range.end.cast_mut()).unwrap();
408 /// let stride = NonZeroUsize::new(4).unwrap();
409 /// let iter = unsafe { RawIter::from_range(start.cast(), end.cast(), stride) };
410 /// ```
411 #[inline]
412 pub unsafe fn from_range(start: NonNull<u8>, end: NonNull<u8>, stride: NonZeroUsize) -> Self {
413 debug_assert!(start <= end);
414 debug_assert!(end.as_ptr() as usize <= isize::MAX as usize);
415 debug_assert_eq!(
416 (end.as_ptr() as usize - start.as_ptr() as usize) % stride,
417 0
418 );
419
420 Self {
421 cur: SendSyncPtr::new(start),
422 end: SendSyncPtr::new(end),
423 stride,
424 }
425 }
426
427 /// Creates an empty [`RawIter`].
428 ///
429 /// # Examples
430 ///
431 /// ```
432 /// use my_ecs::ds::RawIter;
433 ///
434 /// let empty_iter = RawIter::empty();
435 /// ```
436 pub const fn empty() -> Self {
437 Self {
438 cur: SendSyncPtr::dangling(),
439 end: SendSyncPtr::dangling(),
440 stride: NonZeroUsize::MIN,
441 }
442 }
443
444 /// Returns number of remaining items the iterator can visit.
445 ///
446 /// # Examples
447 ///
448 /// ```
449 /// use my_ecs::ds::RawIter;
450 /// use std::{ptr::NonNull, num::NonZeroUsize};
451 ///
452 /// let arr = [0, 1, 2];
453 /// let ptr = NonNull::new(arr.as_ptr().cast_mut()).unwrap();
454 /// let stride = NonZeroUsize::new(4).unwrap();
455 /// let iter = unsafe { RawIter::new(ptr.cast(), arr.len(), stride) };
456 /// assert_eq!(iter.len(), 3);
457 /// ```
458 #[inline]
459 pub const fn len(&self) -> usize {
460 let end = self.end.as_ptr();
461 let cur = self.cur.as_ptr();
462 // Safety: Owners guarantee safety.
463 unsafe { end.offset_from(cur) as usize / self.stride.get() }
464 }
465
466 /// Returns true if the iterator has consumed completely so that it cannot
467 /// yield anything.
468 ///
469 /// # Examples
470 ///
471 /// ```
472 /// use my_ecs::ds::RawIter;
473 /// use std::{ptr::NonNull, num::NonZeroUsize};
474 ///
475 /// let arr: [i32; 0] = [];
476 /// let ptr = NonNull::new(arr.as_ptr().cast_mut()).unwrap();
477 /// let stride = NonZeroUsize::new(4).unwrap();
478 /// let mut iter = unsafe { RawIter::new(ptr.cast(), arr.len(), stride) };
479 /// assert!(iter.is_empty());
480 /// ```
481 #[inline]
482 pub const fn is_empty(&self) -> bool {
483 self.len() == 0
484 }
485
486 /// Returns a slice from the remaining iterator.
487 ///
488 /// # Safety
489 ///
490 /// - Caller must provide correct type `T` for the iterator.
491 /// - Lifetime define by caller must be sufficient to the iterator.
492 pub unsafe fn as_slice<'o, T>(&self) -> &'o [T] {
493 // We need properly aligned pointer for the type `T`, not `u8`.
494 let ptr = if self.cur.is_dangling() {
495 NonNull::<T>::dangling().as_ptr().cast_const()
496 } else {
497 self.cur.as_ptr().cast::<T>().cast_const()
498 };
499 slice::from_raw_parts(ptr, self.len())
500 }
501
502 /// Returns a mutable slice from the remaining iterator.
503 ///
504 /// # Safety
505 ///
506 /// - Caller must provide correct type `T` for the iterator.
507 /// - Lifetime define by caller must be sufficient to the iterator.
508 pub unsafe fn as_mut_slice<'o, T>(&mut self) -> &'o mut [T] {
509 // We need properly aligned pointer for the type `T`, not `u8`.
510 let ptr = if self.cur.is_dangling() {
511 NonNull::<T>::dangling().as_ptr()
512 } else {
513 self.cur.as_ptr().cast::<T>()
514 };
515 slice::from_raw_parts_mut(ptr, self.len())
516 }
517}
518
519impl Iterator for RawIter {
520 type Item = SendSyncPtr<u8>;
521
522 #[inline]
523 fn next(&mut self) -> Option<Self::Item> {
524 if self.cur < self.end {
525 let res = self.cur;
526 // Safety: Owners guarantee safety.
527 self.cur = unsafe { self.cur.add(self.stride.get()) };
528 Some(res)
529 } else {
530 None
531 }
532 }
533
534 #[inline]
535 fn size_hint(&self) -> (usize, Option<usize>) {
536 let len = Self::len(self);
537 (len, Some(len))
538 }
539}
540
541impl iter::FusedIterator for RawIter {}
542
543impl ExactSizeIterator for RawIter {
544 #[inline]
545 fn len(&self) -> usize {
546 Self::len(self)
547 }
548}
549
550impl DoubleEndedIterator for RawIter {
551 #[inline]
552 fn next_back(&mut self) -> Option<Self::Item> {
553 if self.cur < self.end {
554 // Safety: Owners guarantee safety.
555 self.end = unsafe { self.end.sub(self.stride.get()) };
556 Some(self.end)
557 } else {
558 None
559 }
560 }
561}
562
563/// A type-erased parallel iterator of a slice.
564///
565/// This is a new type of [`RawIter`]. [`Iterator`] and
566/// [`rayon::iter::ParallelIterator`] have the same signature methods, So
567/// clients have to write fully-qualified syntax to specify a method. This new
568/// type helps clients avoid it. If you don't want parallelism, just use
569/// [`RawIter`].
570#[derive(Debug, Clone, Copy)]
571#[repr(transparent)]
572pub struct ParRawIter(pub RawIter);
573
574impl ParRawIter {
575 /// Converts the parallel iterator into sequential iterator by unwrapping
576 /// self.
577 #[inline]
578 pub const fn into_seq(self) -> RawIter {
579 self.0
580 }
581
582 /// Returns remaining length of the iterator.
583 #[inline]
584 pub const fn len(&self) -> usize {
585 self.0.len()
586 }
587
588 /// Returns true if the iterator has consumed completely so that it cannot
589 /// yield anything.
590 #[inline]
591 pub const fn is_empty(&self) -> bool {
592 self.len() == 0
593 }
594}
595
596impl Deref for ParRawIter {
597 type Target = RawIter;
598
599 #[inline]
600 fn deref(&self) -> &Self::Target {
601 &self.0
602 }
603}
604
605impl DerefMut for ParRawIter {
606 #[inline]
607 fn deref_mut(&mut self) -> &mut Self::Target {
608 &mut self.0
609 }
610}
611
612impl Producer for ParRawIter {
613 type Item = SendSyncPtr<u8>;
614 type IntoIter = RawIter;
615
616 #[inline]
617 fn into_iter(self) -> Self::IntoIter {
618 self.into_seq()
619 }
620
621 #[inline]
622 fn split_at(self, index: usize) -> (Self, Self) {
623 let l_cur = self.cur;
624 let l_end = unsafe { self.cur.add(index * self.stride.get()) };
625 let r_cur = l_end;
626 let r_end = self.end;
627
628 // Safety: Splitting is safe.
629 let (l, r) = unsafe {
630 (
631 RawIter::from_range(l_cur.as_nonnull(), l_end.as_nonnull(), self.stride),
632 RawIter::from_range(r_cur.as_nonnull(), r_end.as_nonnull(), self.stride),
633 )
634 };
635 (ParRawIter(l), ParRawIter(r))
636 }
637}
638
639impl_into_iterator_for_parallel!(
640 "for" = ParRawIter; "to" = RawIter; "item" = SendSyncPtr<u8>;
641);
642impl_parallel_iterator!(
643 "for" = ParRawIter; "item" = SendSyncPtr<u8>;
644);
645impl_unindexed_producer!(
646 "for" = ParRawIter; "item" = SendSyncPtr<u8>;
647);
648
649/// An iterator that can be created from [`RawIter`] with concrete type and
650/// lifetime.
651///
652/// This iterator is useful when you have `RawIter` and know what type the
653/// iterator visits. You can create this iterator from the `RawIter` then use it
654/// like normal Rust iterators.
655#[derive(Debug, Clone)]
656#[repr(transparent)]
657pub struct Iter<'cont, T: 'cont> {
658 inner: RawIter,
659 _marker: PhantomData<&'cont T>,
660}
661
662impl<'cont, T> Iter<'cont, T> {
663 /// Borrows the given container then returns an iterator of the container.
664 ///
665 /// # Safety
666 ///
667 /// Given container must contain type `T` items.
668 ///
669 /// # Examples
670 ///
671 /// ```
672 /// use my_ecs::ds::Iter;
673 ///
674 /// let arr = &[1, 2, 3][..]; // [T] implements `AsRawIter`.
675 /// let iter = unsafe { Iter::<i32>::new(arr) };
676 /// ```
677 #[inline]
678 pub unsafe fn new<C>(cont: &'cont C) -> Self
679 where
680 C: AsRawIter + ?Sized,
681 {
682 // We're borrowing container, so lifetime is tied up.
683 unsafe { Self::from_raw(cont.iter()) }
684 }
685
686 /// Creates a new [`Iter`] from the given [`RawIter`].
687 ///
688 /// # Safety
689 ///
690 /// - The `RawIter` must yield pointers to type `T`.
691 /// - Lifetime defined by caller must be sufficient to the `RawIter`.
692 ///
693 /// # Examples
694 ///
695 /// ```
696 /// use my_ecs::ds::{RawIter, Iter};
697 /// use std::{ptr::NonNull, num::NonZeroUsize};
698 ///
699 /// let arr = [0, 1, 2];
700 /// let ptr = NonNull::new(arr.as_ptr().cast_mut()).unwrap();
701 /// let stride = NonZeroUsize::new(4).unwrap();
702 /// unsafe {
703 /// let raw_iter = RawIter::new(ptr.cast(), arr.len(), stride);
704 /// let iter = Iter::<i32>::from_raw(raw_iter);
705 /// }
706 /// ```
707 #[inline]
708 pub const unsafe fn from_raw(raw: RawIter) -> Self {
709 Self {
710 inner: raw,
711 _marker: PhantomData,
712 }
713 }
714
715 /// Returns number of remaining items the iterator can visit.
716 ///
717 /// # Examples
718 ///
719 /// ```
720 /// use my_ecs::ds::Iter;
721 ///
722 /// let arr = &[1, 2, 3][..]; // [T] implements `AsRawIter`.
723 /// let iter = unsafe { Iter::<i32>::new(arr) };
724 /// assert_eq!(iter.len(), 3);
725 /// ```
726 #[inline]
727 pub const fn len(&self) -> usize {
728 self.inner.len()
729 }
730
731 /// Returns true if the iterator has been consumed completely so that it
732 /// cannot yield anything.
733 ///
734 /// # Examples
735 ///
736 /// ```
737 /// use my_ecs::ds::Iter;
738 ///
739 /// let arr: &[i32] = &[][..]; // [T] implements `AsRawIter`.
740 /// let mut iter = unsafe { Iter::<i32>::new(arr) };
741 /// assert!(iter.is_empty());
742 /// ```
743 #[inline]
744 pub const fn is_empty(&self) -> bool {
745 self.len() == 0
746 }
747}
748
749impl<'cont, T> Iterator for Iter<'cont, T> {
750 type Item = &'cont T;
751
752 #[inline]
753 fn next(&mut self) -> Option<Self::Item> {
754 self.inner.next().map(|ptr| unsafe { ptr.cast().as_ref() })
755 }
756
757 #[inline]
758 fn size_hint(&self) -> (usize, Option<usize>) {
759 let len = Self::len(self);
760 (len, Some(len))
761 }
762}
763
764impl<T> iter::FusedIterator for Iter<'_, T> {}
765
766impl<T> ExactSizeIterator for Iter<'_, T> {
767 #[inline]
768 fn len(&self) -> usize {
769 Self::len(self)
770 }
771}
772
773impl<T> DoubleEndedIterator for Iter<'_, T> {
774 #[inline]
775 fn next_back(&mut self) -> Option<Self::Item> {
776 self.inner
777 .next_back()
778 .map(|ptr| unsafe { ptr.cast().as_ref() })
779 }
780}
781
782/// A mutable iterator that can be created from [`RawIter`] with concrete type
783/// and lifetime.
784///
785/// This iterator is useful when you have `RawIter` and know what type the
786/// iterator visits. You can create this iterator from the `RawIter` then use it
787/// like normal Rust iterators.
788#[derive(Debug)]
789#[repr(transparent)]
790pub struct IterMut<'cont, T: 'cont> {
791 inner: RawIter,
792 _marker: PhantomData<&'cont mut T>,
793}
794
795impl<'cont, T> IterMut<'cont, T> {
796 /// Borrows the given container then returns a mutable iterator of the
797 /// container.
798 ///
799 /// # Safety
800 ///
801 /// Given container must contain type `T` items.
802 ///
803 /// # Examples
804 ///
805 /// ```
806 /// use my_ecs::ds::IterMut;
807 ///
808 /// let arr = &mut [1, 2, 3][..]; // [T] implements `AsRawIter`.
809 /// let iter = unsafe { IterMut::<i32>::new(arr) };
810 /// ```
811 #[inline]
812 pub unsafe fn new<C>(cont: &'cont mut C) -> Self
813 where
814 C: AsRawIter + ?Sized,
815 {
816 // We're borrowing container, so lifetime is tied up.
817 unsafe { Self::from_raw(cont.iter()) }
818 }
819
820 /// Create a new [`IterMut`] from the given [`RawIter`].
821 ///
822 /// # Safety
823 ///
824 /// - The `RawIter` must yield pointers to type `T`.
825 /// - The `RawIter` must not be used elsewhere at the same time because
826 /// created iterator must be exclusive.
827 /// - Lifetime defined by caller must be sufficient to the `RawIter`.
828 ///
829 /// # Examples
830 ///
831 /// ```
832 /// use my_ecs::ds::{RawIter, IterMut};
833 /// use std::{ptr::NonNull, num::NonZeroUsize};
834 ///
835 /// let arr = [0, 1, 2];
836 /// let ptr = NonNull::new(arr.as_ptr().cast_mut()).unwrap();
837 /// let stride = NonZeroUsize::new(4).unwrap();
838 /// unsafe {
839 /// let raw_iter = RawIter::new(ptr.cast(), arr.len(), stride);
840 /// let iter = IterMut::<i32>::from_raw(raw_iter);
841 /// }
842 /// ```
843 #[inline]
844 pub unsafe fn from_raw(raw: RawIter) -> Self {
845 Self {
846 inner: raw,
847 _marker: PhantomData,
848 }
849 }
850
851 /// Returns number of remaining items the iterator can visit.
852 ///
853 /// # Examples
854 ///
855 /// ```
856 /// use my_ecs::ds::IterMut;
857 ///
858 /// let arr = &mut [1, 2, 3][..]; // [T] implements `AsRawIter`.
859 /// let iter = unsafe { IterMut::<i32>::new(arr) };
860 /// assert_eq!(iter.len(), 3);
861 /// ```
862 #[inline]
863 pub const fn len(&self) -> usize {
864 self.inner.len()
865 }
866
867 /// Returns true if the iterator has been consumed completely so that it
868 /// cannot yield anything.
869 ///
870 /// # Examples
871 ///
872 /// ```
873 /// use my_ecs::ds::IterMut;
874 ///
875 /// let arr: &mut [i32] = &mut [][..]; // [T] implements `AsRawIter`.
876 /// let mut iter = unsafe { IterMut::<i32>::new(arr) };
877 /// assert!(iter.is_empty());
878 /// ```
879 #[inline]
880 pub const fn is_empty(&self) -> bool {
881 self.len() == 0
882 }
883}
884
885impl<'cont, T> Iterator for IterMut<'cont, T> {
886 type Item = &'cont mut T;
887
888 #[inline]
889 fn next(&mut self) -> Option<Self::Item> {
890 self.inner.next().map(|ptr| unsafe { ptr.cast().as_mut() })
891 }
892
893 #[inline]
894 fn size_hint(&self) -> (usize, Option<usize>) {
895 let len = Self::len(self);
896 (len, Some(len))
897 }
898}
899
900impl<T> iter::FusedIterator for IterMut<'_, T> {}
901
902impl<T> ExactSizeIterator for IterMut<'_, T> {
903 #[inline]
904 fn len(&self) -> usize {
905 Self::len(self)
906 }
907}
908
909impl<T> DoubleEndedIterator for IterMut<'_, T> {
910 #[inline]
911 fn next_back(&mut self) -> Option<Self::Item> {
912 self.inner
913 .next_back()
914 .map(|ptr| unsafe { ptr.cast().as_mut() })
915 }
916}
917
918/// An iterator that can be created from [`ParRawIter`] with concrete type and
919/// lifetime.
920///
921/// This iterator is useful when you have `ParRawIter` and know what type the
922/// iterator visits. You can create this iterator from the `ParRawIter` then use
923/// it like normal Rust iterators.
924#[derive(Debug, Clone)]
925#[repr(transparent)]
926pub struct ParIter<'cont, T: 'cont> {
927 inner: ParRawIter,
928 _marker: PhantomData<&'cont T>,
929}
930
931impl<'cont, T> ParIter<'cont, T> {
932 /// Borrows the given container then returns an iterator of the container.
933 ///
934 /// # Safety
935 ///
936 /// Given container must contain type `T` items.
937 ///
938 /// # Examples
939 ///
940 /// ```
941 /// use my_ecs::ds::ParIter;
942 ///
943 /// let arr = &[1, 2, 3][..]; // [T] implements `AsRawIter`.
944 /// let iter = unsafe { ParIter::<i32>::new(arr) };
945 /// ```
946 #[inline]
947 pub unsafe fn new<C>(cont: &'cont C) -> Self
948 where
949 C: AsRawIter + ?Sized,
950 {
951 // We're borrowing container, so lifetime is tied up.
952 unsafe { Self::from_raw(cont.par_iter()) }
953 }
954
955 /// Creates a new [`ParIter`] from the given [`ParRawIter`].
956 ///
957 /// # Safety
958 ///
959 /// - The `ParRawIter` must yield pointers to type `T`.
960 /// - Lifetime defined by caller must be sufficient to the `ParRawIter`.
961 ///
962 /// # Examples
963 ///
964 /// ```
965 /// use my_ecs::ds::{RawIter, ParRawIter, ParIter};
966 /// use std::{ptr::NonNull, num::NonZeroUsize};
967 ///
968 /// let arr = [0, 1, 2];
969 /// let ptr = NonNull::new(arr.as_ptr().cast_mut()).unwrap();
970 /// let stride = NonZeroUsize::new(4).unwrap();
971 /// unsafe {
972 /// let raw_iter = RawIter::new(ptr.cast(), arr.len(), stride);
973 /// let par_raw_iter = ParRawIter(raw_iter);
974 /// let iter = ParIter::<i32>::from_raw(par_raw_iter);
975 /// }
976 /// ```
977 #[inline]
978 pub const unsafe fn from_raw(raw: ParRawIter) -> Self {
979 Self {
980 inner: raw,
981 _marker: PhantomData,
982 }
983 }
984
985 /// Converts the parallel iterator into sequential iterator.
986 ///
987 /// # Examples
988 ///
989 /// ```
990 /// use my_ecs::ds::ParIter;
991 ///
992 /// let arr = &[1, 2, 3][..]; // [T] implements `AsRawIter`.
993 /// let iter = unsafe { ParIter::<i32>::new(arr) };
994 /// let seq_iter = iter.into_seq();
995 /// ```
996 #[inline]
997 pub const fn into_seq(self) -> Iter<'cont, T> {
998 // Safety: Correct type and lifetime are given.
999 unsafe { Iter::from_raw(self.inner.into_seq()) }
1000 }
1001
1002 /// Returns number of remaining items the iterator can visit.
1003 ///
1004 /// # Examples
1005 ///
1006 /// ```
1007 /// use my_ecs::ds::ParIter;
1008 ///
1009 /// let arr = &[1, 2, 3][..]; // [T] implements `AsRawIter`.
1010 /// let iter = unsafe { ParIter::<i32>::new(arr) };
1011 /// assert_eq!(iter.len(), 3);
1012 /// ```
1013 #[inline]
1014 pub const fn len(&self) -> usize {
1015 self.inner.len()
1016 }
1017
1018 /// Returns true if the iterator has been consumed completely so that it
1019 /// cannot yield anything.
1020 ///
1021 /// # Examples
1022 ///
1023 /// ```
1024 /// use my_ecs::ds::ParIter;
1025 ///
1026 /// let arr: &[i32] = &[][..]; // [T] implements `AsRawIter`.
1027 /// let mut iter = unsafe { ParIter::<i32>::new(arr) };
1028 /// assert!(iter.is_empty());
1029 /// ```
1030 #[inline]
1031 pub const fn is_empty(&self) -> bool {
1032 self.len() == 0
1033 }
1034}
1035
1036impl<'cont, T: Send + Sync + 'cont> Producer for ParIter<'cont, T> {
1037 type Item = &'cont T;
1038 type IntoIter = Iter<'cont, T>;
1039
1040 #[inline]
1041 fn into_iter(self) -> Self::IntoIter {
1042 self.into_seq()
1043 }
1044
1045 #[inline]
1046 fn split_at(self, index: usize) -> (Self, Self) {
1047 let (l, r) = self.inner.split_at(index);
1048 unsafe { (Self::from_raw(l), Self::from_raw(r)) }
1049 }
1050}
1051
1052impl_into_iterator_for_parallel!(
1053 "lifetimes" = 'cont; "bounds" = T: {'cont};
1054 "for" = ParIter; "to" = Iter<'cont, T>; "item" = &'cont T;
1055);
1056impl_parallel_iterator!(
1057 "lifetimes" = 'cont; "bounds" = T: {Send + Sync + 'cont};
1058 "for" = ParIter; "item" = &'cont T;
1059);
1060impl_unindexed_producer!(
1061 "lifetimes" = 'cont; "bounds" = T: {Send + Sync + 'cont};
1062 "for" = ParIter; "item" = &'cont T;
1063);
1064
1065/// A mutable iterator that can be created from [`ParRawIter`] with concrete
1066/// type and lifetime.
1067///
1068/// This iterator is useful when you have `ParRawIter` and know what type the
1069/// iterator visits. You can create this iterator from the `ParRawIter` then use
1070/// it like normal Rust iterators.
1071#[derive(Debug)]
1072#[repr(transparent)]
1073pub struct ParIterMut<'cont, T: 'cont> {
1074 inner: ParRawIter,
1075 _marker: PhantomData<&'cont mut T>,
1076}
1077
1078impl<'cont, T> ParIterMut<'cont, T> {
1079 /// Borrows the given container then returns a mutable iterator of the
1080 /// container.
1081 ///
1082 /// # Safety
1083 ///
1084 /// Given container must contain type `T` items.
1085 ///
1086 /// # Examples
1087 ///
1088 /// ```
1089 /// use my_ecs::ds::ParIterMut;
1090 ///
1091 /// let arr = &mut [1, 2, 3][..]; // [T] implements `AsRawIter`.
1092 /// let iter = unsafe { ParIterMut::<i32>::new(arr) };
1093 /// ```
1094 #[inline]
1095 pub fn new<C>(cont: &'cont mut C) -> Self
1096 where
1097 C: AsRawIter + ?Sized,
1098 {
1099 // We're borrowing container, so lifetime is tied up.
1100 unsafe { Self::from_raw(cont.par_iter()) }
1101 }
1102
1103 /// Creates a new [`ParIterMut`] from the given [`ParRawIter`].
1104 ///
1105 /// # Safety
1106 ///
1107 /// - The `ParRawIter` must yield pointers to type `T`.
1108 /// - The `ParRawIter` must not be used elsewhere at the same time because
1109 /// created iterator must be exclusive.
1110 /// - Lifetime defined by caller must be sufficient to the `ParRawIter`.
1111 ///
1112 /// # Examples
1113 ///
1114 /// ```
1115 /// use my_ecs::ds::{RawIter, ParRawIter, ParIterMut};
1116 /// use std::{ptr::NonNull, num::NonZeroUsize};
1117 ///
1118 /// let arr = [0, 1, 2];
1119 /// let ptr = NonNull::new(arr.as_ptr().cast_mut()).unwrap();
1120 /// let stride = NonZeroUsize::new(4).unwrap();
1121 /// unsafe {
1122 /// let raw_iter = RawIter::new(ptr.cast(), arr.len(), stride);
1123 /// let par_raw_iter = ParRawIter(raw_iter);
1124 /// let iter = ParIterMut::<i32>::from_raw(par_raw_iter);
1125 /// }
1126 /// ```
1127 #[inline]
1128 pub unsafe fn from_raw(raw: ParRawIter) -> Self {
1129 Self {
1130 inner: raw,
1131 _marker: PhantomData,
1132 }
1133 }
1134
1135 /// Converts the parallel iterator into sequential iterator.
1136 ///
1137 /// # Examples
1138 ///
1139 /// ```
1140 /// use my_ecs::ds::ParIterMut;
1141 ///
1142 /// let arr = &mut [1, 2, 3][..]; // [T] implements `AsRawIter`.
1143 /// let iter = unsafe { ParIterMut::<i32>::new(arr) };
1144 /// let seq_iter = iter.into_seq();
1145 /// ```
1146 #[inline]
1147 pub fn into_seq(self) -> IterMut<'cont, T> {
1148 // Safety: Correct type and lifetime are given.
1149 unsafe { IterMut::from_raw(self.inner.into_seq()) }
1150 }
1151
1152 /// Returns number of remaining items the iterator can visit.
1153 ///
1154 /// # Examples
1155 ///
1156 /// ```
1157 /// use my_ecs::ds::ParIterMut;
1158 ///
1159 /// let arr = &mut [1, 2, 3][..]; // [T] implements `AsRawIter`.
1160 /// let iter = unsafe { ParIterMut::<i32>::new(arr) };
1161 /// assert_eq!(iter.len(), 3);
1162 /// ```
1163 #[inline]
1164 pub const fn len(&self) -> usize {
1165 self.inner.len()
1166 }
1167
1168 /// Returns true if the iterator has been consumed completely so that it
1169 /// cannot yield anything.
1170 ///
1171 /// # Examples
1172 ///
1173 /// ```
1174 /// use my_ecs::ds::ParIterMut;
1175 ///
1176 /// let arr: &mut [i32] = &mut [][..]; // [T] implements `AsRawIter`.
1177 /// let mut iter = unsafe { ParIterMut::<i32>::new(arr) };
1178 /// assert!(iter.is_empty());
1179 /// ```
1180 #[inline]
1181 pub const fn is_empty(&self) -> bool {
1182 self.len() == 0
1183 }
1184}
1185
1186impl<'cont, T: Send + Sync + 'cont> Producer for ParIterMut<'cont, T> {
1187 type Item = &'cont mut T;
1188 type IntoIter = IterMut<'cont, T>;
1189
1190 #[inline]
1191 fn into_iter(self) -> Self::IntoIter {
1192 self.into_seq()
1193 }
1194
1195 #[inline]
1196 fn split_at(self, index: usize) -> (Self, Self) {
1197 let (l, r) = self.inner.split_at(index);
1198 (
1199 Self {
1200 inner: l,
1201 _marker: PhantomData,
1202 },
1203 Self {
1204 inner: r,
1205 _marker: PhantomData,
1206 },
1207 )
1208 }
1209}
1210
1211impl_into_iterator_for_parallel!(
1212 "lifetimes" = 'cont; "bounds" = T: {'cont};
1213 "for" = ParIterMut; "to" = IterMut<'cont, T>; "item" = &'cont mut T;
1214);
1215impl_parallel_iterator!(
1216 "lifetimes" = 'cont; "bounds" = T: {Send + Sync + 'cont};
1217 "for" = ParIterMut; "item" = &'cont mut T;
1218);
1219impl_unindexed_producer!(
1220 "lifetimes" = 'cont; "bounds" = T: {Send + Sync + 'cont};
1221 "for" = ParIterMut; "item" = &'cont mut T;
1222);
1223
1224/// A type-erased nested iterator.
1225///
1226/// This iterator is intended to be used by containers that has nested structure
1227/// like `Vec<Vec<T>>`. [`ChunkAnyVec`](crate::ds::ChunkAnyVec) is one of
1228/// containers that support this iterator. Plus, the iterator is using some
1229/// terminologies such as 'chunk' used in `ChunkAnyVec`, but you can think of it
1230/// as inner vector in `Vec<Vec<T>>`.
1231///
1232/// For better compiler optimization, the iterator is manually flattened, so it
1233/// is quite big in terms of size, but we can expect high iteration performance.
1234///
1235/// # Safety
1236///
1237/// The iterator includes raw pointers, but it implements [`Send`] ans [`Sync`].
1238/// You must carefully send this iterator to another worker.
1239//
1240// To implement rayon's ParallelIterator, we have to implement
1241// `ExactSizeIterator` and `DoubleEndedIterator`. So we track right side status
1242// and total number of items which are not needed for just `Iterator`.
1243#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1244pub struct FlatRawIter {
1245 /// Left [RawIter::cur].
1246 ///
1247 /// When [Iterator::next] is called, this pointer may be returned.
1248 pub(crate) ll: SendSyncPtr<u8>,
1249
1250 /// Left [RawIter::end], which is right boundary of the left iterator.
1251 ///
1252 /// Note that `end` is not included in the range. It's the next pointer of
1253 /// the right bound.
1254 pub(crate) lr: SendSyncPtr<u8>,
1255
1256 /// Right [RawIter::cur], which is left boundary of the right iterator.
1257 pub(crate) rl: SendSyncPtr<u8>,
1258
1259 /// Right [RawIter::end].
1260 ///
1261 /// When [DoubleEndedIterator::next_back] is called, the pointer before this
1262 /// may be returned. Note that `end` is not included in the range. It's the
1263 /// next pointer of the right bound.
1264 pub(crate) rr: SendSyncPtr<u8>,
1265
1266 /// Pointer to the actual container.
1267 pub(crate) this: SendSyncPtr<u8>,
1268
1269 /// Left chunk index for the next left [RawIter].
1270 ///
1271 /// This index always points to the next left iterator, not current one,
1272 /// and starts from 0.
1273 pub(crate) li: usize,
1274
1275 /// Right chunk index for the current right [RawIter].
1276 ///
1277 /// This index always points to the current right iterator, and starts from
1278 /// number of chunks.
1279 pub(crate) ri: usize,
1280
1281 /// Function that returns [`RawIter`] of a chunk for the given chunk index.
1282 ///
1283 /// If the chunk index is out of bounds, empty [`RawIter`] is returned.
1284 pub(crate) fn_iter: unsafe fn(this: NonNull<u8>, chunk_idx: usize) -> RawIter,
1285
1286 /// Function that returns [`RawIter`], chunk index, and offset from an item
1287 /// index.
1288 ///
1289 /// If the item index is out of bounds, empty [`RawIter`] is returned.
1290 pub(crate) fn_find: unsafe fn(this: NonNull<u8>, item_idx: usize) -> (RawIter, usize, usize),
1291
1292 /// Stride in bytes.
1293 pub(crate) stride: usize,
1294
1295 // used for parallel.
1296 pub(crate) off: usize,
1297
1298 /// Number of remaining items.
1299 pub(crate) len: usize,
1300}
1301
1302impl FlatRawIter {
1303 /// Creates a new [`FlatRawIter`] from raw parts.
1304 ///
1305 /// * this - A pointer to a container.
1306 /// * chunks - Number of chunks of the container.
1307 /// * fn_iter - A function that returns [`RawIter`] for a chunk index.
1308 /// * stride - Stride in bytes.
1309 /// * len - Total number of items.
1310 ///
1311 /// # Safety
1312 ///
1313 /// Caller must guarantee that the created iterator must have valid access
1314 /// to the given pointer while it is in use.
1315 #[inline]
1316 pub const unsafe fn new(
1317 this: NonNull<u8>,
1318 chunks: usize,
1319 fn_iter: unsafe fn(this: NonNull<u8>, chunk_idx: usize) -> RawIter,
1320 fn_find: unsafe fn(this: NonNull<u8>, item_idx: usize) -> (RawIter, usize, usize),
1321 stride: usize,
1322 len: usize,
1323 ) -> Self {
1324 Self {
1325 ll: SendSyncPtr::dangling(),
1326 lr: SendSyncPtr::dangling(),
1327 rl: SendSyncPtr::dangling(),
1328 rr: SendSyncPtr::dangling(),
1329 this: SendSyncPtr::new(this),
1330 li: 0,
1331 ri: chunks,
1332 fn_iter,
1333 fn_find,
1334 stride,
1335 off: 0,
1336 len,
1337 }
1338 }
1339
1340 /// Returns number of remaining items the iterator can visit.
1341 ///
1342 /// # Examples
1343 ///
1344 /// ```
1345 /// use my_ecs::{tinfo, ds::{ChunkAnyVec, FlatRawIter, AsFlatRawIter}};
1346 ///
1347 /// // `ChunkAnyVec` supports `FlatRawIter`.
1348 /// let chunk_cap = 2;
1349 /// let mut v = ChunkAnyVec::new(tinfo!(i32), chunk_cap);
1350 /// unsafe { v.push(0_i32 ) };
1351 ///
1352 /// let iter: FlatRawIter = unsafe { v.iter() };
1353 /// assert_eq!(iter.len(), 1);
1354 /// ```
1355 #[inline]
1356 pub const fn len(&self) -> usize {
1357 self.len
1358 }
1359
1360 /// Returns true if the iterator has consumed completely so that it cannot
1361 /// yield anything.
1362 ///
1363 /// # Examples
1364 ///
1365 /// ```
1366 /// use my_ecs::{tinfo, ds::{ChunkAnyVec, FlatRawIter, AsFlatRawIter}};
1367 ///
1368 /// // `ChunkAnyVec` supports `FlatRawIter`.
1369 /// let chunk_cap = 2;
1370 /// let mut v = ChunkAnyVec::new(tinfo!(i32), chunk_cap);
1371 ///
1372 /// let iter: FlatRawIter = unsafe { v.iter() };
1373 /// assert!(iter.is_empty());
1374 /// ```
1375 #[inline]
1376 pub const fn is_empty(&self) -> bool {
1377 self.len() == 0
1378 }
1379
1380 /// Returns a slice from the remaining iterator.
1381 ///
1382 /// # Safety
1383 ///
1384 /// - Caller must provide correct type `T` for the iterator.
1385 /// - Lifetime define by caller must be sufficient to the iterator.
1386 pub unsafe fn as_slice<'o, T>(&self, chunk_idx: usize) -> &'o [T] {
1387 // `fn_iter` gives us empty iterator if `chunk` is out of bounds.
1388 let raw_iter = unsafe { (self.fn_iter)(self.this.as_nonnull(), chunk_idx) };
1389 raw_iter.as_slice()
1390 }
1391
1392 /// Returns a mutable slice from the remaining iterator.
1393 ///
1394 /// # Safety
1395 ///
1396 /// - Caller must provide correct type `T` for the iterator.
1397 /// - Lifetime define by caller must be sufficient to the iterator.
1398 pub unsafe fn as_mut_slice<'o, T>(&mut self, chunk_idx: usize) -> &'o mut [T] {
1399 // `fn_iter` gives us empty iterator if `chunk` is out of bounds.
1400 let mut raw_iter = unsafe { (self.fn_iter)(self.this.as_nonnull(), chunk_idx) };
1401 raw_iter.as_mut_slice()
1402 }
1403
1404 /// Returns number of chunks if you've not been called
1405 /// [`next_back`](Self::next_back) on this iterator.
1406 pub(crate) fn num_chunks(&self) -> usize {
1407 self.ri
1408 }
1409}
1410
1411impl Iterator for FlatRawIter {
1412 type Item = SendSyncPtr<u8>;
1413
1414 #[inline]
1415 fn next(&mut self) -> Option<Self::Item> {
1416 if self.ll == self.lr {
1417 (self.ll, self.lr) = if self.li < self.ri {
1418 // Safety: Owners guarantee validity.
1419 let next = unsafe { (self.fn_iter)(self.this.as_nonnull(), self.li) };
1420 (next.cur, next.end)
1421 } else {
1422 (self.rl, self.rr)
1423 };
1424 if self.ll == self.lr {
1425 return None;
1426 }
1427 self.li += 1;
1428 }
1429
1430 let res = Some(self.ll);
1431 // Safety: Owners guarantee validity.
1432 self.ll = unsafe { self.ll.add(self.stride) };
1433 if self.li > self.ri {
1434 self.rl = self.ll;
1435 }
1436 self.len -= 1;
1437 res
1438 }
1439
1440 #[inline]
1441 fn size_hint(&self) -> (usize, Option<usize>) {
1442 let len = Self::len(self);
1443 (len, Some(len))
1444 }
1445}
1446
1447impl iter::FusedIterator for FlatRawIter {}
1448
1449impl ExactSizeIterator for FlatRawIter {
1450 #[inline]
1451 fn len(&self) -> usize {
1452 Self::len(self)
1453 }
1454}
1455
1456impl DoubleEndedIterator for FlatRawIter {
1457 #[inline]
1458 fn next_back(&mut self) -> Option<Self::Item> {
1459 if self.rl == self.rr {
1460 (self.rl, self.rr) = if self.li < self.ri {
1461 // Safety: Owners guarantee validity.
1462 let next = unsafe { (self.fn_iter)(self.this.as_nonnull(), self.ri - 1) };
1463 (next.cur, next.end)
1464 } else {
1465 (self.ll, self.lr)
1466 };
1467 if self.rl == self.rr {
1468 return None;
1469 }
1470 self.ri -= 1;
1471 }
1472
1473 // Safety: Owners guarantee validity.
1474 self.rr = unsafe { self.rr.sub(self.stride) };
1475 if self.li > self.ri {
1476 self.lr = self.rr;
1477 }
1478 self.len -= 1;
1479 Some(self.rr)
1480 }
1481}
1482
1483/// A type-erased parallel nested iterator.
1484///
1485/// This is a new type of [`FlatRawIter`]. [`Iterator`] and
1486/// [`rayon::iter::ParallelIterator`] have the same signature methods, So
1487/// clients have to write fully-qualified syntax to specify a method. This new
1488/// type helps clients avoid it. If you don't want parallelism, just use
1489/// [`FlatRawIter`].
1490#[derive(Debug, Clone, Copy)]
1491#[repr(transparent)]
1492pub struct ParFlatRawIter(pub FlatRawIter);
1493
1494impl ParFlatRawIter {
1495 /// Converts the parallel iterator into sequential iterator by unwrapping
1496 /// self.
1497 #[inline]
1498 pub const fn into_seq(self) -> FlatRawIter {
1499 self.0
1500 }
1501
1502 /// Returns remaining length of the iterator.
1503 #[inline]
1504 pub const fn len(&self) -> usize {
1505 self.0.len()
1506 }
1507
1508 /// Returns true if the iterator has consumed completely so that it cannot
1509 /// yield anything.
1510 #[inline]
1511 pub const fn is_empty(&self) -> bool {
1512 self.len() == 0
1513 }
1514}
1515
1516impl Deref for ParFlatRawIter {
1517 type Target = FlatRawIter;
1518
1519 #[inline]
1520 fn deref(&self) -> &Self::Target {
1521 &self.0
1522 }
1523}
1524
1525impl DerefMut for ParFlatRawIter {
1526 #[inline]
1527 fn deref_mut(&mut self) -> &mut Self::Target {
1528 &mut self.0
1529 }
1530}
1531
1532impl Producer for ParFlatRawIter {
1533 type Item = SendSyncPtr<u8>;
1534 type IntoIter = FlatRawIter;
1535
1536 #[inline]
1537 fn into_iter(self) -> Self::IntoIter {
1538 self.into_seq()
1539 }
1540
1541 #[inline]
1542 fn split_at(self, index: usize) -> (Self, Self) {
1543 let (
1544 RawIter {
1545 cur: ml, end: mr, ..
1546 },
1547 mi,
1548 off,
1549 ) = unsafe { (self.fn_find)(self.this.as_nonnull(), self.off + index) };
1550 let mm = unsafe { ml.add(off * self.stride) };
1551
1552 // Basic idea to split is something like so,
1553 //
1554 // Left-chunk Mid-chunk Right-chunk
1555 // li mi ri
1556 // [**********] .. [**********] .. [**********]
1557 // ^ ^ ^ ^ ^ ^ ^
1558 // ll lr ml mm mr rl rr
1559 // | | | || \ | |
1560 // [**********] .. [*****][*****] .. [**********]
1561 // |---- Left child -----||---- Right child ----|
1562 //
1563 // But, we must consider something like
1564 // - Imagine that mid-chunk is left chunk, but not split
1565 // as depicted below.
1566 //
1567 // ml mm mr
1568 // v v v
1569 // [********************]
1570 // [****]
1571 // ^ ^
1572 // ll lr
1573
1574 let is_left_chunk_cut = mi + 1 == self.li;
1575 let lchild = if !is_left_chunk_cut {
1576 FlatRawIter {
1577 ll: self.ll,
1578 lr: self.lr,
1579 rl: ml,
1580 rr: mm,
1581 this: self.this,
1582 li: self.li,
1583 ri: mi,
1584 fn_iter: self.fn_iter,
1585 fn_find: self.fn_find,
1586 stride: self.stride,
1587 off: self.off,
1588 len: index,
1589 }
1590 } else {
1591 FlatRawIter {
1592 ll: self.ll,
1593 lr: mm,
1594 rl: self.ll,
1595 rr: mm,
1596 this: self.this,
1597 li: mi + 1,
1598 ri: mi,
1599 fn_iter: self.fn_iter,
1600 fn_find: self.fn_find,
1601 stride: self.stride,
1602 off: self.off,
1603 len: index,
1604 }
1605 };
1606
1607 let is_right_chunk_cut = mi == self.ri;
1608 let rchild = if !is_right_chunk_cut {
1609 FlatRawIter {
1610 ll: mm,
1611 lr: mr,
1612 rl: self.rl,
1613 rr: self.rr,
1614 this: self.this,
1615 li: mi + 1,
1616 ri: self.ri,
1617 fn_iter: self.fn_iter,
1618 fn_find: self.fn_find,
1619 stride: self.stride,
1620 off: self.off + index,
1621 len: self.len - index,
1622 }
1623 } else {
1624 FlatRawIter {
1625 ll: mm,
1626 lr: self.rr,
1627 rl: mm,
1628 rr: self.rr,
1629 this: self.this,
1630 li: mi + 1,
1631 ri: mi,
1632 fn_iter: self.fn_iter,
1633 fn_find: self.fn_find,
1634 stride: self.stride,
1635 off: self.off + index,
1636 len: self.len - index,
1637 }
1638 };
1639
1640 (ParFlatRawIter(lchild), ParFlatRawIter(rchild))
1641 }
1642}
1643
1644impl_into_iterator_for_parallel!(
1645 "for" = ParFlatRawIter; "to" = FlatRawIter; "item" = SendSyncPtr<u8>;
1646);
1647impl_parallel_iterator!(
1648 "for" = ParFlatRawIter; "item" = SendSyncPtr<u8>;
1649);
1650impl_unindexed_producer!(
1651 "for" = ParFlatRawIter; "item" = SendSyncPtr<u8>;
1652);
1653
1654/// An iterator that can be created from [`FlatRawIter`] with concrete type and
1655/// lifetime.
1656///
1657/// This iterator is useful when you have `FlatRawIter` and know what type the
1658/// iterator visits. You can create this iterator from the `FlatRawIter` then
1659/// use it like normal Rust iterators.
1660#[derive(Debug, Clone)]
1661#[repr(transparent)]
1662pub struct FlatIter<'cont, T: 'cont> {
1663 inner: FlatRawIter,
1664 _marker: PhantomData<&'cont T>,
1665}
1666
1667impl<'cont, T> FlatIter<'cont, T> {
1668 /// Borrows the given container then returns an iterator of the container.
1669 ///
1670 /// # Safety
1671 ///
1672 /// Given container must contain type `T` items.
1673 ///
1674 /// # Examples
1675 ///
1676 /// ```
1677 /// use my_ecs::{tinfo, ds::{ChunkAnyVec, FlatIter}};
1678 ///
1679 /// // `ChunkAnyVec` implements `AsFlatRawIter`.
1680 /// let chunk_cap = 2;
1681 /// let v = ChunkAnyVec::new(tinfo!(i32), chunk_cap);
1682 /// let iter = FlatIter::<i32>::new(&v);
1683 /// ```
1684 #[inline]
1685 pub fn new<C>(cont: &'cont C) -> Self
1686 where
1687 C: AsFlatRawIter + ?Sized,
1688 {
1689 // We're borrowing container, so lifetime is tied up.
1690 unsafe { Self::from_raw(cont.iter()) }
1691 }
1692
1693 /// Creates a new [`FlatIter`] from the given [`FlatRawIter`].
1694 ///
1695 /// # Safety
1696 ///
1697 /// - The `FlatRawIter` must yield pointers to type `T`.
1698 /// - Lifetime defined by caller must be sufficient to the `FlatRawIter`.
1699 ///
1700 /// # Examples
1701 ///
1702 /// ```
1703 /// use my_ecs::{tinfo, ds::{ChunkAnyVec, AsFlatRawIter, FlatIter}};
1704 ///
1705 /// // `ChunkAnyVec` implements `AsFlatRawIter`.
1706 /// let chunk_cap = 2;
1707 /// let v = ChunkAnyVec::new(tinfo!(i32), chunk_cap);
1708 /// unsafe {
1709 /// let raw_iter = v.iter();
1710 /// let iter = FlatIter::<i32>::from_raw(raw_iter);
1711 /// }
1712 /// ```
1713 #[inline]
1714 pub const unsafe fn from_raw(raw: FlatRawIter) -> Self {
1715 Self {
1716 inner: raw,
1717 _marker: PhantomData,
1718 }
1719 }
1720
1721 /// Returns number of remaining items the iterator can visit.
1722 ///
1723 /// # Examples
1724 ///
1725 /// ```
1726 /// use my_ecs::{tinfo, ds::{ChunkAnyVec, FlatIter}};
1727 ///
1728 /// // `ChunkAnyVec` implements `AsFlatRawIter`.
1729 /// let chunk_cap = 2;
1730 /// let mut v = ChunkAnyVec::new(tinfo!(i32), chunk_cap);
1731 /// unsafe { v.push(0_i32) };
1732 ///
1733 /// let iter = FlatIter::<i32>::new(&v);
1734 /// assert_eq!(iter.len(), 1);
1735 /// ```
1736 #[inline]
1737 pub const fn len(&self) -> usize {
1738 self.inner.len()
1739 }
1740
1741 /// Returns true if the iterator has been consumed completely so that it
1742 /// cannot yield anything.
1743 ///
1744 /// # Examples
1745 ///
1746 /// ```
1747 /// use my_ecs::{tinfo, ds::{ChunkAnyVec, FlatIter}};
1748 ///
1749 /// // `ChunkAnyVec` implements `AsFlatRawIter`.
1750 /// let chunk_cap = 2;
1751 /// let v = ChunkAnyVec::new(tinfo!(i32), chunk_cap);
1752 ///
1753 /// let iter = FlatIter::<i32>::new(&v);
1754 /// assert!(iter.is_empty());
1755 /// ```
1756 #[inline]
1757 pub const fn is_empty(&self) -> bool {
1758 self.len() == 0
1759 }
1760}
1761
1762impl<'cont, T> Iterator for FlatIter<'cont, T> {
1763 type Item = &'cont T;
1764
1765 #[inline]
1766 fn next(&mut self) -> Option<Self::Item> {
1767 self.inner.next().map(|ptr| unsafe { ptr.cast().as_ref() })
1768 }
1769
1770 #[inline]
1771 fn size_hint(&self) -> (usize, Option<usize>) {
1772 let len = Self::len(self);
1773 (len, Some(len))
1774 }
1775}
1776
1777impl<T> iter::FusedIterator for FlatIter<'_, T> {}
1778
1779impl<T> ExactSizeIterator for FlatIter<'_, T> {
1780 #[inline]
1781 fn len(&self) -> usize {
1782 Self::len(self)
1783 }
1784}
1785
1786impl<T> DoubleEndedIterator for FlatIter<'_, T> {
1787 #[inline]
1788 fn next_back(&mut self) -> Option<Self::Item> {
1789 self.inner
1790 .next_back()
1791 .map(|ptr| unsafe { ptr.cast().as_ref() })
1792 }
1793}
1794
1795/// A mutable iterator that can be created from [`FlatRawIter`] with concrete
1796/// type and lifetime.
1797///
1798/// This iterator is useful when you have `FlatRawIter` and know what type the
1799/// iterator visits. You can create this iterator from the `FlatRawIter` then
1800/// use it like normal Rust iterators.
1801#[derive(Debug)]
1802#[repr(transparent)]
1803pub struct FlatIterMut<'cont, T: 'cont> {
1804 inner: FlatRawIter,
1805 _marker: PhantomData<&'cont mut T>,
1806}
1807
1808impl<'cont, T> FlatIterMut<'cont, T> {
1809 /// Borrows the given container then returns an iterator of the container.
1810 ///
1811 /// # Safety
1812 ///
1813 /// Given container must contain type `T` items.
1814 ///
1815 /// # Examples
1816 ///
1817 /// ```
1818 /// use my_ecs::{tinfo, ds::{ChunkAnyVec, FlatIterMut}};
1819 ///
1820 /// // `ChunkAnyVec` implements `AsFlatRawIter`.
1821 /// let chunk_cap = 2;
1822 /// let mut v = ChunkAnyVec::new(tinfo!(i32), chunk_cap);
1823 /// let iter = FlatIterMut::<i32>::new(&mut v);
1824 /// ```
1825 #[inline]
1826 pub fn new<C>(cont: &'cont mut C) -> Self
1827 where
1828 C: AsFlatRawIter + ?Sized,
1829 {
1830 // We're borrowing container, so lifetime is tied up.
1831 unsafe { Self::from_raw(cont.iter()) }
1832 }
1833
1834 /// Creates a new [`FlatIterMut`] from the given [`FlatRawIter`].
1835 ///
1836 /// # Safety
1837 ///
1838 /// - The `FlatRawIter` must yield pointers to type `T`.
1839 /// - The `FlatRawIter` must not be used elsewhere at the same time because
1840 /// created iterator must be exclusive.
1841 /// - Lifetime defined by caller must be sufficient to the `FlatRawIter`.
1842 ///
1843 /// # Examples
1844 ///
1845 /// ```
1846 /// use my_ecs::{tinfo, ds::{ChunkAnyVec, AsFlatRawIter, FlatIterMut}};
1847 ///
1848 /// // `ChunkAnyVec` implements `AsFlatRawIter`.
1849 /// let chunk_cap = 2;
1850 /// let v = ChunkAnyVec::new(tinfo!(i32), chunk_cap);
1851 /// unsafe {
1852 /// let raw_iter = v.iter();
1853 /// let iter = FlatIterMut::<i32>::from_raw(raw_iter);
1854 /// }
1855 /// ```
1856 #[inline]
1857 pub unsafe fn from_raw(raw: FlatRawIter) -> Self {
1858 Self {
1859 inner: raw,
1860 _marker: PhantomData,
1861 }
1862 }
1863
1864 /// Returns number of remaining items the iterator can visit.
1865 ///
1866 /// # Examples
1867 ///
1868 /// ```
1869 /// use my_ecs::{tinfo, ds::{ChunkAnyVec, FlatIterMut}};
1870 ///
1871 /// // `ChunkAnyVec` implements `AsFlatRawIter`.
1872 /// let chunk_cap = 2;
1873 /// let mut v = ChunkAnyVec::new(tinfo!(i32), chunk_cap);
1874 /// unsafe { v.push(0_i32) };
1875 ///
1876 /// let iter = FlatIterMut::<i32>::new(&mut v);
1877 /// assert_eq!(iter.len(), 1);
1878 /// ```
1879 #[inline]
1880 pub const fn len(&self) -> usize {
1881 self.inner.len()
1882 }
1883
1884 /// Returns true if the iterator has been consumed completely so that it
1885 /// cannot yield anything.
1886 ///
1887 /// # Examples
1888 ///
1889 /// ```
1890 /// use my_ecs::{tinfo, ds::{ChunkAnyVec, FlatIterMut}};
1891 ///
1892 /// // `ChunkAnyVec` implements `AsFlatRawIter`.
1893 /// let chunk_cap = 2;
1894 /// let mut v = ChunkAnyVec::new(tinfo!(i32), chunk_cap);
1895 ///
1896 /// let iter = FlatIterMut::<i32>::new(&mut v);
1897 /// assert!(iter.is_empty());
1898 /// ```
1899 #[inline]
1900 pub const fn is_empty(&self) -> bool {
1901 self.len() == 0
1902 }
1903}
1904
1905impl<'cont, T> Iterator for FlatIterMut<'cont, T> {
1906 type Item = &'cont mut T;
1907
1908 #[inline]
1909 fn next(&mut self) -> Option<Self::Item> {
1910 self.inner.next().map(|ptr| unsafe { ptr.cast().as_mut() })
1911 }
1912
1913 #[inline]
1914 fn size_hint(&self) -> (usize, Option<usize>) {
1915 let len = Self::len(self);
1916 (len, Some(len))
1917 }
1918}
1919
1920impl<T> iter::FusedIterator for FlatIterMut<'_, T> {}
1921
1922impl<T> ExactSizeIterator for FlatIterMut<'_, T> {
1923 #[inline]
1924 fn len(&self) -> usize {
1925 Self::len(self)
1926 }
1927}
1928
1929impl<T> DoubleEndedIterator for FlatIterMut<'_, T> {
1930 #[inline]
1931 fn next_back(&mut self) -> Option<Self::Item> {
1932 self.inner
1933 .next_back()
1934 .map(|ptr| unsafe { ptr.cast().as_mut() })
1935 }
1936}
1937
1938/// A parallel nested iterator.
1939///
1940/// This is a new type of [`FlatIter`]. [`Iterator`] and
1941/// [`rayon::iter::ParallelIterator`] have the same signature methods, So
1942/// clients have to write fully-qualified syntax to specify a method. This new
1943/// type helps clients avoid it. If you don't want parallelism, just use
1944/// [`FlatIter`].
1945#[derive(Debug, Clone)]
1946#[repr(transparent)]
1947pub struct ParFlatIter<'cont, T: 'cont>(pub FlatIter<'cont, T>);
1948
1949impl<'cont, T> ParFlatIter<'cont, T> {
1950 /// Converts the parallel iterator into sequential iterator by unwrapping
1951 /// self.
1952 #[inline]
1953 pub const fn into_seq(self) -> FlatIter<'cont, T> {
1954 self.0
1955 }
1956
1957 /// Returns remaining length of the iterator.
1958 #[inline]
1959 pub const fn len(&self) -> usize {
1960 self.0.len()
1961 }
1962
1963 /// Returns true if the iterator has consumed completely so that it cannot
1964 /// yield anything.
1965 #[inline]
1966 pub const fn is_empty(&self) -> bool {
1967 self.len() == 0
1968 }
1969}
1970
1971impl<'cont, T: Send + Sync + 'cont> Producer for ParFlatIter<'cont, T> {
1972 type Item = &'cont T;
1973 type IntoIter = FlatIter<'cont, T>;
1974
1975 #[inline]
1976 fn into_iter(self) -> Self::IntoIter {
1977 self.into_seq()
1978 }
1979
1980 #[inline]
1981 fn split_at(self, index: usize) -> (Self, Self) {
1982 let par_iter = ParFlatRawIter(self.0.inner);
1983 let (l, r) = par_iter.split_at(index);
1984
1985 // Safety: Splitting is safe.
1986 unsafe {
1987 let l = FlatIter::from_raw(l.0);
1988 let r = FlatIter::from_raw(r.0);
1989 (Self(l), Self(r))
1990 }
1991 }
1992}
1993
1994impl_into_iterator_for_parallel!(
1995 "lifetimes" = 'cont; "bounds" = T: {'cont};
1996 "for" = ParFlatIter; "to" = FlatIter<'cont, T>; "item" = &'cont T;
1997);
1998impl_parallel_iterator!(
1999 "lifetimes" = 'cont; "bounds" = T: {Send + Sync + 'cont};
2000 "for" = ParFlatIter; "item" = &'cont T;
2001);
2002impl_unindexed_producer!(
2003 "lifetimes" = 'cont; "bounds" = T: {Send + Sync + 'cont};
2004 "for" = ParFlatIter; "item" = &'cont T;
2005);
2006
2007/// A parallel nested mutable iterator.
2008///
2009/// This is a new type of [`FlatIterMut`]. [`Iterator`] and
2010/// [`rayon::iter::ParallelIterator`] have the same signature methods, So
2011/// clients have to write fully-qualified syntax to specify a method. This new
2012/// type helps clients avoid it. If you don't want parallelism, just use
2013/// [`FlatIterMut`].
2014#[derive(Debug)]
2015#[repr(transparent)]
2016pub struct ParFlatIterMut<'cont, T: 'cont>(pub FlatIterMut<'cont, T>);
2017
2018impl<'cont, T> ParFlatIterMut<'cont, T> {
2019 /// Converts the parallel iterator into sequential iterator by unwrapping
2020 /// self.
2021 #[inline]
2022 pub fn into_seq(self) -> FlatIterMut<'cont, T> {
2023 self.0
2024 }
2025
2026 /// Returns remaining length of the iterator.
2027 #[inline]
2028 pub const fn len(&self) -> usize {
2029 self.0.len()
2030 }
2031
2032 /// Returns true if the iterator has consumed completely so that it cannot
2033 /// yield anything.
2034 #[inline]
2035 pub const fn is_empty(&self) -> bool {
2036 self.len() == 0
2037 }
2038}
2039
2040impl<'cont, T: Send + Sync + 'cont> Producer for ParFlatIterMut<'cont, T> {
2041 type Item = &'cont mut T;
2042 type IntoIter = FlatIterMut<'cont, T>;
2043
2044 #[inline]
2045 fn into_iter(self) -> Self::IntoIter {
2046 self.into_seq()
2047 }
2048
2049 #[inline]
2050 fn split_at(self, index: usize) -> (Self, Self) {
2051 let par_iter = ParFlatRawIter(self.0.inner);
2052 let (l, r) = par_iter.split_at(index);
2053
2054 // Safety: Splitting is safe.
2055 unsafe {
2056 let l = FlatIterMut::from_raw(l.0);
2057 let r = FlatIterMut::from_raw(r.0);
2058 (Self(l), Self(r))
2059 }
2060 }
2061}
2062
2063impl_into_iterator_for_parallel!(
2064 "lifetimes" = 'cont; "bounds" = T: {'cont};
2065 "for" = ParFlatIterMut; "to" = FlatIterMut<'cont, T>;
2066 "item" = &'cont mut T;
2067);
2068impl_parallel_iterator!(
2069 "lifetimes" = 'cont; "bounds" = T: {Send + Sync + 'cont};
2070 "for" = ParFlatIterMut; "item" = &'cont mut T;
2071);
2072impl_unindexed_producer!(
2073 "lifetimes" = 'cont; "bounds" = T: {Send + Sync + 'cont};
2074 "for" = ParFlatIterMut; "item" = &'cont mut T;
2075);
2076
2077/// A raw getter for a container of items.
2078///
2079/// The getter basically provides [`RawGetter::get`] method for random access,
2080/// but you can register sequential access function through
2081/// [`RawGetter::with_iter`]. Then you can call [`RawGetter::iter`] for
2082/// sequential access.
2083///
2084/// Sequential access would be way faster than random access due to its cache
2085/// friendly access pattern, so it's recommended to perfer it over random access
2086/// as much as possible.
2087#[derive(Debug, Clone, Copy)]
2088pub struct RawGetter {
2089 /// Pointer to the container.
2090 this: SendSyncPtr<u8>,
2091
2092 /// Number of items.
2093 len: usize,
2094
2095 /// A function pointer for random access from a pointer of container.
2096 fn_get: unsafe fn(this: NonNull<u8>, index: usize) -> NonNull<u8>,
2097
2098 /// A function pointer for generating sequential access iterator from a
2099 /// pointer of container.
2100 fn_iter: unsafe fn(this: NonNull<u8>) -> FlatRawIter,
2101}
2102
2103impl RawGetter {
2104 /// Creates a new [`RawGetter`] from raw parts.
2105 ///
2106 /// * this - A pointer to a container.
2107 /// * len - Number of items of the container.
2108 /// * fn_get - A function that returns pointer to an item for an item index.
2109 ///
2110 /// # Safety
2111 ///
2112 /// Caller must guarantee that the created getter must have valid access
2113 /// to the given pointer while it is in use.
2114 pub const unsafe fn new(
2115 this: NonNull<u8>,
2116 len: usize,
2117 fn_get: unsafe fn(this: NonNull<u8>, index: usize) -> NonNull<u8>,
2118 ) -> Self {
2119 Self {
2120 this: SendSyncPtr::new(this),
2121 len,
2122 fn_get,
2123 fn_iter: |_| panic!("have you registered iterator function?"),
2124 }
2125 }
2126
2127 /// Registers the given function to the raw getter.
2128 ///
2129 /// * fn_iter - A function pointer for generating sequential access
2130 /// iterator.
2131 pub const fn with_iter(mut self, fn_iter: unsafe fn(this: NonNull<u8>) -> FlatRawIter) -> Self {
2132 self.fn_iter = fn_iter;
2133 self
2134 }
2135
2136 /// Returns number of items in the associated container.
2137 pub const fn len(&self) -> usize {
2138 self.len
2139 }
2140
2141 /// Returns true if the associated container is empty.
2142 pub const fn is_empty(&self) -> bool {
2143 self.len() == 0
2144 }
2145
2146 /// Returns a type-erased pointer to an item of the associated container.
2147 pub fn get(&self, index: usize) -> Option<NonNull<u8>> {
2148 if index < self.len {
2149 unsafe { Some(self.get_unchecked(index)) }
2150 } else {
2151 None
2152 }
2153 }
2154
2155 /// Returns a type-erased pointer to an item of the associated container.
2156 ///
2157 /// # Safety
2158 ///
2159 /// Undefined behavior if the given index is out of bounds.
2160 pub unsafe fn get_unchecked(&self, index: usize) -> NonNull<u8> {
2161 // Safety: In addition to index, `self.this` must be a valid pointer,
2162 // which is guaranteed by owners.
2163 unsafe { (self.fn_get)(self.this.as_nonnull(), index) }
2164 }
2165
2166 /// Returns a sequential access iterator for the associated container.
2167 ///
2168 /// Make sure that you have registered a function through
2169 /// [`RawGetter::with_iter`].
2170 ///
2171 /// # Panics
2172 ///
2173 /// Panics if iterator geneartion function have not registered yet.
2174 pub fn iter(&self) -> FlatRawIter {
2175 // Safety: Owners guarantee validity.
2176 unsafe { (self.fn_iter)(self.this.as_nonnull()) }
2177 }
2178
2179 /// Returns a type-erased pointer to the associated container.
2180 pub fn ptr(&self) -> NonNull<u8> {
2181 self.this.as_nonnull()
2182 }
2183}
2184
2185/// A getter that can be created from [`RawGetter`] with concrete type and
2186/// lifetime.
2187///
2188/// This getter is useful when you have `RawGetter` and know what type the
2189/// getter will return. You can create this getter from the `RawGetter` then
2190/// use it as a `get` function of an associated container.
2191#[derive(Debug, Clone)]
2192#[repr(transparent)]
2193pub struct Getter<'cont, T: 'cont> {
2194 raw: RawGetter,
2195 _marker: PhantomData<&'cont T>,
2196}
2197
2198impl<'cont, T> Getter<'cont, T> {
2199 /// Creates a new [`Getter`] from the given [`RawGetter`].
2200 ///
2201 /// # Safety
2202 ///
2203 /// - The `RawGetter` must return pointers to type `T`.
2204 /// - Lifetime defined by caller must be sufficient to the `RawGetter`.
2205 pub unsafe fn from_raw(raw: RawGetter) -> Self {
2206 Self {
2207 raw,
2208 _marker: PhantomData,
2209 }
2210 }
2211
2212 /// Converts the getter into [`RawGetter`] by unwrpping self.
2213 pub fn into_raw(self) -> RawGetter {
2214 self.raw
2215 }
2216
2217 /// Returns number of items in the associated container.
2218 pub fn len(&self) -> usize {
2219 self.raw.len()
2220 }
2221
2222 /// Returns true is the associated container is empty.
2223 pub fn is_empty(&self) -> bool {
2224 self.raw.is_empty()
2225 }
2226
2227 /// Returns a shared reference to a value at the given index in the
2228 /// associated container.
2229 pub fn get(&self, index: usize) -> Option<&T> {
2230 if index < self.len() {
2231 // Safety: We checked the length.
2232 unsafe { Some(self.get_unchecked(index)) }
2233 } else {
2234 None
2235 }
2236 }
2237
2238 /// Returns a shared reference to a value at the given index in the
2239 /// associated container.
2240 ///
2241 /// # Safety
2242 ///
2243 /// Undefined behavior if the given index is out of bounds.
2244 pub unsafe fn get_unchecked(&self, index: usize) -> &T {
2245 unsafe {
2246 let ptr = self.raw.get_unchecked(index).cast();
2247 ptr.as_ref()
2248 }
2249 }
2250
2251 /// Returns a sequential access iterator of the associated container.
2252 ///
2253 /// But if you created the iterator from a [`RawGetter`] without calling
2254 /// [`RawGetter::with_iter`], this will panic.
2255 ///
2256 /// # Panics
2257 ///
2258 /// Panics if iterator geneartion function have not registered yet.
2259 pub fn iter(&self) -> FlatIter<'cont, T> {
2260 // Safety: Correct type and lifetime are given.
2261 unsafe { FlatIter::from_raw(self.raw.iter()) }
2262 }
2263
2264 /// Returns a parallel iterator of the associated container.
2265 ///
2266 /// But if you created the iterator from a [`RawGetter`] without calling
2267 /// [`RawGetter::with_iter`], this will panic.
2268 ///
2269 /// # Panics
2270 ///
2271 /// Panics if iterator geneartion function have not registered yet.
2272 #[inline]
2273 pub fn par_iter(&self) -> ParFlatIter<'cont, T> {
2274 ParFlatIter(self.iter())
2275 }
2276
2277 /// Returns number of chunks.
2278 pub fn num_chunks(&self) -> usize {
2279 let flat_iter = self.raw.iter();
2280 flat_iter.num_chunks()
2281 }
2282
2283 /// Retrieves a slice for the given chunk index.
2284 ///
2285 /// If the given chunk index is out of bounds, empty slice is returned.
2286 pub fn as_slice(&self, chunk_index: usize) -> &[T] {
2287 // Safety: Type is correct.
2288 unsafe { self.raw.iter().as_slice(chunk_index) }
2289 }
2290}
2291
2292impl<'cont, T> IntoIterator for Getter<'cont, T> {
2293 type Item = &'cont T;
2294 type IntoIter = FlatIter<'cont, T>;
2295
2296 fn into_iter(self) -> Self::IntoIter {
2297 Self::iter(&self)
2298 }
2299}
2300
2301impl<'cont, T: Send + Sync> IntoParallelIterator for Getter<'cont, T> {
2302 type Iter = ParFlatIter<'cont, T>;
2303 type Item = &'cont T;
2304
2305 fn into_par_iter(self) -> Self::Iter {
2306 Self::par_iter(&self)
2307 }
2308}
2309
2310/// A mutable getter that can be created from [`RawGetter`] with concrete type
2311/// and lifetime.
2312///
2313/// This getter is useful when you have `RawGetter` and know what type the
2314/// getter will return. You can create this getter from the `RawGetter` then
2315/// use it as a `get_mut` function of an associated container.
2316#[derive(Debug, Clone)]
2317#[repr(transparent)]
2318pub struct GetterMut<'cont, T: 'cont> {
2319 raw: RawGetter,
2320 _marker: PhantomData<&'cont mut T>,
2321}
2322
2323impl<'cont, T> GetterMut<'cont, T> {
2324 /// Creates a new [`GetterMut`] from the given [`RawGetter`].
2325 ///
2326 /// # Safety
2327 ///
2328 /// - The `RawGetter` must return pointers to type `T`.
2329 /// - The `RawGetter` must not be used elsewhere at the same time because
2330 /// created getter must be exclusive.
2331 /// - Lifetime defined by caller must be sufficient to the `RawGetter`.
2332 pub unsafe fn from_raw(raw: RawGetter) -> Self {
2333 Self {
2334 raw,
2335 _marker: PhantomData,
2336 }
2337 }
2338
2339 /// Converts the getter into [`RawGetter`] by unwrpping self.
2340 pub fn into_raw(self) -> RawGetter {
2341 self.raw
2342 }
2343
2344 /// Returns number of items in the associated container.
2345 pub fn len(&self) -> usize {
2346 self.raw.len()
2347 }
2348
2349 /// Returns true is the associated container is empty.
2350 pub fn is_empty(&self) -> bool {
2351 self.raw.is_empty()
2352 }
2353
2354 /// Returns a shared reference to a value at the given index in the
2355 /// associated container.
2356 pub fn get(&self, index: usize) -> Option<&T> {
2357 if index < self.len() {
2358 // Safety: We checked the length.
2359 unsafe { Some(self.get_unchecked(index)) }
2360 } else {
2361 None
2362 }
2363 }
2364
2365 /// Returns a shared reference to a value at the given index in the
2366 /// associated container.
2367 ///
2368 /// # Safety
2369 ///
2370 /// Undefined behavior if the given index is out of bounds.
2371 pub unsafe fn get_unchecked(&self, index: usize) -> &T {
2372 unsafe {
2373 let ptr = self.raw.get_unchecked(index).cast();
2374 ptr.as_ref()
2375 }
2376 }
2377
2378 /// Returns a mutable reference to a value at the given index in the
2379 /// associated container.
2380 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
2381 if index < self.len() {
2382 // Safety: `index` is in bounds.
2383 unsafe { Some(self.get_unchecked_mut(index)) }
2384 } else {
2385 None
2386 }
2387 }
2388
2389 /// Returns a mutable reference to a value at the given index in the
2390 /// associated container.
2391 ///
2392 /// # Safety
2393 ///
2394 /// Undefined behavior if the given index is out of bounds.
2395 pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T {
2396 unsafe {
2397 let mut ptr = self.raw.get_unchecked(index).cast();
2398 ptr.as_mut()
2399 }
2400 }
2401
2402 /// Returns a sequential access iterator of the associated container.
2403 ///
2404 /// But if you created the iterator from a [`RawGetter`] without calling
2405 /// [`RawGetter::with_iter`], this will panic.
2406 ///
2407 /// # Panics
2408 ///
2409 /// Panics if iterator geneartion function have not registered yet.
2410 pub fn iter(&self) -> FlatIter<'cont, T> {
2411 // Safety: Correct type and lifetime are given.
2412 unsafe { FlatIter::from_raw(self.raw.iter()) }
2413 }
2414
2415 /// Returns a mutable sequential access iterator of the associated
2416 /// container.
2417 ///
2418 /// But if you created the iterator from a [`RawGetter`] without calling
2419 /// [`RawGetter::with_iter`], this will panic.
2420 ///
2421 /// # Panics
2422 ///
2423 /// Panics if iterator geneartion function have not registered yet.
2424 pub fn iter_mut(&mut self) -> FlatIterMut<'cont, T> {
2425 // Safety: Correct type and lifetime are given.
2426 unsafe { FlatIterMut::from_raw(self.raw.iter()) }
2427 }
2428
2429 /// Returns a parallel iterator of the associated container.
2430 ///
2431 /// But if you created the iterator from a [`RawGetter`] without calling
2432 /// [`RawGetter::with_iter`], this will panic.
2433 ///
2434 /// # Panics
2435 ///
2436 /// Panics if iterator geneartion function have not registered yet.
2437 #[inline]
2438 pub fn par_iter(&self) -> ParFlatIter<'cont, T> {
2439 ParFlatIter(self.iter())
2440 }
2441
2442 /// Returns a parallel mutable iterator of the associated container.
2443 ///
2444 /// But if you created the iterator from a [`RawGetter`] without calling
2445 /// [`RawGetter::with_iter`], this will panic.
2446 ///
2447 /// # Panics
2448 ///
2449 /// Panics if iterator geneartion function have not registered yet.
2450 #[inline]
2451 pub fn par_iter_mut(&mut self) -> ParFlatIterMut<'cont, T> {
2452 ParFlatIterMut(self.iter_mut())
2453 }
2454
2455 /// Returns number of chunks.
2456 pub fn num_chunks(&self) -> usize {
2457 let flat_iter = self.raw.iter();
2458 flat_iter.num_chunks()
2459 }
2460
2461 /// Retrieves a shared slice for the given chunk index.
2462 ///
2463 /// If the given chunk index is out of bounds, empty slice will be returned.
2464 pub fn as_slice(&self, chunk_index: usize) -> &[T] {
2465 // Safety: Type is correct.
2466 unsafe { self.raw.iter().as_slice(chunk_index) }
2467 }
2468
2469 /// Retrieves a mutable slice for the given chunk index.
2470 ///
2471 /// If the given chunk index is out of bounds, empty slice will be returned.
2472 pub fn as_mut_slice(&mut self, chunk_index: usize) -> &mut [T] {
2473 // Safety: Type is correct.
2474 unsafe { self.raw.iter().as_mut_slice(chunk_index) }
2475 }
2476}
2477
2478impl<'cont, T> IntoIterator for GetterMut<'cont, T> {
2479 type Item = &'cont mut T;
2480 type IntoIter = FlatIterMut<'cont, T>;
2481
2482 fn into_iter(mut self) -> Self::IntoIter {
2483 Self::iter_mut(&mut self)
2484 }
2485}
2486
2487impl<'cont, T: Send + Sync> IntoParallelIterator for GetterMut<'cont, T> {
2488 type Iter = ParFlatIterMut<'cont, T>;
2489 type Item = &'cont mut T;
2490
2491 fn into_par_iter(mut self) -> Self::Iter {
2492 Self::par_iter_mut(&mut self)
2493 }
2494}