soapy/
slice_mut.rs

1use crate::{eq_impl, iter_raw::IterRaw, IterMut, Slice, SliceRef, Soa, Soapy};
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 + Soapy,
18{
19    pub(crate) slice: Slice<T, ()>,
20    pub(crate) len: usize,
21    pub(crate) marker: PhantomData<&'a mut T>,
22}
23
24impl<'a, T> SliceMut<'a, T>
25where
26    T: Soapy,
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<'a, T> AsRef<Slice<T>> for SliceMut<'a, T>
47where
48    T: Soapy,
49{
50    fn as_ref(&self) -> &Slice<T> {
51        self.deref()
52    }
53}
54
55impl<'a, T> AsMut<Slice<T>> for SliceMut<'a, T>
56where
57    T: Soapy,
58{
59    fn as_mut(&mut self) -> &mut Slice<T> {
60        self.deref_mut()
61    }
62}
63
64impl<'a, T> Deref for SliceMut<'a, T>
65where
66    T: Soapy,
67{
68    type Target = Slice<T>;
69
70    fn deref(&self) -> &Self::Target {
71        unsafe { self.slice.as_unsized(self.len) }
72    }
73}
74
75impl<'a, T> DerefMut for SliceMut<'a, T>
76where
77    T: Soapy,
78{
79    fn deref_mut(&mut self) -> &mut Self::Target {
80        unsafe { self.slice.as_unsized_mut(self.len) }
81    }
82}
83
84impl<'a, T> IntoIterator for SliceMut<'a, T>
85where
86    T: Soapy,
87{
88    type Item = T::RefMut<'a>;
89    type IntoIter = IterMut<'a, T>;
90
91    fn into_iter(self) -> Self::IntoIter {
92        IterMut {
93            iter_raw: IterRaw {
94                slice: Slice::with_raw(self.raw()),
95                len: self.len(),
96                adapter: PhantomData,
97            },
98            _marker: PhantomData,
99        }
100    }
101}
102
103eq_impl::impl_for!(SliceMut<'_, T>);
104
105impl<'a, T> Debug for SliceMut<'a, T>
106where
107    T: Soapy,
108    for<'b> T::Ref<'b>: Debug,
109{
110    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
111        self.as_ref().fmt(f)
112    }
113}
114
115impl<'a, T> PartialOrd for SliceMut<'a, T>
116where
117    T: Soapy,
118    for<'b> T::Ref<'b>: PartialOrd,
119{
120    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
121        self.as_ref().partial_cmp(other.as_ref())
122    }
123}
124
125impl<'a, T> Ord for SliceMut<'a, T>
126where
127    T: Soapy,
128    for<'b> T::Ref<'b>: Ord,
129{
130    fn cmp(&self, other: &Self) -> Ordering {
131        self.as_ref().cmp(other.as_ref())
132    }
133}
134
135impl<'a, T> Hash for SliceMut<'a, T>
136where
137    T: Soapy,
138    for<'b> T::Ref<'b>: Hash,
139{
140    fn hash<H: Hasher>(&self, state: &mut H) {
141        self.as_ref().hash(state)
142    }
143}