bv/traits/
bit_sliceable.rs

1use {Bits, BitsMut};
2use range_compat::*;
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 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 where Self: Sized {
49        self.bit_slice(range)
50    }
51}
52
53impl<Range, T> BitSliceableMut<Range> for T
54    where T: BitSliceable<Range>,
55          T::Slice: BitsMut { }
56
57
58impl<'a> BitSliceable<RangeFull> for &'a [bool] {
59    type Slice = &'a [bool];
60
61    fn bit_slice(self, _: RangeFull) -> &'a [bool] {
62        self
63    }
64}
65
66impl<'a> BitSliceable<RangeFull> for &'a mut [bool] {
67    type Slice = &'a mut [bool];
68
69    fn bit_slice(self, _: RangeFull) -> &'a mut [bool] {
70        self
71    }
72}
73
74impl<'a> BitSliceable<Range<u64>> for &'a [bool] {
75    type Slice = &'a [bool];
76
77    fn bit_slice(self, range: Range<u64>) -> &'a [bool] {
78        &self[range.start as usize .. range.end as usize]
79    }
80}
81
82impl<'a> BitSliceable<Range<u64>> for &'a mut [bool] {
83    type Slice = &'a mut [bool];
84
85    fn bit_slice(self, range: Range<u64>) -> &'a mut [bool] {
86        &mut self[range.start as usize .. range.end as usize]
87    }
88}
89
90#[cfg(inclusive_range)]
91impl<'a> BitSliceable<RangeInclusive<u64>> for &'a [bool] {
92    type Slice = &'a [bool];
93
94    fn bit_slice(self, range: RangeInclusive<u64>) -> &'a [bool] {
95        let (start, end) = get_inclusive_bounds(range)
96            .expect("<&[bool]>::bit_slice: bad inclusive range");
97        // Adding 1 means we could overflow a 32-bit `usize` here, but
98        // we can't construct a RangeInclusive on stable without using
99        // the `..=` token, which breaks older rustcs.
100        &self[start as usize .. end as usize + 1]
101    }
102}
103
104#[cfg(inclusive_range)]
105impl<'a> BitSliceable<RangeInclusive<u64>> for &'a mut [bool] {
106    type Slice = &'a mut [bool];
107
108    fn bit_slice(self, range: RangeInclusive<u64>) -> &'a mut [bool] {
109        let (start, end) = get_inclusive_bounds(range)
110            .expect("<&mut [bool]>::bit_slice: bad inclusive range");
111        &mut self[start as usize .. end as usize + 1]
112    }
113}
114
115impl<'a> BitSliceable<RangeFrom<u64>> for &'a [bool] {
116    type Slice = &'a [bool];
117
118    fn bit_slice(self, range: RangeFrom<u64>) -> &'a [bool] {
119        &self[range.start as usize ..]
120    }
121}
122
123impl<'a> BitSliceable<RangeFrom<u64>> for &'a mut [bool] {
124    type Slice = &'a mut [bool];
125
126    fn bit_slice(self, range: RangeFrom<u64>) -> &'a mut [bool] {
127        &mut self[range.start as usize ..]
128    }
129}
130
131impl<'a> BitSliceable<RangeTo<u64>> for &'a [bool] {
132    type Slice = &'a [bool];
133
134    fn bit_slice(self, range: RangeTo<u64>) -> &'a [bool] {
135        &self[.. range.end as usize]
136    }
137}
138
139impl<'a> BitSliceable<RangeTo<u64>> for &'a mut [bool] {
140    type Slice = &'a mut [bool];
141
142    fn bit_slice(self, range: RangeTo<u64>) -> &'a mut [bool] {
143        &mut self[.. range.end as usize]
144    }
145}
146
147#[cfg(inclusive_range)]
148impl<'a> BitSliceable<RangeToInclusive<u64>> for &'a [bool] {
149    type Slice = &'a [bool];
150
151    fn bit_slice(self, range: RangeToInclusive<u64>) -> &'a [bool] {
152        &self[RangeToInclusive { end: range.end as usize }]
153    }
154}
155
156#[cfg(inclusive_range)]
157impl<'a> BitSliceable<RangeToInclusive<u64>> for &'a mut [bool] {
158    type Slice = &'a mut [bool];
159
160    fn bit_slice(self, range: RangeToInclusive<u64>) -> &'a mut [bool] {
161        &mut self[RangeToInclusive { end: range.end as usize }]
162    }
163}
164