nostd_bv/traits/
bit_sliceable.rs

1use crate::range_compat::*;
2use crate::{Bits, BitsMut};
3
4/// Types that support slicing by ranges.
5///
6/// Note that the [`bit_slice`] method takes `self` by value, which allows
7/// the `Slice` associated type to refer to the lifetime of `Self` in impls
8/// for borrowed types. For example, the impl for `&'a BitVec<u32>` has a
9/// `Slice` type of `BitSlice<'a, u32>`.
10///
11/// [`bit_slice`]: #tymethod.bit_slice
12pub trait BitSliceable<Range>: Bits {
13    /// The type of the slice produced.
14    type Slice: Bits<Block = Self::Block>;
15
16    /// Slices or re-slices the given object.
17    ///
18    /// # Examples
19    ///
20    /// ```
21    /// use nostd_bv::{BitSlice, BitSliceable};
22    ///
23    /// let array = [0b01010011u16];
24    /// let slice = BitSlice::from_slice(&array);
25    ///
26    /// assert_eq!( slice.bit_slice(1..3), slice.bit_slice(4..6) );
27    /// assert_eq!( slice.bit_slice(1..3), slice.bit_slice(6..8) );
28    ///
29    /// assert_ne!( slice.bit_slice(2..4), slice.bit_slice(6..8) );
30    /// assert_eq!( slice.bit_slice(2..4), slice.bit_slice(7..9) );
31    /// ```
32    fn bit_slice(self, range: Range) -> Self::Slice;
33}
34
35/// Types that produce mutable slices.
36///
37/// Do not implement this trait; there is a blanket impl for all
38/// [`BitSliceable`] types whose associated `Slice` types implement `BitsMut`.
39///
40/// [`BitSliceable`]: trait.BitSliceable.html
41pub trait BitSliceableMut<Range>: BitSliceable<Range> {
42    /// An alias for
43    /// [`BitSliceable::bit_slice`](trait.BitSliceable.html#tymethod.bit_slice).
44    ///
45    /// This method provides no additional functionality over `bit_slice`.
46    /// However, it can be used to force auto-ref to choose a `Self` type
47    /// that implements `BitSliceableMut`.
48    fn bit_slice_mut(self, range: Range) -> Self::Slice
49    where
50        Self: Sized,
51    {
52        self.bit_slice(range)
53    }
54}
55
56impl<Range, T> BitSliceableMut<Range> for T
57where
58    T: BitSliceable<Range>,
59    T::Slice: BitsMut,
60{
61}
62
63impl<'a> BitSliceable<RangeFull> for &'a [bool] {
64    type Slice = &'a [bool];
65
66    fn bit_slice(self, _: RangeFull) -> &'a [bool] {
67        self
68    }
69}
70
71impl<'a> BitSliceable<RangeFull> for &'a mut [bool] {
72    type Slice = &'a mut [bool];
73
74    fn bit_slice(self, _: RangeFull) -> &'a mut [bool] {
75        self
76    }
77}
78
79impl<'a> BitSliceable<Range<u64>> for &'a [bool] {
80    type Slice = &'a [bool];
81
82    fn bit_slice(self, range: Range<u64>) -> &'a [bool] {
83        &self[range.start as usize..range.end as usize]
84    }
85}
86
87impl<'a> BitSliceable<Range<u64>> for &'a mut [bool] {
88    type Slice = &'a mut [bool];
89
90    fn bit_slice(self, range: Range<u64>) -> &'a mut [bool] {
91        &mut self[range.start as usize..range.end as usize]
92    }
93}
94
95impl<'a> BitSliceable<RangeInclusive<u64>> for &'a [bool] {
96    type Slice = &'a [bool];
97
98    fn bit_slice(self, range: RangeInclusive<u64>) -> &'a [bool] {
99        let (start, end) =
100            get_inclusive_bounds(range).expect("<&[bool]>::bit_slice: bad inclusive range");
101        // Adding 1 means we could overflow a 32-bit `usize` here, but
102        // we can't construct a RangeInclusive on stable without using
103        // the `..=` token, which breaks older rustcs.
104        &self[start as usize..end as usize + 1]
105    }
106}
107
108impl<'a> BitSliceable<RangeInclusive<u64>> for &'a mut [bool] {
109    type Slice = &'a mut [bool];
110
111    fn bit_slice(self, range: RangeInclusive<u64>) -> &'a mut [bool] {
112        let (start, end) =
113            get_inclusive_bounds(range).expect("<&mut [bool]>::bit_slice: bad inclusive range");
114        &mut self[start as usize..end as usize + 1]
115    }
116}
117
118impl<'a> BitSliceable<RangeFrom<u64>> for &'a [bool] {
119    type Slice = &'a [bool];
120
121    fn bit_slice(self, range: RangeFrom<u64>) -> &'a [bool] {
122        &self[range.start as usize..]
123    }
124}
125
126impl<'a> BitSliceable<RangeFrom<u64>> for &'a mut [bool] {
127    type Slice = &'a mut [bool];
128
129    fn bit_slice(self, range: RangeFrom<u64>) -> &'a mut [bool] {
130        &mut self[range.start as usize..]
131    }
132}
133
134impl<'a> BitSliceable<RangeTo<u64>> for &'a [bool] {
135    type Slice = &'a [bool];
136
137    fn bit_slice(self, range: RangeTo<u64>) -> &'a [bool] {
138        &self[..range.end as usize]
139    }
140}
141
142impl<'a> BitSliceable<RangeTo<u64>> for &'a mut [bool] {
143    type Slice = &'a mut [bool];
144
145    fn bit_slice(self, range: RangeTo<u64>) -> &'a mut [bool] {
146        &mut self[..range.end as usize]
147    }
148}
149
150impl<'a> BitSliceable<RangeToInclusive<u64>> for &'a [bool] {
151    type Slice = &'a [bool];
152
153    fn bit_slice(self, range: RangeToInclusive<u64>) -> &'a [bool] {
154        &self[RangeToInclusive {
155            end: range.end as usize,
156        }]
157    }
158}
159
160impl<'a> BitSliceable<RangeToInclusive<u64>> for &'a mut [bool] {
161    type Slice = &'a mut [bool];
162
163    fn bit_slice(self, range: RangeToInclusive<u64>) -> &'a mut [bool] {
164        &mut self[RangeToInclusive {
165            end: range.end as usize,
166        }]
167    }
168}