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}