soa_rs/
slice.rs

1use crate::{
2    AsMutSlice, AsSlice, Iter, IterMut, SliceMut, SliceRef, SoaDeref, SoaRaw, Soars,
3    chunks_exact::ChunksExact, index::SoaIndex, iter_raw::IterRaw,
4};
5use core::{
6    cmp::Ordering,
7    fmt::{self, Debug, Formatter},
8    hash::{Hash, Hasher},
9    marker::PhantomData,
10    ops::{ControlFlow, Deref, DerefMut},
11};
12
13/// A dynamically-sized view into the contents of a [`Soa`].
14///
15/// [`Slice`] and [`Soa`] have the same relationship as `[T]` and [`Vec`]. The
16/// related types [`SliceRef`] and [`SliceMut`] are equivalent to `&[T]` and
17/// `&mut [T]`.
18///
19/// This struct provides most of the implementation for [`Soa`], [`SliceRef`],
20/// and [`SliceMut`] via [`Deref`] impls. It is not usually constructed directly
21/// but instead used through one of these other types. The [`SliceRef`] and
22/// [`SliceMut`] wrappers attach lifetimes and ensure the same borrowing rules
23/// as `&` and `&mut`.
24///
25/// While [`Vec`] can return `&[T]` for all its slice methods, returning
26/// `&Slice` is not always possible. That is why [`SliceRef`] and [`SliceMut`]
27/// are necessary. While fat pointers allow packing length information as slice
28/// metadata, this is insufficient for SoA slices, which require multiple
29/// pointers alongside the length. Therefore, SoA slice references cannot be
30/// created on the stack and returned like normal slices can.
31///
32/// [`Soa`]: crate::Soa
33/// [`SliceRef`]: crate::SliceRef
34/// [`SliceMut`]: crate::SliceMut
35pub struct Slice<T: Soars, D: ?Sized = [()]> {
36    pub(crate) raw: T::Raw,
37    pub(crate) dst: D,
38}
39
40unsafe impl<T: Soars, D: ?Sized> Sync for Slice<T, D> where T: Sync {}
41unsafe impl<T: Soars, D: ?Sized> Send for Slice<T, D> where T: Send {}
42
43/// ```compile_fail,E0277
44/// use core::marker::PhantomData;
45/// use soa_rs::{soa, Soars};
46///
47/// fn assert_send<T: Send>(_t: T) {}
48///
49/// #[derive(Soars)]
50/// struct NoSendSync(PhantomData<*mut ()>);
51///
52/// assert_send(soa![NoSendSync(PhantomData)]);
53/// ```
54///
55/// ```compile_fail,E0277
56/// use core::marker::PhantomData;
57/// use soa_rs::{soa, Soars};
58///
59/// fn assert_sync<T: Sync>(_t: T) {}
60///
61/// #[derive(Soars)]
62/// struct NoSendSync(PhantomData<*mut ()>);
63///
64/// assert_sync(soa![NoSendSync(PhantomData)]);
65/// ```
66mod send_sync_fail {}
67
68impl<T> Slice<T, ()>
69where
70    T: Soars,
71{
72    /// Constructs a new, empty `Slice<T>`.
73    pub(crate) fn empty() -> Self {
74        Self::with_raw(<T::Raw as SoaRaw>::dangling())
75    }
76
77    /// Creates a new slice with the given [`SoaRaw`]. This is intended for use
78    /// in proc macro code, not user code.
79    #[doc(hidden)]
80    pub const fn with_raw(raw: T::Raw) -> Self {
81        Self { raw, dst: () }
82    }
83
84    /// Converts to an mutable unsized variant.
85    ///
86    /// # Safety
87    ///
88    /// - `length` must be valid for the underlying type `T`.
89    /// - The lifetime of the returned reference is unconstrained. Ensure that
90    ///   the right lifetimes are applied.
91    pub(crate) const unsafe fn as_unsized_mut<'a>(&mut self, len: usize) -> &'a mut Slice<T> {
92        let ptr = core::ptr::slice_from_raw_parts_mut(self, len) as *mut Slice<T>;
93        unsafe { &mut *ptr }
94    }
95
96    /// Converts to an unsized variant.
97    ///
98    /// # Safety
99    ///
100    /// - `length` must be valid for the underlying type `T`.
101    /// - The lifetime of the returned reference is unconstrained. Ensure that
102    ///   the right lifetimes are applied.
103    pub(crate) const unsafe fn as_unsized<'a>(&self, len: usize) -> &'a Slice<T> {
104        let ptr = core::ptr::slice_from_raw_parts(self, len) as *const Slice<T>;
105        unsafe { &*ptr }
106    }
107}
108
109impl<T, D> Slice<T, D>
110where
111    T: Soars,
112    D: ?Sized,
113{
114    /// Gets the [`SoaRaw`] the slice uses.
115    ///
116    /// Used by the [`Soars`] derive macro, but generally not intended for use
117    /// by end users.
118    #[doc(hidden)]
119    #[inline]
120    pub const fn raw(&self) -> T::Raw {
121        self.raw
122    }
123}
124
125impl<T> Slice<T>
126where
127    T: Soars,
128{
129    /// Returns the number of elements in the slice, also referred to as its
130    /// length.
131    ///
132    /// # Examples
133    ///
134    /// ```
135    /// # use soa_rs::{Soa, Soars, soa};
136    /// # #[derive(Soars)]
137    /// # #[soa_derive(Debug, PartialEq)]
138    /// # struct Foo(usize);
139    /// let soa = soa![Foo(1), Foo(2), Foo(3)];
140    /// assert_eq!(soa.len(), 3);
141    /// ```
142    pub const fn len(&self) -> usize {
143        self.dst.len()
144    }
145
146    /// Returns true if the slice contains no elements.
147    ///
148    /// # Examples
149    ///
150    /// ```
151    /// # use soa_rs::{Soa, Soars};
152    /// # #[derive(Soars)]
153    /// # #[soa_derive(Debug, PartialEq)]
154    /// # struct Foo(usize);
155    /// let mut soa = Soa::<Foo>::new();
156    /// assert!(soa.is_empty());
157    /// soa.push(Foo(1));
158    /// assert!(!soa.is_empty());
159    /// ```
160    pub const fn is_empty(&self) -> bool {
161        self.len() == 0
162    }
163
164    /// Returns an iterator over the elements.
165    ///
166    /// The iterator yields all items from start to end.
167    ///
168    /// # Examples
169    ///
170    /// ```
171    /// # use soa_rs::{Soa, Soars, soa};
172    /// # use core::fmt;
173    /// # #[derive(Soars, Debug, PartialEq)]
174    /// # #[soa_derive(Debug, PartialEq)]
175    /// # struct Foo(usize);
176    /// let soa = soa![Foo(1), Foo(2), Foo(4)];
177    /// let mut iter = soa.iter();
178    /// assert_eq!(iter.next(), Some(FooRef(&1)));
179    /// assert_eq!(iter.next(), Some(FooRef(&2)));
180    /// assert_eq!(iter.next(), Some(FooRef(&4)));
181    /// assert_eq!(iter.next(), None);
182    /// ```
183    pub const fn iter(&self) -> Iter<'_, T> {
184        Iter {
185            iter_raw: IterRaw {
186                // SAFETY: The Iter lifetime is bound to &self,
187                // which ensures the aliasing rules are respected.
188                slice: unsafe { self.as_sized() },
189                len: self.len(),
190                adapter: PhantomData,
191            },
192            _marker: PhantomData,
193        }
194    }
195
196    /// Returns an iterator over the elements that allows modifying each value.
197    ///
198    /// The iterator yields all items from start to end.
199    ///
200    /// # Examples
201    ///
202    /// ```
203    /// # use soa_rs::{Soa, Soars, soa};
204    /// # use core::fmt;
205    /// # #[derive(Soars, Debug, PartialEq)]
206    /// # #[soa_derive(Debug, PartialEq)]
207    /// # struct Foo(usize);
208    /// let mut soa = soa![Foo(1), Foo(2), Foo(4)];
209    /// for mut elem in soa.iter_mut() {
210    ///     *elem.0 *= 2;
211    /// }
212    /// assert_eq!(soa, soa![Foo(2), Foo(4), Foo(8)]);
213    /// ```
214    pub fn iter_mut(&mut self) -> IterMut<'_, T> {
215        IterMut {
216            iter_raw: IterRaw {
217                // SAFETY: The Iter lifetime is bound to &self,
218                // which ensures the aliasing rules are respected.
219                slice: unsafe { self.as_sized() },
220                len: self.len(),
221                adapter: PhantomData,
222            },
223            _marker: PhantomData,
224        }
225    }
226
227    /// Returns a reference to an element or subslice depending on the type of
228    /// index.
229    ///
230    /// - If given a position, returns a reference to the element at that
231    ///   position or None if out of bounds.
232    ///
233    /// - If given a range, returns the subslice corresponding to that range, or
234    ///   None if out of bounds.
235    ///
236    /// # Examples
237    ///
238    /// ```
239    /// # use core::fmt;
240    /// # use soa_rs::{Soa, Soars, soa, Slice, AsSlice};
241    /// # #[derive(Soars, Debug, PartialEq)]
242    /// # #[soa_derive(PartialEq, Debug)]
243    /// # struct Foo(usize);
244    /// let soa = soa![Foo(10), Foo(40), Foo(30), Foo(20)];
245    /// assert_eq!(soa.get(1), Some(FooRef(&40)));
246    /// assert!(soa.get(4).is_none());
247    /// assert_eq!(soa.get(..), Some(soa![Foo(10), Foo(40), Foo(30), Foo(20)].as_slice()));
248    /// assert_eq!(soa.get(..2), Some(soa![Foo(10), Foo(40)].as_slice()));
249    /// assert_eq!(soa.get(..=2), Some(soa![Foo(10), Foo(40), Foo(30)].as_slice()));
250    /// assert_eq!(soa.get(2..), Some(soa![Foo(30), Foo(20)].as_slice()));
251    /// assert_eq!(soa.get(1..3), Some(soa![Foo(40), Foo(30)].as_slice()));
252    /// assert_eq!(soa.get(1..=3), Some(soa![Foo(40), Foo(30), Foo(20)].as_slice()));
253    /// assert!(soa.get(2..5).is_none());
254    /// ```
255    #[inline]
256    pub fn get<I>(&self, index: I) -> Option<I::Output<'_>>
257    where
258        I: SoaIndex<T>,
259    {
260        index.get(self)
261    }
262
263    /// Returns a mutable reference to an element or subslice depending on the
264    /// type of index (see [`get`]) or `None` if the index is out of bounds.
265    ///
266    /// # Examples
267    ///
268    /// ```
269    /// # use soa_rs::{Soa, Soars, soa};
270    /// # #[derive(Soars, Debug, PartialEq)]
271    /// # #[soa_derive(Debug, PartialEq)]
272    /// # struct Foo(usize);
273    /// let mut soa = soa![Foo(1), Foo(2), Foo(3)];
274    /// if let Some(mut elem) = soa.get_mut(1) {
275    ///     *elem.0 = 42;
276    /// }
277    /// assert_eq!(soa, soa![Foo(1), Foo(42), Foo(3)]);
278    /// ```
279    ///
280    /// [`get`]: Slice::get
281    pub fn get_mut<I>(&mut self, index: I) -> Option<I::OutputMut<'_>>
282    where
283        I: SoaIndex<T>,
284    {
285        index.get_mut(self)
286    }
287
288    /// Returns a reference to the element at the given index.
289    ///
290    /// This is similar to [`Index`], which is not implementable for this type.
291    /// See [`get`] for a non-panicking version.
292    ///
293    /// # Panics
294    ///
295    /// Panics if the index is out-of-bounds, which is whenever
296    /// [`SoaIndex::get`] returns [`None`].
297    ///
298    /// # Examples
299    ///
300    /// ```
301    /// # use core::fmt;
302    /// # use soa_rs::{Soa, Soars, soa};
303    /// # #[derive(Soars, Debug, PartialEq)]
304    /// # #[soa_derive(Debug, PartialEq)]
305    /// # struct Foo(usize);
306    /// let soa = soa![Foo(10), Foo(40), Foo(30), Foo(90)];
307    /// assert_eq!(soa.idx(3), FooRef(&90));
308    /// assert_eq!(soa.idx(1..3), soa![Foo(40), Foo(30)]);
309    /// ```
310    ///
311    /// [`Index`]: core::ops::Index
312    /// [`get`]: Slice::get
313    pub fn idx<I>(&self, index: I) -> I::Output<'_>
314    where
315        I: SoaIndex<T>,
316    {
317        self.get(index).expect("index out of bounds")
318    }
319
320    /// Returns a mutable reference to the element at the given index.
321    ///
322    /// This is similar to [`IndexMut`], which is not implementable for this
323    /// type. See [`get_mut`] for a non-panicking version.
324    ///
325    /// # Panics
326    ///
327    /// Panics if the index is out-of-bounds, which is whenever
328    /// [`SoaIndex::get_mut`] returns [`None`].
329    ///
330    /// # Examples
331    ///
332    /// ```
333    /// # use core::fmt;
334    /// # use soa_rs::{Soa, Soars, soa};
335    /// # #[derive(Soars, Debug, PartialEq)]
336    /// # #[soa_derive(Debug, PartialEq)]
337    /// # struct Foo(usize);
338    /// let mut soa = soa![Foo(10), Foo(20), Foo(30)];
339    /// *soa.idx_mut(1).0 = 42;
340    /// assert_eq!(soa, soa![Foo(10), Foo(42), Foo(30)]);
341    /// ```
342    ///
343    /// [`IndexMut`]: core::ops::Index
344    /// [`get_mut`]: Slice::get_mut
345    pub fn idx_mut<I>(&mut self, index: I) -> I::OutputMut<'_>
346    where
347        I: SoaIndex<T>,
348    {
349        self.get_mut(index).expect("index out of bounds")
350    }
351
352    /// Divides one slice into two at an index.
353    ///
354    /// The first will contain all indices from `[0, mid)` (excluding
355    /// the index `mid` itself) and the second will contain all
356    /// indices from `[mid, len)` (excluding the index `len` itself).
357    ///
358    /// # Panics
359    ///
360    /// Panics if `mid > len`.  For a non-panicking alternative see
361    /// [`split_at_checked`](Slice::split_at_checked).
362    ///
363    /// # Examples
364    ///
365    /// ```
366    /// # use soa_rs::{Soa, Soars, soa};
367    /// # #[derive(Soars, Debug, PartialEq)]
368    /// # #[soa_derive(Debug, PartialEq)]
369    /// # struct Foo(usize);
370    /// let soa = soa![Foo(1), Foo(2), Foo(3), Foo(4), Foo(5)];
371    /// let (l, r) = soa.split_at(3);
372    /// assert_eq!(l, soa![Foo(1), Foo(2), Foo(3)]);
373    /// assert_eq!(r, soa![Foo(4), Foo(5)]);
374    /// ```
375    #[must_use]
376    pub fn split_at(&self, mid: usize) -> (SliceRef<'_, T>, SliceRef<'_, T>) {
377        match self.split_at_checked(mid) {
378            Some(pair) => pair,
379            None => panic!("mid > len"),
380        }
381    }
382
383    /// Divides one mutable slice into two at an index.
384    ///
385    /// The first will contain all indices from `[0, mid)` (excluding
386    /// the index `mid` itself) and the second will contain all
387    /// indices from `[mid, len)` (excluding the index `len` itself).
388    ///
389    /// # Panics
390    ///
391    /// Panics if `mid > len`.  For a non-panicking alternative see
392    /// [`split_at_mut_checked`](Slice::split_at_mut_checked).
393    ///
394    /// # Examples
395    ///
396    /// ```
397    /// # use soa_rs::{Soa, Soars, soa};
398    /// # #[derive(Soars, Debug, PartialEq)]
399    /// # #[soa_derive(Debug, PartialEq)]
400    /// # struct Foo(usize);
401    /// let mut soa = soa![Foo(1), Foo(2), Foo(3), Foo(4), Foo(5)];
402    /// let (l, r) = soa.split_at_mut(3);
403    /// assert_eq!(l, soa![Foo(1), Foo(2), Foo(3)]);
404    /// assert_eq!(r, soa![Foo(4), Foo(5)]);
405    /// ```
406    #[must_use]
407    pub fn split_at_mut(&mut self, mid: usize) -> (SliceMut<'_, T>, SliceMut<'_, T>) {
408        match self.split_at_mut_checked(mid) {
409            Some(pair) => pair,
410            None => panic!("mid > len"),
411        }
412    }
413
414    /// Divides one slice into two at an index,
415    /// returning `None` if the slice is too short.
416    ///
417    /// If `mid ≤ len` returns a pair of slices where the first will contain all
418    /// indices from `[0, mid)` (excluding the index `mid` itself) and the
419    /// second will contain all indices from `[mid, len)` (excluding the index
420    /// `len` itself).
421    ///
422    /// Otherwise, if `mid > len`, returns `None`.
423    ///
424    /// # Examples
425    ///
426    /// ```
427    /// # use soa_rs::{Soa, Soars, soa};
428    /// # #[derive(Soars, Debug, PartialEq)]
429    /// # #[soa_derive(Debug, PartialEq)]
430    /// # struct Foo(usize);
431    /// let soa = soa![Foo(1), Foo(2), Foo(3), Foo(4)];
432    ///
433    /// {
434    ///     let (l, r) = soa.split_at_checked(0).unwrap();
435    ///     assert_eq!(l, soa![]);
436    ///     assert_eq!(r, soa);
437    /// }
438    ///
439    /// {
440    ///     let (l, r) = soa.split_at_checked(2).unwrap();
441    ///     assert_eq!(l, soa![Foo(1), Foo(2)]);
442    ///     assert_eq!(r, soa![Foo(3), Foo(4)]);
443    /// }
444    ///
445    /// {
446    ///     let (l, r) = soa.split_at_checked(4).unwrap();
447    ///     assert_eq!(l, soa);
448    ///     assert_eq!(r, soa![]);
449    /// }
450    ///
451    /// assert_eq!(None, soa.split_at_checked(5));
452    #[must_use]
453    pub fn split_at_checked(&self, mid: usize) -> Option<(SliceRef<'_, T>, SliceRef<'_, T>)> {
454        // SAFETY:
455        // Don't use `bool::then_some` here because constructing an invalid reference is unsound,
456        // even if it is not accessed
457        (mid <= self.len()).then(|| unsafe { self.split_at_unchecked(mid) })
458    }
459
460    /// Divides one mutable slice into two at an index,
461    /// returning `None` if the slice is too short.
462    ///
463    /// If `mid ≤ len` returns a pair of slices where the first will contain all
464    /// indices from `[0, mid)` (excluding the index `mid` itself) and the
465    /// second will contain all indices from `[mid, len)` (excluding the index
466    /// `len` itself).
467    ///
468    /// Otherwise, if `mid > len`, returns `None`.
469    ///
470    /// # Examples
471    ///
472    /// ```
473    /// # use soa_rs::{Soa, Soars, soa};
474    /// # #[derive(Soars, Debug, PartialEq)]
475    /// # #[soa_derive(Debug, PartialEq)]
476    /// # struct Foo(usize);
477    /// let mut soa = soa![Foo(1), Foo(2), Foo(3), Foo(4)];
478    ///
479    /// {
480    ///     let (l, r) = soa.split_at_mut_checked(0).unwrap();
481    ///     assert_eq!(l, soa![]);
482    ///     assert_eq!(r, soa![Foo(1), Foo(2), Foo(3), Foo(4)]);
483    /// }
484    ///
485    /// {
486    ///     let (l, r) = soa.split_at_mut_checked(2).unwrap();
487    ///     assert_eq!(l, soa![Foo(1), Foo(2)]);
488    ///     assert_eq!(r, soa![Foo(3), Foo(4)]);
489    /// }
490    ///
491    /// {
492    ///     let (l, r) = soa.split_at_mut_checked(4).unwrap();
493    ///     assert_eq!(l, soa![Foo(1), Foo(2), Foo(3), Foo(4)]);
494    ///     assert_eq!(r, soa![]);
495    /// }
496    ///
497    /// assert_eq!(None, soa.split_at_mut_checked(5));
498    #[must_use]
499    pub fn split_at_mut_checked(
500        &mut self,
501        mid: usize,
502    ) -> Option<(SliceMut<'_, T>, SliceMut<'_, T>)> {
503        // SAFETY:
504        // Don't use `bool::then_some` here because constructing an invalid reference is unsound,
505        // even if it is not accessed
506        (mid <= self.len()).then(|| unsafe { self.split_at_mut_unchecked(mid) })
507    }
508
509    /// Divides one slice into two at an index without doing bounds checking.
510    ///
511    /// The first will contain all indices from `[0, mid)` (excluding
512    /// the index `mid` itself) and the second will contain all
513    /// indices from `[mid, len)` (excluding the index `len` itself).
514    ///
515    /// For a safe alternative, see [`split_at`].
516    ///
517    /// # Safety
518    ///
519    /// Calling this method with an out-of-bounds index is undefined behavior,
520    /// even if the resulting reference is not used.
521    ///
522    /// [`split_at`]: Slice::split_at
523    ///
524    /// # Examples
525    ///
526    /// ```
527    /// # use soa_rs::{Soa, Soars, soa};
528    /// # #[derive(Soars, Debug, PartialEq)]
529    /// # #[soa_derive(Debug, PartialEq)]
530    /// # struct Foo(usize);
531    /// let soa = soa![Foo(1), Foo(2), Foo(3)];
532    /// let (l, r) = unsafe { soa.split_at_unchecked(2) };
533    /// assert_eq!(l, soa![Foo(1), Foo(2)]);
534    /// assert_eq!(r, soa![Foo(3)]);
535    /// ```
536    #[must_use]
537    pub unsafe fn split_at_unchecked(&self, mid: usize) -> (SliceRef<'_, T>, SliceRef<'_, T>) {
538        let (l, r, r_len) = self.split_at_parts(mid);
539        // SAFETY: Lifetime matches that of self
540        let l = unsafe { SliceRef::from_slice(l, mid) };
541        let r = unsafe { SliceRef::from_slice(r, r_len) };
542        (l, r)
543    }
544
545    /// Divides one mutable slice into two at an index without doing bounds checking.
546    ///
547    /// The first will contain all indices from `[0, mid)` (excluding
548    /// the index `mid` itself) and the second will contain all
549    /// indices from `[mid, len)` (excluding the index `len` itself).
550    ///
551    /// For a safe alternative, see [`split_at_mut`].
552    ///
553    /// # Safety
554    ///
555    /// Calling this method with an out-of-bounds index is undefined behavior,
556    /// even if the resulting reference is not used.
557    ///
558    /// [`split_at_mut`]: Slice::split_at_mut
559    ///
560    /// # Examples
561    ///
562    /// ```
563    /// # use soa_rs::{Soa, Soars, soa};
564    /// # #[derive(Soars, Debug, PartialEq)]
565    /// # #[soa_derive(Debug, PartialEq)]
566    /// # struct Foo(usize);
567    /// let mut soa = soa![Foo(1), Foo(2), Foo(3)];
568    /// let (l, r) = unsafe { soa.split_at_mut_unchecked(1) };
569    /// assert_eq!(l, soa![Foo(1)]);
570    /// assert_eq!(r, soa![Foo(2), Foo(3)]);
571    /// ```
572    #[must_use]
573    pub unsafe fn split_at_mut_unchecked(
574        &mut self,
575        mid: usize,
576    ) -> (SliceMut<'_, T>, SliceMut<'_, T>) {
577        let (l, r, r_len) = self.split_at_parts(mid);
578        // SAFETY: Lifetime matches that of self
579        let l = unsafe { SliceMut::from_slice(l, mid) };
580        let r = unsafe { SliceMut::from_slice(r, r_len) };
581        (l, r)
582    }
583
584    fn split_at_parts(&self, mid: usize) -> (Slice<T, ()>, Slice<T, ()>, usize) {
585        (
586            unsafe { self.as_sized() },
587            Slice::with_raw(unsafe { self.raw.offset(mid) }),
588            self.len() - mid,
589        )
590    }
591
592    /// Swaps the position of two elements.
593    ///
594    /// # Arguments
595    ///
596    /// - `a`: The index of the first element
597    /// - `b`: The index of the second element
598    ///
599    /// # Panics
600    ///
601    /// Panics if `a` or `b` is out of bounds.
602    ///
603    /// # Examples
604    ///
605    /// ```
606    /// # use soa_rs::{Soa, Soars, soa};
607    /// # #[derive(Soars, Debug, PartialEq)]
608    /// # #[soa_derive(Debug, PartialEq)]
609    /// # struct Foo(usize);
610    /// let mut soa = soa![Foo(0), Foo(1), Foo(2), Foo(3), Foo(4)];
611    /// soa.swap(2, 4);
612    /// assert_eq!(soa, soa![Foo(0), Foo(1), Foo(4), Foo(3), Foo(2)]);
613    /// ```
614    pub fn swap(&mut self, a: usize, b: usize) {
615        if a >= self.len() || b >= self.len() {
616            panic!("index out of bounds");
617        }
618
619        // SAFETY: We bounds checked a and b
620        unsafe {
621            let a = self.raw().offset(a);
622            let b = self.raw().offset(b);
623            let tmp = a.get();
624            b.copy_to(a, 1);
625            b.set(tmp);
626        }
627    }
628
629    /// Returns the first element of the slice, or None if empty.
630    ///
631    /// # Examples
632    ///
633    /// ```
634    /// # use soa_rs::{Soa, Soars, soa};
635    /// # #[derive(Soars, Debug, PartialEq)]
636    /// # #[soa_derive(Debug, PartialEq)]
637    /// # struct Foo(usize);
638    /// let soa = soa![Foo(10), Foo(40), Foo(30)];
639    /// assert_eq!(soa.first(), Some(FooRef(&10)));
640    ///
641    /// let soa = Soa::<Foo>::new();
642    /// assert_eq!(soa.first(), None);
643    /// ```
644    pub fn first(&self) -> Option<T::Ref<'_>> {
645        self.get(0)
646    }
647
648    /// Returns a mutable reference to the first element of the slice, or None if empty.
649    ///
650    /// # Examples
651    ///
652    /// ```
653    /// # use soa_rs::{Soa, Soars, soa};
654    /// # #[derive(Soars, Debug, PartialEq)]
655    /// # #[soa_derive(Debug, PartialEq)]
656    /// # struct Foo(usize);
657    /// let mut soa = soa![Foo(0), Foo(1), Foo(2)];
658    /// if let Some(mut first) = soa.first_mut() {
659    ///     *first.0 = 5;
660    /// }
661    /// assert_eq!(soa, soa![Foo(5), Foo(1), Foo(2)]);
662    /// ```
663    pub fn first_mut(&mut self) -> Option<T::RefMut<'_>> {
664        self.get_mut(0)
665    }
666
667    /// Returns the last element of the slice, or None if empty.
668    ///
669    /// # Examples
670    ///
671    /// ```
672    /// # use soa_rs::{Soa, Soars, soa};
673    /// # #[derive(Soars, Debug, PartialEq)]
674    /// # #[soa_derive(Debug, PartialEq)]
675    /// # struct Foo(usize);
676    /// let soa = soa![Foo(10), Foo(40), Foo(30)];
677    /// assert_eq!(soa.last(), Some(FooRef(&30)));
678    ///
679    /// let soa = Soa::<Foo>::new();
680    /// assert_eq!(soa.last(), None);
681    /// ```
682    pub fn last(&self) -> Option<T::Ref<'_>> {
683        self.get(self.len().saturating_sub(1))
684    }
685
686    /// Returns a mutable reference to the last element of the slice, or None if empty.
687    ///
688    /// # Examples
689    ///
690    /// ```
691    /// # use soa_rs::{Soa, Soars, soa};
692    /// # #[derive(Soars, Debug, PartialEq)]
693    /// # #[soa_derive(Debug, PartialEq)]
694    /// # struct Foo(usize);
695    /// let mut soa = soa![Foo(0), Foo(1), Foo(2)];
696    /// if let Some(mut last) = soa.last_mut() {
697    ///     *last.0 = 5;
698    /// }
699    /// assert_eq!(soa, soa![Foo(0), Foo(1), Foo(5)]);
700    /// ```
701    pub fn last_mut(&mut self) -> Option<T::RefMut<'_>> {
702        self.get_mut(self.len().saturating_sub(1))
703    }
704
705    /// Returns an iterator over `chunk_size` elements of the slice at a time,
706    /// starting at the beginning of the slice.
707    ///
708    /// The chunks are slices and do not overlap. If `chunk_size` does not divide
709    /// the length of the slice, then the last up to `chunk_size-1` elements will
710    /// be omitted and can be retrieved from the [`remainder`] function of the
711    /// iterator.
712    ///
713    /// Due to each chunk having exactly `chunk_size` elements, the compiler can
714    /// often optimize the resulting code better than in the case of chunks.
715    ///
716    /// [`remainder`]: ChunksExact::remainder
717    ///
718    /// # Examples
719    ///
720    /// ```
721    /// # use soa_rs::{Soa, Soars, soa, AsSlice};
722    /// # #[derive(Soars, Debug, PartialEq)]
723    /// # #[soa_derive(Debug, PartialEq)]
724    /// # struct Foo(char);
725    /// let soa = soa![Foo('l'), Foo('o'), Foo('r'), Foo('e'), Foo('m')];
726    /// let mut iter = soa.chunks_exact(2);
727    /// assert_eq!(iter.next(), Some(soa![Foo('l'), Foo('o')].as_slice()));
728    /// assert_eq!(iter.next(), Some(soa![Foo('r'), Foo('e')].as_slice()));
729    /// assert!(iter.next().is_none());
730    /// assert_eq!(iter.remainder(), &soa![Foo('m')]);
731    /// ```
732    pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T> {
733        if chunk_size == 0 {
734            panic!("chunk size must be nonzero")
735        }
736
737        ChunksExact::new(self, chunk_size)
738    }
739
740    /// Returns a collection of slices for each field of the slice.
741    ///
742    /// For convenience, slices can also be aquired using the getter methods for
743    /// individual fields.
744    ///
745    /// # Examples
746    ///
747    /// ```
748    /// # use soa_rs::{Soa, Soars, soa};
749    /// # #[derive(Soars, Debug, PartialEq)]
750    /// # #[soa_derive(Debug, PartialEq)]
751    /// # struct Foo {
752    /// #     foo: u8,
753    /// #     bar: u8,
754    /// # }
755    /// let soa = soa![Foo { foo: 1, bar: 2 }, Foo { foo: 3, bar: 4 }];
756    /// let slices = soa.slices();
757    /// assert_eq!(slices.foo, soa.foo());
758    /// assert_eq!(slices.bar, soa.bar());
759    /// ```
760    pub fn slices(&self) -> T::Slices<'_> {
761        // SAFETY:
762        // - The returned lifetime is bound to self
763        // - len elements are allocated and initialized
764        unsafe { self.raw.slices(self.len()) }
765    }
766
767    /// Returns a collection of mutable slices for each field of the slice.
768    ///
769    /// For convenience, individual mutable slices can also be aquired using the
770    /// getter methods for individual fields. This method is necessary to be
771    /// able to mutably borrow multiple SoA fields simultaneously.
772    ///
773    /// # Examples
774    ///
775    /// ```
776    /// # use soa_rs::{Soa, Soars, soa};
777    /// # #[derive(Soars, Debug, PartialEq)]
778    /// # #[soa_derive(Debug, PartialEq)]
779    /// # struct Foo {
780    /// #     foo: u8,
781    /// #     bar: u8,
782    /// # }
783    /// let mut soa = soa![Foo { foo: 1, bar: 0 }, Foo { foo: 2, bar: 0 }];
784    /// let slices = soa.slices_mut();
785    /// for (foo, bar) in slices.foo.iter().zip(slices.bar) {
786    ///     *bar = foo * 2;
787    /// }
788    /// assert_eq!(soa.bar(), [2, 4]);
789    /// ```
790    pub fn slices_mut(&mut self) -> T::SlicesMut<'_> {
791        // SAFETY:
792        // - The returned lifetime is bound to self
793        // - len elements are allocated and initialized
794        unsafe { self.raw.slices_mut(self.len()) }
795    }
796
797    /// Converts from an unsized variant to sized variant
798    ///
799    /// # Safety
800    ///
801    /// Since this returns an owned value, it implicitly extends the lifetime &
802    /// in an unbounded way. The caller must ensure proper lifetimes with, for
803    /// example, [`PhantomData`].
804    ///
805    /// [`PhantomData`]: core::marker::PhantomData
806    pub(crate) const unsafe fn as_sized(&self) -> Slice<T, ()> {
807        let ptr = core::ptr::from_ref(self).cast();
808        unsafe { *ptr }
809    }
810}
811
812impl<T> Clone for Slice<T, ()>
813where
814    T: Soars,
815{
816    fn clone(&self) -> Self {
817        *self
818    }
819}
820
821impl<T> Copy for Slice<T, ()> where T: Soars {}
822
823impl<'a, T> IntoIterator for &'a Slice<T>
824where
825    T: Soars,
826{
827    type Item = T::Ref<'a>;
828    type IntoIter = Iter<'a, T>;
829
830    fn into_iter(self) -> Self::IntoIter {
831        self.iter()
832    }
833}
834
835impl<'a, T> IntoIterator for &'a mut Slice<T>
836where
837    T: Soars,
838{
839    type Item = T::RefMut<'a>;
840    type IntoIter = IterMut<'a, T>;
841
842    fn into_iter(self) -> Self::IntoIter {
843        self.iter_mut()
844    }
845}
846
847impl<T, R> PartialEq<R> for Slice<T>
848where
849    T: Soars,
850    R: AsSlice<Item = T> + ?Sized,
851    for<'a> T::Ref<'a>: PartialEq,
852{
853    fn eq(&self, other: &R) -> bool {
854        let other = other.as_slice();
855        self.len() == other.len() && self.iter().zip(other.iter()).all(|(me, them)| me == them)
856    }
857}
858
859impl<T> Eq for Slice<T>
860where
861    T: Soars,
862    for<'a> T::Ref<'a>: Eq,
863{
864}
865
866impl<T> Debug for Slice<T>
867where
868    T: Soars,
869    for<'a> T::Ref<'a>: Debug,
870{
871    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
872        let mut list = f.debug_list();
873        self.iter().for_each(|item| {
874            list.entry(&item);
875        });
876        list.finish()
877    }
878}
879
880impl<T> PartialOrd for Slice<T>
881where
882    T: Soars,
883    for<'a> T::Ref<'a>: PartialOrd,
884{
885    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
886        match self
887            .iter()
888            .zip(other.iter())
889            .try_fold(Ordering::Equal, |_, (a, b)| match a.partial_cmp(&b) {
890                ord @ (None | Some(Ordering::Less | Ordering::Greater)) => ControlFlow::Break(ord),
891                Some(Ordering::Equal) => ControlFlow::Continue(self.len().cmp(&other.len())),
892            }) {
893            ControlFlow::Continue(ord) => Some(ord),
894            ControlFlow::Break(ord) => ord,
895        }
896    }
897}
898
899impl<T> Ord for Slice<T>
900where
901    T: Soars,
902    for<'a> T::Ref<'a>: Ord,
903{
904    fn cmp(&self, other: &Self) -> Ordering {
905        match self
906            .iter()
907            .zip(other.iter())
908            .try_fold(Ordering::Equal, |_, (a, b)| match a.cmp(&b) {
909                ord @ (Ordering::Greater | Ordering::Less) => ControlFlow::Break(ord),
910                Ordering::Equal => ControlFlow::Continue(self.len().cmp(&other.len())),
911            }) {
912            ControlFlow::Continue(ord) | ControlFlow::Break(ord) => ord,
913        }
914    }
915}
916
917impl<T> Hash for Slice<T>
918where
919    T: Soars,
920    for<'a> T::Ref<'a>: Hash,
921{
922    fn hash<H: Hasher>(&self, state: &mut H) {
923        self.len().hash(state);
924        for item in self {
925            item.hash(state);
926        }
927    }
928}
929
930impl<T> Deref for Slice<T>
931where
932    T: Soars,
933{
934    type Target = T::Deref;
935
936    fn deref(&self) -> &Self::Target {
937        <T::Deref as SoaDeref>::from_slice(self)
938    }
939}
940
941impl<T> DerefMut for Slice<T>
942where
943    T: Soars,
944{
945    fn deref_mut(&mut self) -> &mut Self::Target {
946        <T::Deref as SoaDeref>::from_slice_mut(self)
947    }
948}
949
950impl<T> AsRef<Slice<T>> for Slice<T>
951where
952    T: Soars,
953{
954    fn as_ref(&self) -> &Self {
955        self
956    }
957}
958
959impl<T> AsMut<Slice<T>> for Slice<T>
960where
961    T: Soars,
962{
963    fn as_mut(&mut self) -> &mut Self {
964        self
965    }
966}
967
968impl<T> AsSlice for Slice<T>
969where
970    T: Soars,
971{
972    type Item = T;
973
974    fn as_slice(&self) -> SliceRef<'_, Self::Item> {
975        // SAFETY: The returned lifetime is bound to self
976        unsafe { SliceRef::from_slice(self.as_sized(), self.len()) }
977    }
978}
979
980impl<T> AsMutSlice for Slice<T>
981where
982    T: Soars,
983{
984    fn as_mut_slice(&mut self) -> SliceMut<'_, Self::Item> {
985        // SAFETY: The returned lifetime is bound to self
986        unsafe { SliceMut::from_slice(self.as_sized(), self.len()) }
987    }
988}