audio/
slice.rs

1//! Traits used to generically describe and operate over slice-like types.
2//!
3//! This is used in for example [LinearChannel][crate::channel::LinearChannel] to allow
4//! it to abstract over its content.
5
6#![allow(clippy::len_without_is_empty)]
7
8use core::ptr;
9
10/// Describes how a buffer can be indexed.
11pub trait SliceIndex: Slice
12where
13    Self: Sized,
14{
15    /// Get a range out of the given slice.
16    #[doc(hidden)]
17    fn index_from(self, index: usize) -> Self;
18
19    /// Index to the given index.
20    #[doc(hidden)]
21    fn index_to(self, index: usize) -> Self;
22
23    /// Index to the given index.
24    #[doc(hidden)]
25    fn index_full(self, from: usize, to: usize) -> Self;
26}
27
28/// Trait used to operate over a slice.
29pub trait Slice
30where
31    Self: Sized,
32{
33    /// A single item in the slice.
34    type Item: Copy;
35
36    /// Get the length of the slice.
37    #[doc(hidden)]
38    fn len(&self) -> usize;
39
40    /// Helper to reborrow the items of self.
41    #[doc(hidden)]
42    fn as_ref(&self) -> &[Self::Item];
43
44    /// Get the pointer to the first element.
45    #[doc(hidden)]
46    fn as_ptr(&self) -> ptr::NonNull<Self::Item>;
47}
48
49/// Trait used to operate generically over a mutable slice.
50pub trait SliceMut: Slice
51where
52    Self: Sized,
53{
54    /// Construct a mutable slice.
55    fn as_mut(&mut self) -> &mut [Self::Item];
56
57    /// Get the base mutable pointer.
58    fn as_mut_ptr(&mut self) -> ptr::NonNull<Self::Item>;
59}
60
61impl<T> SliceIndex for &[T]
62where
63    T: Copy,
64{
65    #[inline]
66    fn index_from(self, index: usize) -> Self {
67        self.get(index..).unwrap_or_default()
68    }
69
70    #[inline]
71    fn index_to(self, index: usize) -> Self {
72        self.get(..index).unwrap_or_default()
73    }
74
75    #[inline]
76    fn index_full(self, from: usize, to: usize) -> Self {
77        self.get(from..to).unwrap_or_default()
78    }
79}
80
81impl<T> Slice for &[T]
82where
83    T: Copy,
84{
85    type Item = T;
86
87    #[inline]
88    fn len(&self) -> usize {
89        <[T]>::len(self)
90    }
91
92    #[inline]
93    fn as_ref(&self) -> &[Self::Item] {
94        self
95    }
96
97    #[inline]
98    fn as_ptr(&self) -> ptr::NonNull<Self::Item> {
99        unsafe { ptr::NonNull::new_unchecked(<[T]>::as_ptr(&self[..]) as *mut _) }
100    }
101}
102
103impl<T, const N: usize> Slice for [T; N]
104where
105    T: Copy,
106{
107    type Item = T;
108
109    #[inline]
110    fn len(&self) -> usize {
111        N
112    }
113
114    #[inline]
115    fn as_ref(&self) -> &[Self::Item] {
116        &self[..]
117    }
118
119    #[inline]
120    fn as_ptr(&self) -> ptr::NonNull<Self::Item> {
121        unsafe { ptr::NonNull::new_unchecked(<[T]>::as_ptr(self) as *mut _) }
122    }
123}
124
125impl<T, const N: usize> Slice for &[T; N]
126where
127    T: Copy,
128{
129    type Item = T;
130
131    #[inline]
132    fn len(&self) -> usize {
133        N
134    }
135
136    #[inline]
137    fn as_ref(&self) -> &[Self::Item] {
138        &self[..]
139    }
140
141    #[inline]
142    fn as_ptr(&self) -> ptr::NonNull<Self::Item> {
143        unsafe { ptr::NonNull::new_unchecked(<[T]>::as_ptr(&self[..]) as *mut _) }
144    }
145}
146
147impl<T> SliceIndex for &mut [T]
148where
149    T: Copy,
150{
151    #[inline]
152    fn index_from(self, index: usize) -> Self {
153        self.get_mut(index..).unwrap_or_default()
154    }
155
156    #[inline]
157    fn index_to(self, index: usize) -> Self {
158        self.get_mut(..index).unwrap_or_default()
159    }
160
161    #[inline]
162    fn index_full(self, from: usize, to: usize) -> Self {
163        self.get_mut(from..to).unwrap_or_default()
164    }
165}
166
167impl<T> Slice for &mut [T]
168where
169    T: Copy,
170{
171    type Item = T;
172
173    #[inline]
174    fn len(&self) -> usize {
175        <[T]>::len(self)
176    }
177
178    #[inline]
179    fn as_ref(&self) -> &[Self::Item] {
180        &self[..]
181    }
182
183    #[inline]
184    fn as_ptr(&self) -> ptr::NonNull<Self::Item> {
185        unsafe { ptr::NonNull::new_unchecked(<[T]>::as_ptr(&self[..]) as *mut _) }
186    }
187}
188
189impl<T, const N: usize> Slice for &mut [T; N]
190where
191    T: Copy,
192{
193    type Item = T;
194
195    #[inline]
196    fn len(&self) -> usize {
197        N
198    }
199
200    #[inline]
201    fn as_ref(&self) -> &[Self::Item] {
202        &self[..]
203    }
204
205    #[inline]
206    fn as_ptr(&self) -> ptr::NonNull<Self::Item> {
207        unsafe { ptr::NonNull::new_unchecked(<[T]>::as_ptr(&self[..]) as *mut _) }
208    }
209}
210
211impl<T> SliceMut for &mut [T]
212where
213    T: Copy,
214{
215    #[inline]
216    fn as_mut(&mut self) -> &mut [Self::Item] {
217        self
218    }
219
220    #[inline]
221    fn as_mut_ptr(&mut self) -> ptr::NonNull<Self::Item> {
222        unsafe { ptr::NonNull::new_unchecked(<[T]>::as_mut_ptr(self)) }
223    }
224}
225
226impl<T, const N: usize> SliceMut for [T; N]
227where
228    T: Copy,
229{
230    #[inline]
231    fn as_mut(&mut self) -> &mut [Self::Item] {
232        self
233    }
234
235    #[inline]
236    fn as_mut_ptr(&mut self) -> ptr::NonNull<Self::Item> {
237        unsafe { ptr::NonNull::new_unchecked(<[T]>::as_mut_ptr(&mut self[..])) }
238    }
239}
240
241impl<T, const N: usize> SliceMut for &mut [T; N]
242where
243    T: Copy,
244{
245    #[inline]
246    fn as_mut(&mut self) -> &mut [Self::Item] {
247        &mut self[..]
248    }
249
250    #[inline]
251    fn as_mut_ptr(&mut self) -> ptr::NonNull<Self::Item> {
252        unsafe { ptr::NonNull::new_unchecked(<[T]>::as_mut_ptr(&mut self[..])) }
253    }
254}