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}