sized_chunks/ring_buffer/
slice.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5use core::borrow::Borrow;
6use core::cmp::Ordering;
7use core::fmt::Debug;
8use core::fmt::Error;
9use core::fmt::Formatter;
10use core::hash::Hash;
11use core::hash::Hasher;
12use core::ops::IndexMut;
13use core::ops::{Bound, Index, Range, RangeBounds};
14
15use super::{Iter, IterMut, RingBuffer};
16
17use array_ops::{Array, ArrayMut, HasLength};
18
19/// An indexable representation of a subset of a `RingBuffer`.
20pub struct Slice<'a, A, const N: usize> {
21    pub(crate) buffer: &'a RingBuffer<A, N>,
22    pub(crate) range: Range<usize>,
23}
24
25impl<'a, A: 'a, const N: usize> HasLength for Slice<'a, A, N> {
26    /// Get the length of the slice.
27    #[inline]
28    #[must_use]
29    fn len(&self) -> usize {
30        self.range.end - self.range.start
31    }
32}
33
34impl<'a, A: 'a, const N: usize> Array for Slice<'a, A, N> {
35    /// Get a reference to the value at a given index.
36    #[inline]
37    #[must_use]
38    fn get(&self, index: usize) -> Option<&A> {
39        if index >= self.len() {
40            None
41        } else {
42            Some(unsafe { self.get_unchecked(index) })
43        }
44    }
45}
46
47impl<'a, A: 'a, const N: usize> Slice<'a, A, N> {
48    /// Get an unchecked reference to the value at the given index.
49    ///
50    /// # Safety
51    ///
52    /// You must ensure the index is not out of bounds.
53    #[must_use]
54    pub unsafe fn get_unchecked(&self, index: usize) -> &A {
55        self.buffer.get_unchecked(self.range.start + index)
56    }
57
58    /// Get an iterator over references to the items in the slice in order.
59    #[inline]
60    #[must_use]
61    pub fn iter(&self) -> Iter<'_, A, N> {
62        Iter {
63            buffer: self.buffer,
64            left_index: self.buffer.origin + self.range.start,
65            right_index: self.buffer.origin + self.range.start + self.len(),
66            remaining: self.len(),
67        }
68    }
69
70    /// Create a subslice of this slice.
71    ///
72    /// This consumes the slice. To create a subslice without consuming it,
73    /// clone it first: `my_slice.clone().slice(1..2)`.
74    #[must_use]
75    pub fn slice<R: RangeBounds<usize>>(self, range: R) -> Slice<'a, A, N> {
76        let new_range = Range {
77            start: match range.start_bound() {
78                Bound::Unbounded => self.range.start,
79                Bound::Included(index) => self.range.start + index,
80                Bound::Excluded(_) => unimplemented!(),
81            },
82            end: match range.end_bound() {
83                Bound::Unbounded => self.range.end,
84                Bound::Included(index) => self.range.start + index + 1,
85                Bound::Excluded(index) => self.range.start + index,
86            },
87        };
88        if new_range.start < self.range.start
89            || new_range.end > self.range.end
90            || new_range.start > new_range.end
91        {
92            panic!("Slice::slice: index out of bounds");
93        }
94        Slice {
95            buffer: self.buffer,
96            range: new_range,
97        }
98    }
99
100    /// Split the slice into two subslices at the given index.
101    #[must_use]
102    pub fn split_at(self, index: usize) -> (Slice<'a, A, N>, Slice<'a, A, N>) {
103        if index > self.len() {
104            panic!("Slice::split_at: index out of bounds");
105        }
106        let index = self.range.start + index;
107        (
108            Slice {
109                buffer: self.buffer,
110                range: Range {
111                    start: self.range.start,
112                    end: index,
113                },
114            },
115            Slice {
116                buffer: self.buffer,
117                range: Range {
118                    start: index,
119                    end: self.range.end,
120                },
121            },
122        )
123    }
124
125    /// Construct a new `RingBuffer` by copying the elements in this slice.
126    #[inline]
127    #[must_use]
128    pub fn to_owned(&self) -> RingBuffer<A, N>
129    where
130        A: Clone,
131    {
132        self.iter().cloned().collect()
133    }
134}
135
136impl<'a, A: 'a, const N: usize> From<&'a RingBuffer<A, N>> for Slice<'a, A, N> {
137    #[inline]
138    #[must_use]
139    fn from(buffer: &'a RingBuffer<A, N>) -> Self {
140        Slice {
141            range: Range {
142                start: 0,
143                end: buffer.len(),
144            },
145            buffer,
146        }
147    }
148}
149
150impl<'a, A: 'a, const N: usize> Clone for Slice<'a, A, N> {
151    #[inline]
152    #[must_use]
153    fn clone(&self) -> Self {
154        Slice {
155            buffer: self.buffer,
156            range: self.range.clone(),
157        }
158    }
159}
160
161impl<'a, A: 'a, const N: usize> Index<usize> for Slice<'a, A, N> {
162    type Output = A;
163
164    #[inline]
165    #[must_use]
166    fn index(&self, index: usize) -> &Self::Output {
167        self.buffer.index(self.range.start + index)
168    }
169}
170
171impl<'a, A: PartialEq + 'a, const N: usize> PartialEq for Slice<'a, A, N> {
172    #[inline]
173    #[must_use]
174    fn eq(&self, other: &Self) -> bool {
175        self.len() == other.len() && self.iter().eq(other.iter())
176    }
177}
178
179impl<'a, A: PartialEq + 'a, const N: usize> PartialEq<SliceMut<'a, A, N>> for Slice<'a, A, N> {
180    #[inline]
181    #[must_use]
182    fn eq(&self, other: &SliceMut<'a, A, N>) -> bool {
183        self.len() == other.len() && self.iter().eq(other.iter())
184    }
185}
186
187impl<'a, A: PartialEq + 'a, const N: usize> PartialEq<RingBuffer<A, N>> for Slice<'a, A, N> {
188    #[inline]
189    #[must_use]
190    fn eq(&self, other: &RingBuffer<A, N>) -> bool {
191        self.len() == other.len() && self.iter().eq(other.iter())
192    }
193}
194
195impl<'a, A: PartialEq + 'a, S, const N: usize> PartialEq<S> for Slice<'a, A, N>
196where
197    S: Borrow<[A]>,
198{
199    #[inline]
200    #[must_use]
201    fn eq(&self, other: &S) -> bool {
202        let other = other.borrow();
203        self.len() == other.len() && self.iter().eq(other.iter())
204    }
205}
206
207impl<'a, A: Eq + 'a, const N: usize> Eq for Slice<'a, A, N> {}
208
209impl<'a, A: PartialOrd + 'a, const N: usize> PartialOrd for Slice<'a, A, N> {
210    #[inline]
211    #[must_use]
212    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
213        self.iter().partial_cmp(other.iter())
214    }
215}
216
217impl<'a, A: Ord + 'a, const N: usize> Ord for Slice<'a, A, N> {
218    #[inline]
219    #[must_use]
220    fn cmp(&self, other: &Self) -> Ordering {
221        self.iter().cmp(other.iter())
222    }
223}
224
225impl<'a, A: Debug + 'a, const N: usize> Debug for Slice<'a, A, N> {
226    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
227        f.write_str("RingBuffer")?;
228        f.debug_list().entries(self.iter()).finish()
229    }
230}
231
232impl<'a, A: Hash + 'a, const N: usize> Hash for Slice<'a, A, N> {
233    #[inline]
234    fn hash<H: Hasher>(&self, hasher: &mut H) {
235        for item in self {
236            item.hash(hasher)
237        }
238    }
239}
240
241impl<'a, A: 'a, const N: usize> IntoIterator for &'a Slice<'a, A, N> {
242    type Item = &'a A;
243    type IntoIter = Iter<'a, A, N>;
244
245    #[inline]
246    #[must_use]
247    fn into_iter(self) -> Self::IntoIter {
248        self.iter()
249    }
250}
251
252// Mutable slice
253
254/// An indexable representation of a mutable subset of a `RingBuffer`.
255pub struct SliceMut<'a, A, const N: usize> {
256    pub(crate) buffer: &'a mut RingBuffer<A, N>,
257    pub(crate) range: Range<usize>,
258}
259
260impl<'a, A: 'a, const N: usize> HasLength for SliceMut<'a, A, N> {
261    /// Get the length of the slice.
262    #[inline]
263    #[must_use]
264    fn len(&self) -> usize {
265        self.range.end - self.range.start
266    }
267}
268
269impl<'a, A: 'a, const N: usize> Array for SliceMut<'a, A, N> {
270    /// Get a reference to the value at a given index.
271    #[inline]
272    #[must_use]
273    fn get(&self, index: usize) -> Option<&A> {
274        if index >= self.len() {
275            None
276        } else {
277            Some(unsafe { self.get_unchecked(index) })
278        }
279    }
280}
281
282impl<'a, A: 'a, const N: usize> ArrayMut for SliceMut<'a, A, N> {
283    /// Get a mutable reference to the value at a given index.
284    #[inline]
285    #[must_use]
286    fn get_mut(&mut self, index: usize) -> Option<&mut A> {
287        if index >= self.len() {
288            None
289        } else {
290            Some(unsafe { self.get_unchecked_mut(index) })
291        }
292    }
293}
294
295impl<'a, A: 'a, const N: usize> SliceMut<'a, A, N> {
296    /// Downgrade this slice into a non-mutable slice.
297    #[inline]
298    #[must_use]
299    pub fn unmut(self) -> Slice<'a, A, N> {
300        Slice {
301            buffer: self.buffer,
302            range: self.range,
303        }
304    }
305
306    /// Get an unchecked reference to the value at the given index.
307    ///
308    /// # Safety
309    ///
310    /// You must ensure the index is not out of bounds.
311    #[must_use]
312    pub unsafe fn get_unchecked(&self, index: usize) -> &A {
313        self.buffer.get_unchecked(self.range.start + index)
314    }
315
316    /// Get an unchecked mutable reference to the value at the given index.
317    ///
318    /// # Safety
319    ///
320    /// You must ensure the index is not out of bounds.
321    #[must_use]
322    pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut A {
323        self.buffer.get_unchecked_mut(self.range.start + index)
324    }
325
326    /// Get an iterator over references to the items in the slice in order.
327    #[inline]
328    #[must_use]
329    pub fn iter(&self) -> Iter<'_, A, N> {
330        Iter {
331            buffer: self.buffer,
332            left_index: self.buffer.origin + self.range.start,
333            right_index: self.buffer.origin + self.range.start + self.len(),
334            remaining: self.len(),
335        }
336    }
337
338    /// Get an iterator over mutable references to the items in the slice in
339    /// order.
340    #[inline]
341    #[must_use]
342    pub fn iter_mut(&mut self) -> IterMut<'_, A, N> {
343        IterMut::new_slice(
344            self.buffer,
345            self.buffer.origin + self.range.start,
346            self.len(),
347        )
348    }
349
350    /// Create a subslice of this slice.
351    ///
352    /// This consumes the slice. Because the slice works like a mutable
353    /// reference, you can only have one slice over a given subset of a
354    /// `RingBuffer` at any one time, so that's just how it's got to be.
355    #[must_use]
356    pub fn slice<R: RangeBounds<usize>>(self, range: R) -> SliceMut<'a, A, N> {
357        let new_range = Range {
358            start: match range.start_bound() {
359                Bound::Unbounded => self.range.start,
360                Bound::Included(index) => self.range.start + index,
361                Bound::Excluded(_) => unimplemented!(),
362            },
363            end: match range.end_bound() {
364                Bound::Unbounded => self.range.end,
365                Bound::Included(index) => self.range.start + index + 1,
366                Bound::Excluded(index) => self.range.start + index,
367            },
368        };
369        if new_range.start < self.range.start
370            || new_range.end > self.range.end
371            || new_range.start > new_range.end
372        {
373            panic!("Slice::slice: index out of bounds");
374        }
375        SliceMut {
376            buffer: self.buffer,
377            range: new_range,
378        }
379    }
380
381    /// Split the slice into two subslices at the given index.
382    #[must_use]
383    pub fn split_at(self, index: usize) -> (SliceMut<'a, A, N>, SliceMut<'a, A, N>) {
384        if index > self.len() {
385            panic!("SliceMut::split_at: index out of bounds");
386        }
387        let index = self.range.start + index;
388        let ptr: *mut RingBuffer<A, N> = self.buffer;
389        (
390            SliceMut {
391                buffer: unsafe { &mut *ptr },
392                range: Range {
393                    start: self.range.start,
394                    end: index,
395                },
396            },
397            SliceMut {
398                buffer: unsafe { &mut *ptr },
399                range: Range {
400                    start: index,
401                    end: self.range.end,
402                },
403            },
404        )
405    }
406
407    /// Construct a new `RingBuffer` by copying the elements in this slice.
408    #[inline]
409    #[must_use]
410    pub fn to_owned(&self) -> RingBuffer<A, N>
411    where
412        A: Clone,
413    {
414        self.iter().cloned().collect()
415    }
416}
417
418impl<'a, A: 'a, const N: usize> From<&'a mut RingBuffer<A, N>> for SliceMut<'a, A, N> {
419    #[must_use]
420    fn from(buffer: &'a mut RingBuffer<A, N>) -> Self {
421        SliceMut {
422            range: Range {
423                start: 0,
424                end: buffer.len(),
425            },
426            buffer,
427        }
428    }
429}
430
431impl<'a, A: 'a, const N: usize> Into<Slice<'a, A, N>> for SliceMut<'a, A, N> {
432    #[inline]
433    #[must_use]
434    fn into(self) -> Slice<'a, A, N> {
435        self.unmut()
436    }
437}
438
439impl<'a, A: 'a, const N: usize> Index<usize> for SliceMut<'a, A, N> {
440    type Output = A;
441
442    #[inline]
443    #[must_use]
444    fn index(&self, index: usize) -> &Self::Output {
445        self.buffer.index(self.range.start + index)
446    }
447}
448
449impl<'a, A: 'a, const N: usize> IndexMut<usize> for SliceMut<'a, A, N> {
450    #[inline]
451    #[must_use]
452    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
453        self.buffer.index_mut(self.range.start + index)
454    }
455}
456
457impl<'a, A: PartialEq + 'a, const N: usize> PartialEq for SliceMut<'a, A, N> {
458    #[inline]
459    #[must_use]
460    fn eq(&self, other: &Self) -> bool {
461        self.len() == other.len() && self.iter().eq(other.iter())
462    }
463}
464
465impl<'a, A: PartialEq + 'a, const N: usize> PartialEq<Slice<'a, A, N>> for SliceMut<'a, A, N> {
466    #[inline]
467    #[must_use]
468    fn eq(&self, other: &Slice<'a, A, N>) -> bool {
469        self.len() == other.len() && self.iter().eq(other.iter())
470    }
471}
472
473impl<'a, A: PartialEq + 'a, const N: usize> PartialEq<RingBuffer<A, N>> for SliceMut<'a, A, N> {
474    #[inline]
475    #[must_use]
476    fn eq(&self, other: &RingBuffer<A, N>) -> bool {
477        self.len() == other.len() && self.iter().eq(other.iter())
478    }
479}
480
481impl<'a, A: PartialEq + 'a, S, const N: usize> PartialEq<S> for SliceMut<'a, A, N>
482where
483    S: Borrow<[A]>,
484{
485    #[inline]
486    #[must_use]
487    fn eq(&self, other: &S) -> bool {
488        let other = other.borrow();
489        self.len() == other.len() && self.iter().eq(other.iter())
490    }
491}
492
493impl<'a, A: Eq + 'a, const N: usize> Eq for SliceMut<'a, A, N> {}
494
495impl<'a, A: PartialOrd + 'a, const N: usize> PartialOrd for SliceMut<'a, A, N> {
496    #[inline]
497    #[must_use]
498    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
499        self.iter().partial_cmp(other.iter())
500    }
501}
502
503impl<'a, A: Ord + 'a, const N: usize> Ord for SliceMut<'a, A, N> {
504    #[inline]
505    #[must_use]
506    fn cmp(&self, other: &Self) -> Ordering {
507        self.iter().cmp(other.iter())
508    }
509}
510
511impl<'a, A: Debug + 'a, const N: usize> Debug for SliceMut<'a, A, N> {
512    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
513        f.write_str("RingBuffer")?;
514        f.debug_list().entries(self.iter()).finish()
515    }
516}
517
518impl<'a, A: Hash + 'a, const N: usize> Hash for SliceMut<'a, A, N> {
519    #[inline]
520    fn hash<H: Hasher>(&self, hasher: &mut H) {
521        for item in self {
522            item.hash(hasher)
523        }
524    }
525}
526
527impl<'a, 'b, A: 'a, const N: usize> IntoIterator for &'a SliceMut<'a, A, N> {
528    type Item = &'a A;
529    type IntoIter = Iter<'a, A, N>;
530
531    #[inline]
532    #[must_use]
533    fn into_iter(self) -> Self::IntoIter {
534        self.iter()
535    }
536}
537
538impl<'a, 'b, A: 'a, const N: usize> IntoIterator for &'a mut SliceMut<'a, A, N> {
539    type Item = &'a mut A;
540    type IntoIter = IterMut<'a, A, N>;
541
542    #[inline]
543    #[must_use]
544    fn into_iter(self) -> Self::IntoIter {
545        self.iter_mut()
546    }
547}