Skip to main content

soa_rs/
soa.rs

1use crate::{
2    AsMutSlice, AsSlice, IntoIter, Iter, IterMut, Slice, SliceMut, SliceRef, SoaClone, SoaRaw,
3    Soars, Vec, iter_raw::IterRaw,
4};
5use core::{
6    borrow::{Borrow, BorrowMut},
7    cmp::Ordering,
8    fmt::{self, Debug, Formatter},
9    hash::{Hash, Hasher},
10    marker::PhantomData,
11    mem::{ManuallyDrop, needs_drop, size_of},
12    ops::{Deref, DerefMut},
13    ptr::NonNull,
14};
15
16/// A growable array type that stores the values for each field of `T`
17/// contiguously.
18///
19/// The design for SoA aligns closely with [`Vec`]:
20/// - Overallocates capacity to provide O(1) amortized insertion
21/// - Does not allocate until elements are added
22/// - Never deallocates memory unless explicitly requested
23/// - Uses `usize::MAX` as the capacity for zero-sized types
24///
25/// See the top-level [`soa_rs`] docs for usage examples.
26///
27/// [`soa_rs`]: crate
28pub struct Soa<T>
29where
30    T: Soars,
31{
32    pub(crate) cap: usize,
33    pub(crate) slice: Slice<T, ()>,
34    pub(crate) len: usize,
35}
36
37impl<T> Soa<T>
38where
39    T: Soars,
40{
41    /// The capacity of the initial allocation. This is an optimization to avoid
42    /// excessive reallocation for small array sizes.
43    const SMALL_CAPACITY: usize = 4;
44
45    /// Constructs a new, empty `Soa<T>`.
46    ///
47    /// The container will not allocate until elements are pushed onto it.
48    ///
49    /// # Examples
50    /// ```
51    /// # use soa_rs::{Soa, Soars};
52    /// # #[derive(Soars, Copy, Clone)]
53    /// # #[soa_derive(Debug, PartialEq)]
54    /// # struct Foo;
55    /// let mut soa = Soa::<Foo>::new();
56    /// ```
57    pub fn new() -> Self {
58        Self {
59            cap: if size_of::<T>() == 0 { usize::MAX } else { 0 },
60            slice: Slice::empty(),
61            len: 0,
62        }
63    }
64
65    /// Construct a new, empty `Soa<T>` with at least the specified capacity.
66    ///
67    /// The container will be able to hold `capacity` elements without
68    /// reallocating. If the `capacity` is 0, the container will not allocate.
69    /// Note that although the returned vector has the minimum capacity
70    /// specified, the vector will have a zero length. The capacity will be as
71    /// specified unless `T` is zero-sized, in which case the capacity will be
72    /// `usize::MAX`.
73    ///
74    /// # Examples
75    /// ```
76    /// # use soa_rs::{Soa, Soars};
77    /// #[derive(Soars)]
78    /// # #[soa_derive(Debug, PartialEq)]
79    /// struct Foo(u8, u8);
80    ///
81    /// let mut soa = Soa::<Foo>::with_capacity(10);
82    /// assert_eq!(soa.len(), 0);
83    /// assert_eq!(soa.capacity(), 10);
84    ///
85    /// // These pushes do not reallocate...
86    /// for i in 0..10 {
87    ///     soa.push(Foo(i, i));
88    /// }
89    /// assert_eq!(soa.len(), 10);
90    /// assert_eq!(soa.capacity(), 10);
91    ///
92    /// // ...but this one does
93    /// soa.push(Foo(11, 11));
94    /// assert_eq!(soa.len(), 11);
95    /// assert_eq!(soa.capacity(), 20);
96    ///
97    /// #[derive(Soars, Copy, Clone)]
98    /// # #[soa_derive(Debug, PartialEq)]
99    /// struct Bar;
100    ///
101    /// // A SOA of a zero-sized type always over-allocates
102    /// let soa = Soa::<Bar>::with_capacity(10);
103    /// assert_eq!(soa.capacity(), usize::MAX);
104    /// ```
105    pub fn with_capacity(capacity: usize) -> Self {
106        match capacity {
107            0 => Self::new(),
108            capacity => {
109                if size_of::<T>() == 0 {
110                    Self {
111                        cap: usize::MAX,
112                        slice: Slice::empty(),
113                        len: 0,
114                    }
115                } else {
116                    Self {
117                        cap: capacity,
118                        // SAFETY:
119                        // - T is nonzero sized
120                        // - capacity is nonzero
121                        slice: Slice::with_raw(unsafe { T::Raw::alloc(capacity) }),
122                        len: 0,
123                    }
124                }
125            }
126        }
127    }
128
129    /// Constructs a new `Soa<T>` with the given first element.
130    ///
131    /// This is mainly useful to get around type inference limitations in some
132    /// situations, namely macros. Type inference can struggle sometimes due to
133    /// dereferencing to an associated type of `T`, which causes Rust to get
134    /// confused about whether, for example, `push`ing and element should coerce
135    /// `self` to the argument's type.
136    ///
137    /// # Examples
138    ///
139    /// ```
140    /// # use soa_rs::{Soa, Soars, soa};
141    /// # #[derive(Soars, Debug, PartialEq)]
142    /// # #[soa_derive(Debug, PartialEq)]
143    /// # struct Foo(usize);
144    /// let soa = Soa::with(Foo(10));
145    /// assert_eq!(soa, soa![Foo(10)]);
146    /// ```
147    pub fn with(element: T) -> Self {
148        let mut out = Self::new();
149        out.push(element);
150        out
151    }
152
153    /// Returns the total number of elements the container can hold without
154    /// reallocating.
155    ///
156    /// # Examples
157    ///
158    /// ```
159    /// # use soa_rs::{Soa, Soars};
160    /// # #[derive(Soars)]
161    /// # #[soa_derive(Debug, PartialEq)]
162    /// # struct Foo(usize);
163    /// let mut soa = Soa::<Foo>::new();
164    /// for i in 0..42 {
165    ///     assert!(soa.capacity() >= i);
166    ///     soa.push(Foo(i));
167    /// }
168    /// ```
169    pub fn capacity(&self) -> usize {
170        self.cap
171    }
172
173    /// Decomposes a `Soa<T>` into its raw components.
174    ///
175    /// Returns the raw pointer to the underlying data, the length of the vector (in
176    /// elements), and the allocated capacity of the data (in elements). These
177    /// are the same arguments in the same order as the arguments to
178    /// [`Soa::from_raw_parts`].
179    ///
180    /// After calling this function, the caller is responsible for the memory
181    /// previously managed by the `Soa`. The only way to do this is to convert the
182    /// raw pointer, length, and capacity back into a Vec with the
183    /// [`Soa::from_raw_parts`] function, allowing the destructor to perform the cleanup.
184    ///
185    /// # Examples
186    ///
187    /// ```
188    /// # use soa_rs::{Soa, Soars, soa};
189    /// # #[derive(Soars, Debug, PartialEq)]
190    /// # #[soa_derive(Debug, PartialEq)]
191    /// # struct Foo(usize);
192    /// let soa = soa![Foo(1), Foo(2)];
193    /// let (ptr, len, cap) = soa.into_raw_parts();
194    /// let rebuilt = unsafe { Soa::<Foo>::from_raw_parts(ptr, len, cap) };
195    /// assert_eq!(rebuilt, soa![Foo(1), Foo(2)]);
196    /// ```
197    pub fn into_raw_parts(self) -> (NonNull<u8>, usize, usize) {
198        let me = ManuallyDrop::new(self);
199        (me.raw().into_parts(), me.len, me.cap)
200    }
201
202    /// Creates a `Soa<T>` from a pointer, a length, and a capacity.
203    ///
204    /// # Safety
205    ///
206    /// This is highly unsafe due to the number of invariants that aren't
207    /// checked. Given that many of these invariants are private implementation
208    /// details of [`SoaRaw`], it is better not to uphold them manually. Rather,
209    /// it only valid to call this method with the output of a previous call to
210    /// [`Soa::into_raw_parts`].
211    pub unsafe fn from_raw_parts(ptr: NonNull<u8>, length: usize, capacity: usize) -> Self {
212        let raw = unsafe { T::Raw::from_parts(ptr, capacity) };
213        Self {
214            cap: capacity,
215            slice: Slice::with_raw(raw),
216            len: length,
217        }
218    }
219
220    /// Appends an element to the back of a collection.
221    ///
222    /// # Examples
223    ///
224    /// ```
225    /// # use soa_rs::{Soa, Soars, soa};
226    /// # #[derive(Soars, Debug, PartialEq)]
227    /// # #[soa_derive(Debug, PartialEq)]
228    /// # struct Foo(usize);
229    /// let mut soa = soa![Foo(1), Foo(2)];
230    /// soa.push(Foo(3));
231    /// assert_eq!(soa, soa![Foo(1), Foo(2), Foo(3)]);
232    /// ```
233    pub fn push(&mut self, element: T) {
234        self.maybe_grow();
235        // SAFETY: After maybe_grow, the allocated capacity is greater than len
236        unsafe {
237            self.raw().offset(self.len).set(element);
238        }
239        self.len += 1;
240    }
241
242    /// Removes the last element from a vector and returns it, or [`None`] if it
243    /// is empty.
244    ///
245    /// # Examples
246    ///
247    /// ```
248    /// # use soa_rs::{Soa, Soars, soa};
249    /// # #[derive(Soars, Debug, PartialEq)]
250    /// # #[soa_derive(Debug, PartialEq)]
251    /// # struct Foo(usize);
252    /// let mut soa = soa![Foo(1), Foo(2), Foo(3)];
253    /// assert_eq!(soa.pop(), Some(Foo(3)));
254    /// assert_eq!(soa, soa![Foo(1), Foo(2)]);
255    /// ```
256    pub fn pop(&mut self) -> Option<T> {
257        if self.len == 0 {
258            None
259        } else {
260            self.len -= 1;
261            // SAFETY: len points to at least one initialized item
262            Some(unsafe { self.raw().offset(self.len).get() })
263        }
264    }
265
266    /// Inserts an element at position `index`, shifting all elements after it
267    /// to the right.
268    ///
269    /// # Panics
270    ///
271    /// Panics if `index > len`
272    ///
273    /// # Examples
274    ///
275    /// ```
276    /// # use soa_rs::{Soa, Soars, soa};
277    /// # #[derive(Soars, Debug, PartialEq)]
278    /// # #[soa_derive(Debug, PartialEq)]
279    /// # struct Foo(usize);
280    /// let mut soa = soa![Foo(1), Foo(2), Foo(3)];
281    /// soa.insert(1, Foo(4));
282    /// assert_eq!(soa, soa![Foo(1), Foo(4), Foo(2), Foo(3)]);
283    /// soa.insert(4, Foo(5));
284    /// assert_eq!(soa, soa![Foo(1), Foo(4), Foo(2), Foo(3), Foo(5)]);
285    /// ```
286    pub fn insert(&mut self, index: usize, element: T) {
287        assert!(index <= self.len, "index out of bounds");
288        self.maybe_grow();
289        // SAFETY: After the bounds check and maybe_grow, index is an
290        // initialized item and index+1 is allocated
291        unsafe {
292            let ith = self.raw().offset(index);
293            ith.copy_to(ith.offset(1), self.len - index);
294            ith.set(element);
295        }
296        self.len += 1;
297    }
298
299    /// Removes and returns the element at position index within the vector,
300    /// shifting all elements after it to the left.
301    ///
302    /// # Examples
303    ///
304    /// ```
305    /// # use soa_rs::{Soa, Soars, soa};
306    /// # #[derive(Soars, Debug, PartialEq)]
307    /// # #[soa_derive(Debug, PartialEq)]
308    /// # struct Foo(usize);
309    /// let mut soa = soa![Foo(1), Foo(2), Foo(3)];
310    /// assert_eq!(soa.remove(1), Foo(2));
311    /// assert_eq!(soa, soa![Foo(1), Foo(3)])
312    /// ```
313    pub fn remove(&mut self, index: usize) -> T {
314        assert!(index < self.len, "index out of bounds");
315        self.len -= 1;
316        // SAFETY: After the bounds check, we know ith item is initialized
317        let ith = unsafe { self.raw().offset(index) };
318        let out = unsafe { ith.get() };
319        // SAFETY: There are len-index initialized elements to shift back
320        unsafe {
321            ith.offset(1).copy_to(ith, self.len - index);
322        }
323        out
324    }
325
326    /// Reserves capacity for at least additional more elements to be inserted
327    /// in the given `Soa<T>`. The collection may reserve more space to
328    /// speculatively avoid frequent reallocations. After calling reserve,
329    /// capacity will be greater than or equal to `self.len() + additional`.
330    /// Does nothing if capacity is already sufficient.
331    ///
332    /// # Examples
333    ///
334    /// ```
335    /// # use soa_rs::{Soa, Soars, soa};
336    /// # #[derive(Soars, Debug, PartialEq)]
337    /// # #[soa_derive(Debug, PartialEq)]
338    /// # struct Foo(usize);
339    /// let mut soa = soa![Foo(1)];
340    /// soa.reserve(10);
341    /// assert!(soa.capacity() >= 11);
342    /// ```
343    pub fn reserve(&mut self, additional: usize) {
344        let new_len = self.len + additional;
345        if new_len > self.cap {
346            let new_cap = new_len
347                // Ensure exponential growth
348                .max(self.cap * 2)
349                .max(Self::SMALL_CAPACITY);
350            self.grow(new_cap);
351        }
352    }
353
354    /// Reserves the minimum capacity for at least additional more elements to
355    /// be inserted in the given `Soa<T>`. Unlike [`Soa::reserve`], this will
356    /// not deliberately over-allocate to speculatively avoid frequent
357    /// allocations. After calling `reserve_exact`, capacity will be equal to
358    /// self.len() + additional, or else `usize::MAX` if `T` is zero-sized. Does
359    /// nothing if the capacity is already sufficient.
360    ///
361    /// # Examples
362    ///
363    /// ```
364    /// # use soa_rs::{Soa, Soars, soa};
365    /// # #[derive(Soars, Debug, PartialEq)]
366    /// # #[soa_derive(Debug, PartialEq)]
367    /// # struct Foo(usize);
368    /// let mut soa = soa![Foo(1)];
369    /// soa.reserve(10);
370    /// assert!(soa.capacity() == 11);
371    /// ```
372    pub fn reserve_exact(&mut self, additional: usize) {
373        let new_len = additional + self.len;
374        if new_len > self.cap {
375            self.grow(new_len);
376        }
377    }
378
379    /// Shrinks the capacity of the container as much as possible.
380    ///
381    /// # Examples
382    ///
383    /// ```
384    /// # use soa_rs::{Soa, Soars, soa};
385    /// # #[derive(Soars, Debug, PartialEq)]
386    /// # #[soa_derive(Debug, PartialEq)]
387    /// # struct Foo(usize);
388    /// let mut soa = Soa::<Foo>::with_capacity(10);
389    /// soa.extend([Foo(1), Foo(2), Foo(3)]);
390    /// assert_eq!(soa.capacity(), 10);
391    /// soa.shrink_to_fit();
392    /// assert_eq!(soa.capacity(), 3);
393    /// ```
394    pub fn shrink_to_fit(&mut self) {
395        self.shrink(self.len);
396    }
397
398    /// Shrinks the capacity of the vector with a lower bound.
399    ///
400    /// The capacity will remain at least as large as both the length and the
401    /// supplied value. If the current capacity is less than the lower limit,
402    /// this is a no-op.
403    ///
404    /// # Examples
405    ///
406    /// ```
407    /// # use soa_rs::{Soa, Soars, soa};
408    /// # #[derive(Soars, Debug, PartialEq)]
409    /// # #[soa_derive(Debug, PartialEq)]
410    /// # struct Foo(usize);
411    /// let mut soa = Soa::<Foo>::with_capacity(10);
412    /// soa.extend([Foo(1), Foo(2), Foo(3)]);
413    /// assert_eq!(soa.capacity(), 10);
414    /// soa.shrink_to(4);
415    /// assert_eq!(soa.capacity(), 4);
416    /// soa.shrink_to(0);
417    /// assert_eq!(soa.capacity(), 3);
418    pub fn shrink_to(&mut self, min_capacity: usize) {
419        let new_cap = self.len.max(min_capacity);
420        if new_cap < self.cap {
421            self.shrink(new_cap);
422        }
423    }
424
425    /// Shortens the vector, keeping the first len elements and dropping the rest.
426    ///
427    /// If len is greater or equal to the vector’s current length, this has no
428    /// effect. Note that this method has no effect on the allocated capacity of
429    /// the vector.
430    ///
431    /// # Examples
432    ///
433    /// Truncating a five-element SOA to two elements:
434    /// ```
435    /// # use soa_rs::{Soa, Soars, soa};
436    /// # #[derive(Soars, Debug, PartialEq)]
437    /// # #[soa_derive(Debug, PartialEq)]
438    /// # struct Foo(usize);
439    /// let mut soa = soa![Foo(1), Foo(2), Foo(3), Foo(4), Foo(5)];
440    /// soa.truncate(2);
441    /// assert_eq!(soa, soa![Foo(1), Foo(2)]);
442    /// ```
443    ///
444    /// No truncation occurs when `len` is greater than the SOA's current
445    /// length:
446    /// ```
447    /// # use soa_rs::{Soa, Soars, soa};
448    /// # #[derive(Soars, Debug, PartialEq)]
449    /// # #[soa_derive(Debug, PartialEq)]
450    /// # struct Foo(usize);
451    /// let mut soa = soa![Foo(1), Foo(2), Foo(3)];
452    /// soa.truncate(8);
453    /// assert_eq!(soa, soa![Foo(1), Foo(2), Foo(3)]);
454    /// ```
455    ///
456    /// Truncating with `len == 0` is equivalent to [`Soa::clear`].
457    /// ```
458    /// # use soa_rs::{Soa, Soars, soa};
459    /// # #[derive(Soars, Debug, PartialEq)]
460    /// # #[soa_derive(Debug, PartialEq)]
461    /// # struct Foo(usize);
462    /// let mut soa = soa![Foo(1), Foo(2), Foo(3)];
463    /// soa.truncate(0);
464    /// assert_eq!(soa, soa![]);
465    /// ```
466    pub fn truncate(&mut self, len: usize) {
467        while len < self.len {
468            self.pop();
469        }
470    }
471
472    /// Removes an element from the vector and returns it.
473    ///
474    /// The removed element is replaced by the last element of the vector. This
475    /// does not preserve ordering, but is O(1). If you need to preserve the
476    /// element order, use remove instead.
477    ///
478    /// # Panics
479    ///
480    /// Panics if index is out of bounds.
481    ///
482    /// # Examples
483    ///
484    /// ```
485    /// # use soa_rs::{Soa, Soars, soa};
486    /// # #[derive(Soars, Debug, PartialEq)]
487    /// # #[soa_derive(Debug, PartialEq)]
488    /// # struct Foo(usize);
489    /// let mut soa = soa![Foo(0), Foo(1), Foo(2), Foo(3)];
490    ///
491    /// assert_eq!(soa.swap_remove(1), Foo(1));
492    /// assert_eq!(soa, soa![Foo(0), Foo(3), Foo(2)]);
493    ///
494    /// assert_eq!(soa.swap_remove(0), Foo(0));
495    /// assert_eq!(soa, soa![Foo(2), Foo(3)])
496    /// ```
497    pub fn swap_remove(&mut self, index: usize) -> T {
498        if index >= self.len {
499            panic!("index out of bounds")
500        }
501        self.len -= 1;
502        // SAFETY: index and len-1 are initialized elements
503        let to_remove = unsafe { self.raw().offset(index) };
504        let last = unsafe { self.raw().offset(self.len) };
505        let out = unsafe { to_remove.get() };
506        unsafe {
507            last.copy_to(to_remove, 1);
508        }
509        out
510    }
511
512    /// Moves all the elements of other into self, leaving other empty.
513    ///
514    /// # Examples
515    ///
516    /// ```
517    /// # use soa_rs::{Soa, Soars, soa};
518    /// # #[derive(Soars, Debug, PartialEq)]
519    /// # #[soa_derive(Debug, PartialEq)]
520    /// # struct Foo(usize);
521    /// let mut soa1  = soa![Foo(1), Foo(2), Foo(3)];
522    /// let mut soa2 = soa![Foo(4), Foo(5), Foo(6)];
523    /// soa1.append(&mut soa2);
524    /// assert_eq!(soa1, soa![Foo(1), Foo(2), Foo(3), Foo(4), Foo(5), Foo(6)]);
525    /// assert_eq!(soa2, soa![]);
526    /// ```
527    pub fn append(&mut self, other: &mut Self) {
528        let len_new = self.len.checked_add(other.len).expect("capacity overflow");
529        self.reserve(other.len);
530
531        // SAFETY:
532        // - `reserve` ensured `self` has capacity for `new_len`
533        // - the source range is initialized
534        // - `self` and `other` are `&mut` and cannot overlap
535        unsafe {
536            let dst = self.raw().offset(self.len);
537            other.raw().copy_to(dst, other.len);
538        }
539
540        other.len = 0;
541        self.len = len_new;
542    }
543
544    /// Clears the vector, removing all values.
545    ///
546    /// Note that this method has no effect on the allocated capacity of the
547    /// vector.
548    ///
549    /// # Examples
550    ///
551    /// ```
552    /// # use soa_rs::{Soa, Soars, soa};
553    /// # #[derive(Soars, Debug, PartialEq)]
554    /// # #[soa_derive(Debug, PartialEq)]
555    /// # struct Foo(usize);
556    /// let mut soa = soa![Foo(1), Foo(2)];
557    /// soa.clear();
558    /// assert!(soa.is_empty());
559    /// ```
560    pub fn clear(&mut self) {
561        while self.pop().is_some() {}
562    }
563
564    /// Grows the allocated capacity if `len == cap`.
565    fn maybe_grow(&mut self) {
566        if self.len < self.cap {
567            return;
568        }
569        let new_cap = match self.cap {
570            0 => Self::SMALL_CAPACITY,
571            old_cap => old_cap * 2,
572        };
573        self.grow(new_cap);
574    }
575
576    // Shrinks the allocated capacity.
577    fn shrink(&mut self, new_cap: usize) {
578        debug_assert!(new_cap <= self.cap);
579        if self.cap == 0 || new_cap == self.cap || size_of::<T>() == 0 {
580            return;
581        }
582
583        if new_cap == 0 {
584            debug_assert!(self.cap > 0);
585            // SAFETY: We asserted the preconditions
586            unsafe {
587                self.raw().dealloc(self.cap);
588            }
589            self.raw = T::Raw::dangling();
590        } else {
591            debug_assert!(new_cap < self.cap);
592            debug_assert!(self.len <= new_cap);
593            // SAFETY: We asserted the preconditions
594            unsafe {
595                self.raw = self.raw().realloc_shrink(self.cap, new_cap, self.len);
596            }
597        }
598
599        self.cap = new_cap;
600    }
601
602    /// Grows the allocated capacity.
603    fn grow(&mut self, new_cap: usize) {
604        debug_assert!(size_of::<T>() > 0);
605        debug_assert!(new_cap > self.cap);
606
607        if self.cap == 0 {
608            debug_assert!(new_cap > 0);
609            // SAFETY: We asserted the preconditions
610            self.raw = unsafe { T::Raw::alloc(new_cap) };
611        } else {
612            debug_assert!(self.len <= self.cap);
613            // SAFETY: We asserted the preconditions
614            unsafe {
615                self.raw = self.raw().realloc_grow(self.cap, new_cap, self.len);
616            }
617        }
618
619        self.cap = new_cap;
620    }
621}
622
623impl<T> Drop for Soa<T>
624where
625    T: Soars,
626{
627    fn drop(&mut self) {
628        if needs_drop::<T>() {
629            while self.pop().is_some() {}
630        }
631
632        if size_of::<T>() > 0 && self.cap > 0 {
633            // SAFETY: We asserted the preconditions
634            unsafe {
635                self.raw().dealloc(self.cap);
636            }
637        }
638    }
639}
640
641impl<T> IntoIterator for Soa<T>
642where
643    T: Soars,
644{
645    type Item = T;
646
647    type IntoIter = IntoIter<T>;
648
649    fn into_iter(self) -> Self::IntoIter {
650        let soa = ManuallyDrop::new(self);
651        IntoIter {
652            iter_raw: IterRaw {
653                slice: soa.slice,
654                len: soa.len,
655                adapter: PhantomData,
656            },
657            ptr: soa.raw().into_parts(),
658            cap: soa.cap,
659        }
660    }
661}
662
663impl<'a, T> IntoIterator for &'a Soa<T>
664where
665    T: Soars,
666{
667    type Item = T::Ref<'a>;
668
669    type IntoIter = Iter<'a, T>;
670
671    fn into_iter(self) -> Self::IntoIter {
672        self.deref().into_iter()
673    }
674}
675
676impl<'a, T> IntoIterator for &'a mut Soa<T>
677where
678    T: Soars,
679{
680    type Item = T::RefMut<'a>;
681
682    type IntoIter = IterMut<'a, T>;
683
684    fn into_iter(self) -> Self::IntoIter {
685        self.deref_mut().into_iter()
686    }
687}
688
689impl<T> Clone for Soa<T>
690where
691    T: SoaClone,
692{
693    fn clone(&self) -> Self {
694        self.iter().map(SoaClone::soa_clone).collect()
695    }
696
697    fn clone_from(&mut self, source: &Self) {
698        self.clear();
699        self.extend(source.iter().map(SoaClone::soa_clone));
700    }
701}
702
703impl<T> Extend<T> for Soa<T>
704where
705    T: Soars,
706{
707    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
708        let iter = iter.into_iter();
709        let (lower, _) = iter.size_hint();
710        self.reserve(lower);
711        for item in iter {
712            self.push(item);
713        }
714    }
715}
716
717impl<T> FromIterator<T> for Soa<T>
718where
719    T: Soars,
720{
721    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
722        let iter = iter.into_iter();
723        let (hint_min, hint_max) = iter.size_hint();
724        let cap = hint_max.unwrap_or(hint_min);
725        let mut out = Self::with_capacity(cap);
726        for item in iter {
727            out.push(item);
728        }
729        out
730    }
731}
732
733impl<T, const N: usize> From<[T; N]> for Soa<T>
734where
735    T: Soars,
736{
737    /// Allocate a `Soa<T>` and move `value`'s items into it.
738    fn from(value: [T; N]) -> Self {
739        value.into_iter().collect()
740    }
741}
742
743impl<T, const N: usize> From<&[T; N]> for Soa<T>
744where
745    T: Soars + Clone,
746{
747    /// Allocate a `Soa<T>` and fill it by cloning `value`'s items.
748    fn from(value: &[T; N]) -> Self {
749        value.as_ref().into()
750    }
751}
752
753impl<T, const N: usize> From<&mut [T; N]> for Soa<T>
754where
755    T: Soars + Clone,
756{
757    /// Allocate a `Soa<T>` and fill it by cloning `value`'s items.
758    fn from(value: &mut [T; N]) -> Self {
759        value.as_ref().into()
760    }
761}
762
763impl<T> From<&[T]> for Soa<T>
764where
765    T: Soars + Clone,
766{
767    /// Allocate a `Soa<T>` and fill it by cloning `value`'s items.
768    fn from(value: &[T]) -> Self {
769        value.iter().cloned().collect()
770    }
771}
772
773impl<T> From<&mut [T]> for Soa<T>
774where
775    T: Soars + Clone,
776{
777    /// Allocate a `Soa<T>` and fill it by cloning `value`'s items.
778    fn from(value: &mut [T]) -> Self {
779        value.as_ref().into()
780    }
781}
782
783impl<T> From<Soa<T>> for Vec<T>
784where
785    T: Soars,
786{
787    /// Allocate a `Vec<T>` and fill it by moving the contents of `value`.
788    fn from(value: Soa<T>) -> Self {
789        value.into_iter().collect()
790    }
791}
792
793impl<T> Debug for Soa<T>
794where
795    T: Soars,
796    for<'a> T::Ref<'a>: Debug,
797{
798    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
799        self.as_slice().fmt(f)
800    }
801}
802
803impl<T> PartialOrd for Soa<T>
804where
805    T: Soars,
806    for<'a> T::Ref<'a>: PartialOrd,
807{
808    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
809        self.as_slice().partial_cmp(&other.as_slice())
810    }
811}
812
813impl<T> Ord for Soa<T>
814where
815    T: Soars,
816    for<'a> T::Ref<'a>: Ord,
817{
818    fn cmp(&self, other: &Self) -> Ordering {
819        self.as_slice().cmp(&other.as_slice())
820    }
821}
822
823impl<T> Hash for Soa<T>
824where
825    T: Soars,
826    for<'a> T::Ref<'a>: Hash,
827{
828    fn hash<H: Hasher>(&self, state: &mut H) {
829        self.as_slice().hash(state)
830    }
831}
832
833impl<T> Default for Soa<T>
834where
835    T: Soars,
836{
837    fn default() -> Self {
838        Self::new()
839    }
840}
841
842impl<T> AsRef<Slice<T>> for Soa<T>
843where
844    T: Soars,
845{
846    fn as_ref(&self) -> &Slice<T> {
847        // SAFETY:
848        // - len is valid for the slice
849        // - The lifetime is bound to self
850        unsafe { self.slice.as_unsized(self.len) }
851    }
852}
853
854impl<T> AsMut<Slice<T>> for Soa<T>
855where
856    T: Soars,
857{
858    fn as_mut(&mut self) -> &mut Slice<T> {
859        // SAFETY:
860        // - len is valid for the slice
861        // - The lifetime is bound to self
862        unsafe { self.slice.as_unsized_mut(self.len) }
863    }
864}
865
866impl<T> AsRef<Self> for Soa<T>
867where
868    T: Soars,
869{
870    fn as_ref(&self) -> &Self {
871        self
872    }
873}
874
875impl<T> AsMut<Self> for Soa<T>
876where
877    T: Soars,
878{
879    fn as_mut(&mut self) -> &mut Self {
880        self
881    }
882}
883
884impl<T> Deref for Soa<T>
885where
886    T: Soars,
887{
888    type Target = Slice<T>;
889
890    fn deref(&self) -> &Self::Target {
891        self.as_ref()
892    }
893}
894
895impl<T> DerefMut for Soa<T>
896where
897    T: Soars,
898{
899    fn deref_mut(&mut self) -> &mut Self::Target {
900        self.as_mut()
901    }
902}
903
904impl<T> Borrow<Slice<T>> for Soa<T>
905where
906    T: Soars,
907{
908    fn borrow(&self) -> &Slice<T> {
909        self.as_ref()
910    }
911}
912
913impl<T> BorrowMut<Slice<T>> for Soa<T>
914where
915    T: Soars,
916{
917    fn borrow_mut(&mut self) -> &mut Slice<T> {
918        self.as_mut()
919    }
920}
921
922impl<T, R> PartialEq<R> for Soa<T>
923where
924    T: Soars,
925    R: AsSlice<Item = T> + ?Sized,
926    for<'a> T::Ref<'a>: PartialEq,
927{
928    fn eq(&self, other: &R) -> bool {
929        self.as_slice() == other.as_slice()
930    }
931}
932
933impl<T> Eq for Soa<T>
934where
935    T: Soars,
936    for<'a> T::Ref<'a>: Eq,
937{
938}
939
940impl<T> AsSlice for Soa<T>
941where
942    T: Soars,
943{
944    type Item = T;
945
946    fn as_slice(&self) -> SliceRef<'_, Self::Item> {
947        // SAFETY:
948        // - len is valid for this slice
949        // - The returned lifetime is bound to self
950        unsafe { SliceRef::from_slice(self.slice, self.len) }
951    }
952}
953
954impl<T> AsMutSlice for Soa<T>
955where
956    T: Soars,
957{
958    fn as_mut_slice(&mut self) -> crate::SliceMut<'_, Self::Item> {
959        // SAFETY:
960        // - len is valid for this slice
961        // - The returned lifetime is bound to self
962        unsafe { SliceMut::from_slice(self.slice, self.len) }
963    }
964}