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>);