soapy/
soa.rs

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