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}