soa_rs/
slice_ref.rs

1use crate::{iter_raw::IterRaw, AsSlice, Iter, Slice, Soars};
2use std::{
3    cmp::Ordering,
4    fmt::{self, Debug, Formatter},
5    hash::{Hash, Hasher},
6    marker::PhantomData,
7    ops::Deref,
8};
9
10/// An immutably borrowed [`Slice`].
11///
12/// A `SliceRef` is a thin wrapper over a [`Slice`] that applies the same
13/// borrowing rules as an immutable reference. It is semantically equivalent to
14/// `&Slice`.
15pub struct SliceRef<'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 T>,
22}
23
24impl<T> SliceRef<'_, T>
25where
26    T: Soars,
27{
28    /// Creates a new [`SliceRef`] 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 [`SliceRef`] 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> Clone for SliceRef<'_, T>
47where
48    T: Soars,
49{
50    fn clone(&self) -> Self {
51        *self
52    }
53}
54
55impl<'a, T> Copy for SliceRef<'a, T> where T: 'a + Soars {}
56
57impl<T> AsRef<Slice<T>> for SliceRef<'_, T>
58where
59    T: Soars,
60{
61    fn as_ref(&self) -> &Slice<T> {
62        // SAFETY:
63        // - len is valid
64        // - The returned lifetime is bound to self
65        unsafe { self.slice.as_unsized(self.len) }
66    }
67}
68
69impl<T> Deref for SliceRef<'_, T>
70where
71    T: Soars,
72{
73    type Target = Slice<T>;
74
75    fn deref(&self) -> &Self::Target {
76        self.as_ref()
77    }
78}
79
80impl<'a, T> IntoIterator for SliceRef<'a, T>
81where
82    T: Soars,
83{
84    type Item = T::Ref<'a>;
85    type IntoIter = Iter<'a, T>;
86
87    fn into_iter(self) -> Self::IntoIter {
88        Iter {
89            iter_raw: IterRaw {
90                slice: Slice::with_raw(self.raw()),
91                len: self.len(),
92                adapter: PhantomData,
93            },
94            _marker: PhantomData,
95        }
96    }
97}
98
99impl<T> Debug for SliceRef<'_, T>
100where
101    T: Soars,
102    for<'b> T::Ref<'b>: Debug,
103{
104    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
105        self.as_ref().fmt(f)
106    }
107}
108
109impl<T> PartialOrd for SliceRef<'_, T>
110where
111    T: Soars,
112    for<'b> T::Ref<'b>: PartialOrd,
113{
114    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
115        self.as_ref().partial_cmp(other.as_ref())
116    }
117}
118
119impl<T> Ord for SliceRef<'_, T>
120where
121    T: Soars + Ord,
122    for<'b> T::Ref<'b>: Ord,
123{
124    fn cmp(&self, other: &Self) -> Ordering {
125        self.as_ref().cmp(other.as_ref())
126    }
127}
128
129impl<T> Hash for SliceRef<'_, T>
130where
131    T: Soars,
132    for<'b> T::Ref<'b>: Hash,
133{
134    fn hash<H: Hasher>(&self, state: &mut H) {
135        self.as_ref().hash(state)
136    }
137}
138
139impl<T, R> PartialEq<R> for SliceRef<'_, T>
140where
141    T: Soars,
142    R: AsSlice<Item = T> + ?Sized,
143    for<'a> T::Ref<'a>: PartialEq,
144{
145    fn eq(&self, other: &R) -> bool {
146        self.as_ref() == other.as_slice().as_ref()
147    }
148}
149
150impl<T> Eq for SliceRef<'_, T>
151where
152    T: Soars,
153    for<'a> T::Ref<'a>: Eq,
154{
155}
156
157impl<T> AsSlice for SliceRef<'_, T>
158where
159    T: Soars,
160{
161    type Item = T;
162
163    fn as_slice(&self) -> SliceRef<'_, Self::Item> {
164        *self
165    }
166}