soa_rs/
slice_ref.rs

1use crate::{AsSlice, Iter, Slice, Soars, iter_raw::IterRaw};
2use core::{
3    borrow::Borrow,
4    cmp::Ordering,
5    fmt::{self, Debug, Formatter},
6    hash::{Hash, Hasher},
7    marker::PhantomData,
8    ops::Deref,
9};
10
11/// An immutably borrowed [`Slice`].
12///
13/// A `SliceRef` is a thin wrapper over a [`Slice`] that applies the same
14/// borrowing rules as an immutable reference. It is semantically equivalent to
15/// `&Slice`.
16pub struct SliceRef<'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 T>,
23}
24
25impl<T> SliceRef<'_, T>
26where
27    T: Soars,
28{
29    /// Creates a new [`SliceRef`] 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 [`SliceRef`] 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> Clone for SliceRef<'_, T>
48where
49    T: Soars,
50{
51    fn clone(&self) -> Self {
52        *self
53    }
54}
55
56impl<'a, T> Copy for SliceRef<'a, T> where T: 'a + Soars {}
57
58impl<T> AsRef<Slice<T>> for SliceRef<'_, T>
59where
60    T: Soars,
61{
62    fn as_ref(&self) -> &Slice<T> {
63        // SAFETY:
64        // - len is valid
65        // - The returned lifetime is bound to self
66        unsafe { self.slice.as_unsized(self.len) }
67    }
68}
69
70impl<T> Borrow<Slice<T>> for SliceRef<'_, T>
71where
72    T: Soars,
73{
74    fn borrow(&self) -> &Slice<T> {
75        self.as_ref()
76    }
77}
78
79impl<T> Deref for SliceRef<'_, T>
80where
81    T: Soars,
82{
83    type Target = Slice<T>;
84
85    fn deref(&self) -> &Self::Target {
86        self.as_ref()
87    }
88}
89
90impl<'a, T> IntoIterator for SliceRef<'a, T>
91where
92    T: Soars,
93{
94    type Item = T::Ref<'a>;
95    type IntoIter = Iter<'a, T>;
96
97    fn into_iter(self) -> Self::IntoIter {
98        Iter {
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 SliceRef<'_, 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 SliceRef<'_, 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 SliceRef<'_, T>
130where
131    T: Soars + Ord,
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 SliceRef<'_, 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 SliceRef<'_, 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 SliceRef<'_, T>
161where
162    T: Soars,
163    for<'a> T::Ref<'a>: Eq,
164{
165}
166
167impl<T> AsSlice for SliceRef<'_, T>
168where
169    T: Soars,
170{
171    type Item = T;
172
173    fn as_slice(&self) -> SliceRef<'_, Self::Item> {
174        *self
175    }
176}