grit_bitvec/
typed_bitvec.rs

1use std::ops::RangeFrom;
2
3use crate::{
4    RawBitVec,
5    TypedBitElem, 
6    TypedBitVecDrain, 
7    TypedBitVecIter,
8    Range,
9    ManuallyDrop,
10    PhantomData
11};
12
13/// ## `TypedBitVec`: "Typed Bitwise Vector"  
14/// A `BitVec` where all the data needed to access and translate the generic `<T>` to and from the expected `usize`
15/// is stored in a monomorphized constant inside the trait [`TypedBitElem`]
16/// 
17/// This is a thin wrapper around [`RawBitVec`] that simply calls the underlying raw method and passes the associated
18/// [`BitProto`](crate::BitProto) along with it, translating the input type to and from `usize` according to the specific implementation
19/// of [`TypedBitElem`]. Unlike [`RawBitVec`] this is safe because it is impossible to ever use the wrong [`BitProto`](crate::BitProto)
20/// 
21/// ### Pros
22/// - Simpler, safer API than [`RawBitVec`]
23/// - Same stack-size as [`RawBitVec`] and [`Vec`] (3 usize)
24/// - Allows for constant-propogation optimizations
25/// - Values are automatically translated to and from the generic type `<T>`
26/// 
27/// ### Cons
28/// - Every separate value of `<T>` creates a distinct type with its own copy of all methods (larger binary)
29/// - Cannot store [`TypedBitVec`]'s with diferent `<T>`'s in the same homogenous collection (`Array`, [`Vec`], [`HashMap`](std::collections::HashMap), etc.)
30/// - *May* require aditional processing to translate the normal `usize` to and from `<T>`
31/// - `<T>` must implement `TypedBitElem` (simple integer implementations are provided via crate features)
32pub struct TypedBitVec<T: TypedBitElem>(pub(crate) RawBitVec, PhantomData<T>);
33
34impl<T: TypedBitElem> TypedBitVec<T> {
35
36    #[inline(always)]
37    pub fn len(&self) -> usize {
38        self.0.len
39    }
40
41    #[inline(always)]
42    pub fn cap(&self) -> usize {
43        unsafe {self.0.cap(T::PROTO)}
44    }
45
46    #[inline(always)]
47    pub fn free(&self) -> usize {
48        unsafe{self.0.free(T::PROTO)}
49    }
50
51    #[inline(always)]
52    pub fn new() -> Self {
53        Self(RawBitVec::new(), PhantomData)
54    }
55
56    #[inline(always)]
57    pub fn with_capacity(cap: usize) -> Self {
58        Self(RawBitVec::with_capacity(T::PROTO, cap), PhantomData)
59    }
60
61    #[inline(always)]
62    pub fn grow_exact_for_additional_elements_if_needed(&mut self, extra_elements: usize) -> Result<(), String> {
63        unsafe {self.0.grow_exact_for_additional_elements_if_needed(T::PROTO, extra_elements)}
64    }
65
66    #[inline(always)]
67    pub fn grow_exact_for_total_elements_if_needed(&mut self, total_elements: usize) -> Result<(), String> {
68        unsafe {self.0.grow_exact_for_total_elements_if_needed(T::PROTO, total_elements)}
69    }
70
71    #[inline(always)]
72    pub fn grow_for_additional_elements_if_needed(&mut self, extra_elements: usize) -> Result<(), String> {
73        unsafe {self.0.grow_for_additional_elements_if_needed(T::PROTO, extra_elements)}
74    }
75
76    #[inline(always)]
77    pub fn grow_for_total_elements_if_needed(&mut self, total_elements: usize) -> Result<(), String> {
78        unsafe {self.0.grow_for_total_elements_if_needed(T::PROTO, total_elements)}
79    }
80
81    #[inline(always)]
82    pub fn clear(&mut self) {
83        self.0.clear()
84    }
85
86    #[inline(always)]
87    pub fn push(&mut self, val: T::Base) -> Result<(), String> {
88        unsafe {self.0.push(T::PROTO, T::val_to_bits(val))}
89    }
90
91    #[inline(always)]
92    pub unsafe fn push_unchecked(&mut self, val: T::Base) {
93        self.0.push_unchecked(T::PROTO, T::val_to_bits(val))
94    }
95
96    #[inline(always)]
97    pub fn pop(&mut self) -> Result<T::Base, String> {
98        match unsafe{self.0.pop(T::PROTO)} {
99            Ok(bits) => Ok(T::bits_to_val(bits)),
100            Err(e) => Err(e),
101        }
102    }
103
104    #[inline(always)]
105    pub unsafe fn pop_unchecked(&mut self) -> T::Base {
106        T::bits_to_val(self.0.pop_unchecked(T::PROTO))
107    }
108
109    #[inline(always)]
110    pub fn insert(&mut self, idx: usize, val: T::Base) -> Result<(), String> {
111        unsafe{self.0.insert(T::PROTO, idx, T::val_to_bits(val))}
112    }
113
114    #[inline(always)]
115    pub unsafe fn insert_unchecked(&mut self, idx: usize, val: T::Base) {
116        self.0.insert_unchecked(T::PROTO, idx, T::val_to_bits(val))
117    }
118
119    #[inline(always)]
120    pub fn insert_bitvec(&mut self, insert_idx: usize, bitvec: Self) -> Result<(), String> {
121        unsafe{self.0.insert_bitvec(T::PROTO, insert_idx, bitvec.into_raw())}
122    }
123
124    #[inline(always)]
125    pub unsafe fn insert_bitvec_unchecked(&mut self, insert_idx: usize, bitvec: Self) {
126        self.0.insert_bitvec_unchecked(T::PROTO, insert_idx, bitvec.into_raw())
127    }
128
129    #[inline]
130    pub fn insert_iter<II, TO, ESI>(&mut self, insert_idx: usize, source: II) -> Result<(), String>
131    where II: IntoIterator<Item = TO, IntoIter = ESI>, TO: ToOwned<Owned = usize>, ESI: ExactSizeIterator + Iterator<Item = TO> {
132        unsafe {self.0.insert_iter(T::PROTO, insert_idx, source)}
133    }
134
135    #[inline]
136    pub unsafe fn insert_iter_unchecked<II, TO, ESI>(&mut self, insert_idx: usize, source: II)
137    where II: IntoIterator<Item = TO, IntoIter = ESI>, TO: ToOwned<Owned = usize>, ESI: ExactSizeIterator + Iterator<Item = TO> {
138        self.0.insert_iter_unchecked(T::PROTO, insert_idx, source)
139    }
140
141    #[inline(always)]
142    pub fn remove(&mut self, idx: usize) -> Result<T::Base, String> {
143        match unsafe{self.0.remove(T::PROTO, idx)} {
144            Ok(bits) => Ok(T::bits_to_val(bits)),
145            Err(e) => Err(e),
146        }
147    }
148
149    #[inline(always)]
150    pub unsafe fn remove_unchecked(&mut self, idx: usize) -> T::Base {
151        T::bits_to_val(self.0.remove_unchecked(T::PROTO, idx))
152    }
153
154    #[inline(always)]
155    pub fn remove_range(&mut self, idx_range: Range<usize>) -> Result<Self, String> {
156        match unsafe{self.0.remove_range(T::PROTO, idx_range)} {
157            Ok(raw) => Ok(Self(raw, PhantomData)),
158            Err(e) => Err(e),
159        }
160    }
161
162    #[inline(always)]
163    pub unsafe fn remove_range_unchecked(&mut self, idx_range: Range<usize>) -> Self {
164        Self(self.0.remove_range_unchecked(T::PROTO, idx_range), PhantomData)
165    }
166
167    #[inline(always)]
168    pub fn trim_range(&mut self, idx_range: RangeFrom<usize>) -> Result<Self, String> {
169        match unsafe{self.0.trim_range(T::PROTO, idx_range)} {
170            Ok(raw) => Ok(Self(raw, PhantomData)),
171            Err(e) => Err(e),
172        }
173    }
174
175    #[inline(always)]
176    pub unsafe fn trim_range_unchecked(&mut self, idx_range: RangeFrom<usize>) -> Self {
177        Self(self.0.trim_range_unchecked(T::PROTO, idx_range), PhantomData)
178    }
179
180    #[inline(always)]
181    pub fn swap(&mut self, idx_a: usize, idx_b: usize) -> Result<(), String> {
182        unsafe{self.0.swap(T::PROTO, idx_a, idx_b)}
183    }
184
185    #[inline(always)]
186    pub unsafe fn swap_unchecked(&mut self, idx_a: usize, idx_b: usize) {
187        self.0.swap_unchecked(T::PROTO, idx_a, idx_b)
188}
189
190    #[inline(always)]
191    pub fn swap_pop(&mut self, idx: usize) -> Result<T::Base, String> {
192        match unsafe{self.0.swap_pop(T::PROTO, idx)} {
193            Ok(bits) => Ok(T::bits_to_val(bits)),
194            Err(e) => Err(e),
195        }
196    }
197
198    #[inline(always)]
199    pub unsafe fn swap_pop_unchecked(&mut self, idx: usize) -> T::Base {
200        T::bits_to_val(self.0.swap_pop_unchecked(T::PROTO, idx))
201    }
202
203    #[inline(always)]
204    pub fn trim_excess_capacity(&mut self, extra_capacity_to_keep: usize) -> Result<(), String> {
205        unsafe{self.0.trim_excess_capacity(T::PROTO, extra_capacity_to_keep)}
206    }
207
208    #[inline(always)]
209    pub fn append_bitvec(&mut self, bitvec: Self) -> Result<(), String> {
210        unsafe{self.0.append_bitvec(T::PROTO, bitvec.into_raw())}
211    }
212
213    #[inline(always)]
214    pub unsafe fn append_bitvec_unchecked(&mut self, bitvec: Self) {
215        self.0.append_bitvec_unchecked(T::PROTO, bitvec.into_raw())
216    }
217
218    #[inline(always)]
219    pub fn append_iter<II, TO, ESI>(&mut self, source: II) -> Result<(), String>
220    where II: IntoIterator<Item = TO, IntoIter = ESI>, TO: ToOwned<Owned = T::Base>, ESI: ExactSizeIterator + Iterator<Item = TO> {
221        unsafe{self.0.append_iter(T::PROTO, source.into_iter().map(|val| T::val_to_bits(val.to_owned())))}
222    }
223
224    #[inline(always)]
225    pub unsafe fn append_iter_unchecked<I, TO>(&mut self, iter: I)
226    where I: Iterator<Item = TO> + ExactSizeIterator, TO: ToOwned<Owned = T::Base> {
227        self.0.append_iter_unchecked(T::PROTO, iter.map(|val| T::val_to_bits(val.to_owned())))
228    }
229
230    #[inline(always)]
231    pub fn get(&self, idx: usize) -> Result<T::Base, String> {
232        match unsafe{self.0.get(T::PROTO, idx)} {
233            Ok(bits) => Ok(T::bits_to_val(bits)),
234            Err(e) => Err(e),
235        }
236    }
237
238    #[inline(always)]
239    pub unsafe fn get_unchecked(&self, idx: usize) -> T::Base {
240        T::bits_to_val(self.0.get_unchecked(T::PROTO, idx))
241    }
242
243    #[inline(always)]
244    pub fn replace(&mut self, idx: usize, val: T::Base) -> Result<T::Base, String> {
245        match unsafe{self.0.replace(T::PROTO, idx, T::val_to_bits(val))} {
246            Ok(bits) => Ok(T::bits_to_val(bits)),
247            Err(e) => Err(e),
248        }
249    }
250
251    #[inline(always)]
252    pub unsafe fn replace_unchecked(&mut self, idx: usize, val: T::Base) -> T::Base {
253        T::bits_to_val(self.0.replace_unchecked(T::PROTO, idx, T::val_to_bits(val)))
254    }
255
256    #[inline(always)]
257    pub fn set(&mut self, idx: usize, val: T::Base) -> Result<(), String> {
258        unsafe{self.0.set(T::PROTO, idx, T::val_to_bits(val))}
259    }
260
261    #[inline(always)]
262    pub unsafe fn set_unchecked(&mut self, idx: usize, val: T::Base) {
263        self.0.set_unchecked(T::PROTO, idx, T::val_to_bits(val))
264    }
265
266    #[inline]
267    pub fn discard_from_end(&mut self, count: usize) {
268        self.0.discard_from_end(count)
269    }
270
271    #[inline(always)]
272    pub fn drain<'vec>(&'vec mut self) -> TypedBitVecDrain<'vec, T> {
273        TypedBitVecDrain(self.0.drain(), PhantomData)
274    }
275
276    #[inline(always)]
277    pub unsafe fn into_raw(self) -> RawBitVec {
278        let nodrop_self = ManuallyDrop::new(self);
279        RawBitVec {
280            ptr: nodrop_self.0.ptr,
281            len: nodrop_self.0.len, 
282            true_cap: nodrop_self.0.true_cap 
283        }
284    }
285}
286
287impl<T: TypedBitElem> IntoIterator for TypedBitVec<T> {
288    type Item = T::Base;
289
290    type IntoIter = TypedBitVecIter<T>;
291
292    #[inline(always)]
293    fn into_iter(self) -> Self::IntoIter {
294        TypedBitVecIter(unsafe{self.into_raw().into_iter()}, PhantomData)
295    }
296}
297
298impl<T: TypedBitElem> Drop for TypedBitVec<T> {
299    #[inline(always)]
300    fn drop(&mut self) {/* RawBitVec::drop() will take care of the allocation */}
301}