soa_rs/
slice.rs

1use crate::{
2    chunks_exact::ChunksExact, index::SoaIndex, iter_raw::IterRaw, AsMutSlice, AsSlice, Iter,
3    IterMut, SliceMut, SliceRef, SoaDeref, SoaRaw, Soars,
4};
5use std::{
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 std::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 std::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 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) unsafe fn as_unsized_mut<'a>(&mut self, len: usize) -> &'a mut Slice<T> {
92        let ptr = std::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) unsafe fn as_unsized<'a>(&self, len: usize) -> &'a Slice<T> {
104        let ptr = std::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 std::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 std::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 std::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 std::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`]: std::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 std::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`]: std::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    /// Swaps the position of two elements.
353    ///
354    /// # Arguments
355    ///
356    /// - `a`: The index of the first element
357    /// - `b`: The index of the second element
358    ///
359    /// # Panics
360    ///
361    /// Panics if `a` or `b` is out of bounds.
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 mut soa = soa![Foo(0), Foo(1), Foo(2), Foo(3), Foo(4)];
371    /// soa.swap(2, 4);
372    /// assert_eq!(soa, soa![Foo(0), Foo(1), Foo(4), Foo(3), Foo(2)]);
373    /// ```
374    pub fn swap(&mut self, a: usize, b: usize) {
375        if a >= self.len() || b >= self.len() {
376            panic!("index out of bounds");
377        }
378
379        // SAFETY: We bounds checked a and b
380        unsafe {
381            let a = self.raw().offset(a);
382            let b = self.raw().offset(b);
383            let tmp = a.get();
384            b.copy_to(a, 1);
385            b.set(tmp);
386        }
387    }
388
389    /// Returns the first element of the slice, or None if empty.
390    ///
391    /// # Examples
392    ///
393    /// ```
394    /// # use soa_rs::{Soa, Soars, soa};
395    /// # #[derive(Soars, Debug, PartialEq)]
396    /// # #[soa_derive(Debug, PartialEq)]
397    /// # struct Foo(usize);
398    /// let soa = soa![Foo(10), Foo(40), Foo(30)];
399    /// assert_eq!(soa.first(), Some(FooRef(&10)));
400    ///
401    /// let soa = Soa::<Foo>::new();
402    /// assert_eq!(soa.first(), None);
403    /// ```
404    pub fn first(&self) -> Option<T::Ref<'_>> {
405        self.get(0)
406    }
407
408    /// Returns a mutable reference to the first element of the slice, or None if empty.
409    ///
410    /// # Examples
411    ///
412    /// ```
413    /// # use soa_rs::{Soa, Soars, soa};
414    /// # #[derive(Soars, Debug, PartialEq)]
415    /// # #[soa_derive(Debug, PartialEq)]
416    /// # struct Foo(usize);
417    /// let mut soa = soa![Foo(0), Foo(1), Foo(2)];
418    /// if let Some(mut first) = soa.first_mut() {
419    ///     *first.0 = 5;
420    /// }
421    /// assert_eq!(soa, soa![Foo(5), Foo(1), Foo(2)]);
422    /// ```
423    pub fn first_mut(&mut self) -> Option<T::RefMut<'_>> {
424        self.get_mut(0)
425    }
426
427    /// Returns the last element of the slice, or None if empty.
428    ///
429    /// # Examples
430    ///
431    /// ```
432    /// # use soa_rs::{Soa, Soars, soa};
433    /// # #[derive(Soars, Debug, PartialEq)]
434    /// # #[soa_derive(Debug, PartialEq)]
435    /// # struct Foo(usize);
436    /// let soa = soa![Foo(10), Foo(40), Foo(30)];
437    /// assert_eq!(soa.last(), Some(FooRef(&30)));
438    ///
439    /// let soa = Soa::<Foo>::new();
440    /// assert_eq!(soa.last(), None);
441    /// ```
442    pub fn last(&self) -> Option<T::Ref<'_>> {
443        self.get(self.len().saturating_sub(1))
444    }
445
446    /// Returns a mutable reference to the last element of the slice, or None if empty.
447    ///
448    /// # Examples
449    ///
450    /// ```
451    /// # use soa_rs::{Soa, Soars, soa};
452    /// # #[derive(Soars, Debug, PartialEq)]
453    /// # #[soa_derive(Debug, PartialEq)]
454    /// # struct Foo(usize);
455    /// let mut soa = soa![Foo(0), Foo(1), Foo(2)];
456    /// if let Some(mut last) = soa.last_mut() {
457    ///     *last.0 = 5;
458    /// }
459    /// assert_eq!(soa, soa![Foo(0), Foo(1), Foo(5)]);
460    /// ```
461    pub fn last_mut(&mut self) -> Option<T::RefMut<'_>> {
462        self.get_mut(self.len().saturating_sub(1))
463    }
464
465    /// Returns an iterator over `chunk_size` elements of the slice at a time,
466    /// starting at the beginning of the slice.
467    ///
468    /// The chunks are slices and do not overlap. If `chunk_size` does not divide
469    /// the length of the slice, then the last up to `chunk_size-1` elements will
470    /// be omitted and can be retrieved from the [`remainder`] function of the
471    /// iterator.
472    ///
473    /// Due to each chunk having exactly `chunk_size` elements, the compiler can
474    /// often optimize the resulting code better than in the case of chunks.
475    ///
476    /// [`remainder`]: ChunksExact::remainder
477    ///
478    /// # Examples
479    ///
480    /// ```
481    /// # use soa_rs::{Soa, Soars, soa, AsSlice};
482    /// # #[derive(Soars, Debug, PartialEq)]
483    /// # #[soa_derive(Debug, PartialEq)]
484    /// # struct Foo(char);
485    /// let soa = soa![Foo('l'), Foo('o'), Foo('r'), Foo('e'), Foo('m')];
486    /// let mut iter = soa.chunks_exact(2);
487    /// assert_eq!(iter.next(), Some(soa![Foo('l'), Foo('o')].as_slice()));
488    /// assert_eq!(iter.next(), Some(soa![Foo('r'), Foo('e')].as_slice()));
489    /// assert!(iter.next().is_none());
490    /// assert_eq!(iter.remainder(), &soa![Foo('m')]);
491    /// ```
492    pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T> {
493        if chunk_size == 0 {
494            panic!("chunk size must be nonzero")
495        }
496
497        ChunksExact::new(self, chunk_size)
498    }
499
500    /// Returns a collection of slices for each field of the slice.
501    ///
502    /// For convenience, slices can also be aquired using the getter methods for
503    /// individual fields.
504    ///
505    /// # Examples
506    ///
507    /// ```
508    /// # use soa_rs::{Soa, Soars, soa};
509    /// # #[derive(Soars, Debug, PartialEq)]
510    /// # #[soa_derive(Debug, PartialEq)]
511    /// # struct Foo {
512    /// #     foo: u8,
513    /// #     bar: u8,
514    /// # }
515    /// let soa = soa![Foo { foo: 1, bar: 2 }, Foo { foo: 3, bar: 4 }];
516    /// let slices = soa.slices();
517    /// assert_eq!(slices.foo, soa.foo());
518    /// assert_eq!(slices.bar, soa.bar());
519    /// ```
520    pub fn slices(&self) -> T::Slices<'_> {
521        // SAFETY:
522        // - The returned lifetime is bound to self
523        // - len elements are allocated and initialized
524        unsafe { self.raw.slices(self.len()) }
525    }
526
527    /// Returns a collection of mutable slices for each field of the slice.
528    ///
529    /// For convenience, individual mutable slices can also be aquired using the
530    /// getter methods for individual fields. This method is necessary to be
531    /// able to mutably borrow multiple SoA fields simultaneously.
532    ///
533    /// # Examples
534    ///
535    /// ```
536    /// # use soa_rs::{Soa, Soars, soa};
537    /// # #[derive(Soars, Debug, PartialEq)]
538    /// # #[soa_derive(Debug, PartialEq)]
539    /// # struct Foo {
540    /// #     foo: u8,
541    /// #     bar: u8,
542    /// # }
543    /// let mut soa = soa![Foo { foo: 1, bar: 0 }, Foo { foo: 2, bar: 0 }];
544    /// let slices = soa.slices_mut();
545    /// for (foo, bar) in slices.foo.iter().zip(slices.bar) {
546    ///     *bar = foo * 2;
547    /// }
548    /// assert_eq!(soa.bar(), [2, 4]);
549    /// ```
550    pub fn slices_mut(&mut self) -> T::SlicesMut<'_> {
551        // SAFETY:
552        // - The returned lifetime is bound to self
553        // - len elements are allocated and initialized
554        unsafe { self.raw.slices_mut(self.len()) }
555    }
556
557    /// Converts from an unsized variant to sized variant
558    ///
559    /// # Safety
560    ///
561    /// Since this returns an owned value, it implicitly extends the lifetime &
562    /// in an unbounded way. The caller must ensure proper lifetimes with, for
563    /// example, [`PhantomData`].
564    ///
565    /// [`PhantomData`]: std::marker::PhantomData
566    pub(crate) const unsafe fn as_sized(&self) -> Slice<T, ()> {
567        let ptr = std::ptr::from_ref(self).cast();
568        unsafe { *ptr }
569    }
570}
571
572impl<T> Clone for Slice<T, ()>
573where
574    T: Soars,
575{
576    fn clone(&self) -> Self {
577        *self
578    }
579}
580
581impl<T> Copy for Slice<T, ()> where T: Soars {}
582
583impl<'a, T> IntoIterator for &'a Slice<T>
584where
585    T: Soars,
586{
587    type Item = T::Ref<'a>;
588    type IntoIter = Iter<'a, T>;
589
590    fn into_iter(self) -> Self::IntoIter {
591        self.iter()
592    }
593}
594
595impl<'a, T> IntoIterator for &'a mut Slice<T>
596where
597    T: Soars,
598{
599    type Item = T::RefMut<'a>;
600    type IntoIter = IterMut<'a, T>;
601
602    fn into_iter(self) -> Self::IntoIter {
603        self.iter_mut()
604    }
605}
606
607impl<T, R> PartialEq<R> for Slice<T>
608where
609    T: Soars,
610    R: AsSlice<Item = T> + ?Sized,
611    for<'a> T::Ref<'a>: PartialEq,
612{
613    fn eq(&self, other: &R) -> bool {
614        let other = other.as_slice();
615        self.len() == other.len() && self.iter().zip(other.iter()).all(|(me, them)| me == them)
616    }
617}
618
619impl<T> Eq for Slice<T>
620where
621    T: Soars,
622    for<'a> T::Ref<'a>: Eq,
623{
624}
625
626impl<T> Debug for Slice<T>
627where
628    T: Soars,
629    for<'a> T::Ref<'a>: Debug,
630{
631    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
632        let mut list = f.debug_list();
633        self.iter().for_each(|item| {
634            list.entry(&item);
635        });
636        list.finish()
637    }
638}
639
640impl<T> PartialOrd for Slice<T>
641where
642    T: Soars,
643    for<'a> T::Ref<'a>: PartialOrd,
644{
645    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
646        match self
647            .iter()
648            .zip(other.iter())
649            .try_fold(Ordering::Equal, |_, (a, b)| match a.partial_cmp(&b) {
650                ord @ (None | Some(Ordering::Less | Ordering::Greater)) => ControlFlow::Break(ord),
651                Some(Ordering::Equal) => ControlFlow::Continue(self.len().cmp(&other.len())),
652            }) {
653            ControlFlow::Continue(ord) => Some(ord),
654            ControlFlow::Break(ord) => ord,
655        }
656    }
657}
658
659impl<T> Ord for Slice<T>
660where
661    T: Soars,
662    for<'a> T::Ref<'a>: Ord,
663{
664    fn cmp(&self, other: &Self) -> Ordering {
665        match self
666            .iter()
667            .zip(other.iter())
668            .try_fold(Ordering::Equal, |_, (a, b)| match a.cmp(&b) {
669                ord @ (Ordering::Greater | Ordering::Less) => ControlFlow::Break(ord),
670                Ordering::Equal => ControlFlow::Continue(self.len().cmp(&other.len())),
671            }) {
672            ControlFlow::Continue(ord) | ControlFlow::Break(ord) => ord,
673        }
674    }
675}
676
677impl<T> Hash for Slice<T>
678where
679    T: Soars,
680    for<'a> T::Ref<'a>: Hash,
681{
682    fn hash<H: Hasher>(&self, state: &mut H) {
683        self.len().hash(state);
684        for item in self {
685            item.hash(state);
686        }
687    }
688}
689
690impl<T> Deref for Slice<T>
691where
692    T: Soars,
693{
694    type Target = T::Deref;
695
696    fn deref(&self) -> &Self::Target {
697        <T::Deref as SoaDeref>::from_slice(self)
698    }
699}
700
701impl<T> DerefMut for Slice<T>
702where
703    T: Soars,
704{
705    fn deref_mut(&mut self) -> &mut Self::Target {
706        <T::Deref as SoaDeref>::from_slice_mut(self)
707    }
708}
709
710impl<T> AsRef<Slice<T>> for Slice<T>
711where
712    T: Soars,
713{
714    fn as_ref(&self) -> &Self {
715        self
716    }
717}
718
719impl<T> AsMut<Slice<T>> for Slice<T>
720where
721    T: Soars,
722{
723    fn as_mut(&mut self) -> &mut Self {
724        self
725    }
726}
727
728impl<T> AsSlice for Slice<T>
729where
730    T: Soars,
731{
732    type Item = T;
733
734    fn as_slice(&self) -> SliceRef<'_, Self::Item> {
735        // SAFETY: The returned lifetime is bound to self
736        unsafe { SliceRef::from_slice(self.as_sized(), self.len()) }
737    }
738}
739
740impl<T> AsMutSlice for Slice<T>
741where
742    T: Soars,
743{
744    fn as_mut_slice(&mut self) -> SliceMut<'_, Self::Item> {
745        // SAFETY: The returned lifetime is bound to self
746        unsafe { SliceMut::from_slice(self.as_sized(), self.len()) }
747    }
748}