soa_rs/
slice_mut.rs

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