soa_rs/
slice_mut.rs

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