Skip to main content

soa_rs/
slice_mut.rs

1use crate::{
2    AsMutSlice, AsSlice, IterMut, Slice, SliceRef, SoaClone, Soars, Vec, iter_raw::IterRaw,
3};
4use core::{
5    borrow::{Borrow, BorrowMut},
6    cmp::Ordering,
7    fmt::{self, Debug, Formatter},
8    hash::{Hash, Hasher},
9    marker::PhantomData,
10    ops::{Deref, DerefMut},
11};
12
13/// An mutably borrowed [`Slice`].
14///
15/// A `SliceMut` is a thin wrapper over a [`Slice`] that applies the same
16/// borrowing rules as a mutable reference. It is semantically equivalent to
17/// `&mut Slice`.
18pub struct SliceMut<'a, T>
19where
20    T: 'a + Soars,
21{
22    pub(crate) slice: Slice<T, ()>,
23    pub(crate) len: usize,
24    pub(crate) marker: PhantomData<&'a mut T>,
25}
26
27impl<T> SliceMut<'_, T>
28where
29    T: Soars,
30{
31    /// Creates a new [`SliceMut`] from the given slice and length. Intended for
32    /// use in proc macro code, not user code.
33    ///
34    /// # Safety
35    ///
36    /// The provided slice and its length must be compatible. Since the slice
37    /// passed in has no intrinsic lifetime, care must be taken to ensure that
38    /// the lifetime of [`SliceMut`] is valid.
39    #[doc(hidden)]
40    pub unsafe fn from_slice(slice: Slice<T, ()>, len: usize) -> Self {
41        Self {
42            slice,
43            len,
44            marker: PhantomData,
45        }
46    }
47}
48
49impl<T> AsRef<Slice<T>> for SliceMut<'_, T>
50where
51    T: Soars,
52{
53    fn as_ref(&self) -> &Slice<T> {
54        self.deref()
55    }
56}
57
58impl<T> AsMut<Slice<T>> for SliceMut<'_, T>
59where
60    T: Soars,
61{
62    fn as_mut(&mut self) -> &mut Slice<T> {
63        self.deref_mut()
64    }
65}
66
67impl<T> Borrow<Slice<T>> for SliceMut<'_, T>
68where
69    T: Soars,
70{
71    fn borrow(&self) -> &Slice<T> {
72        self.as_ref()
73    }
74}
75
76impl<T> BorrowMut<Slice<T>> for SliceMut<'_, T>
77where
78    T: Soars,
79{
80    fn borrow_mut(&mut self) -> &mut Slice<T> {
81        self.as_mut()
82    }
83}
84
85impl<T> Deref for SliceMut<'_, T>
86where
87    T: Soars,
88{
89    type Target = Slice<T>;
90
91    fn deref(&self) -> &Self::Target {
92        // SAFETY:
93        // - len is valid
94        // - The lifetime is bound to self
95        unsafe { self.slice.as_unsized(self.len) }
96    }
97}
98
99impl<T> DerefMut for SliceMut<'_, T>
100where
101    T: Soars,
102{
103    fn deref_mut(&mut self) -> &mut Self::Target {
104        // SAFETY:
105        // - len is valid
106        // - The lifetime is bound to self
107        unsafe { self.slice.as_unsized_mut(self.len) }
108    }
109}
110
111impl<'a, T> IntoIterator for SliceMut<'a, T>
112where
113    T: Soars,
114{
115    type Item = T::RefMut<'a>;
116    type IntoIter = IterMut<'a, T>;
117
118    fn into_iter(self) -> Self::IntoIter {
119        IterMut {
120            iter_raw: IterRaw {
121                slice: Slice::with_raw(self.raw()),
122                len: self.len(),
123                adapter: PhantomData,
124            },
125            _marker: PhantomData,
126        }
127    }
128}
129
130impl<T> Debug for SliceMut<'_, T>
131where
132    T: Soars,
133    for<'b> T::Ref<'b>: Debug,
134{
135    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
136        self.as_ref().fmt(f)
137    }
138}
139
140impl<T> PartialOrd for SliceMut<'_, T>
141where
142    T: Soars,
143    for<'b> T::Ref<'b>: PartialOrd,
144{
145    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
146        self.as_ref().partial_cmp(other.as_ref())
147    }
148}
149
150impl<T> Ord for SliceMut<'_, T>
151where
152    T: Soars,
153    for<'b> T::Ref<'b>: Ord,
154{
155    fn cmp(&self, other: &Self) -> Ordering {
156        self.as_ref().cmp(other.as_ref())
157    }
158}
159
160impl<T> Hash for SliceMut<'_, T>
161where
162    T: Soars,
163    for<'b> T::Ref<'b>: Hash,
164{
165    fn hash<H: Hasher>(&self, state: &mut H) {
166        self.as_ref().hash(state)
167    }
168}
169
170impl<T, R> PartialEq<R> for SliceMut<'_, T>
171where
172    T: Soars,
173    R: AsSlice<Item = T> + ?Sized,
174    for<'a> T::Ref<'a>: PartialEq,
175{
176    fn eq(&self, other: &R) -> bool {
177        self.as_ref() == other.as_slice().as_ref()
178    }
179}
180
181impl<T> Eq for SliceMut<'_, T>
182where
183    T: Soars,
184    for<'a> T::Ref<'a>: Eq,
185{
186}
187
188impl<T> From<SliceMut<'_, T>> for Vec<T>
189where
190    T: SoaClone,
191{
192    /// Allocate a `Vec<T>` and fill it by cloning `value`'s items.
193    fn from(value: SliceMut<T>) -> Self {
194        value.as_ref().into()
195    }
196}
197
198impl<T> AsSlice for SliceMut<'_, T>
199where
200    T: Soars,
201{
202    type Item = T;
203
204    fn as_slice(&self) -> SliceRef<'_, Self::Item> {
205        // SAFETY:
206        // - len is valid
207        // - The lifetime is bound to self
208        unsafe { SliceRef::from_slice(self.slice, self.len) }
209    }
210}
211
212impl<T> AsMutSlice for SliceMut<'_, T>
213where
214    T: Soars,
215{
216    fn as_mut_slice(&mut self) -> SliceMut<'_, Self::Item> {
217        // SAFETY:
218        // - len is valid
219        // - The lifetime is bound to self
220        unsafe { Self::from_slice(self.slice, self.len) }
221    }
222}