deepmesa_collections/bitvec/
bitref.rs

1/*
2   BitVector: A fast contiguous growable array of bits allocated
3   on the heap that allows storing and manipulating an arbitrary
4   number of bits. This collection is backed by a Vector<u8> which
5   manages the underlying memory.
6
7   Copyright 2021 "Rahul Singh <rsingh@arrsingh.com>"
8
9   Licensed under the Apache License, Version 2.0 (the "License");
10   you may not use this file except in compliance with the License.
11   You may obtain a copy of the License at
12
13       http://www.apache.org/licenses/LICENSE-2.0
14
15   Unless required by applicable law or agreed to in writing, software
16   distributed under the License is distributed on an "AS IS" BASIS,
17   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   See the License for the specific language governing permissions and
19   limitations under the License.
20*/
21
22use crate::bitvec::{bitops, traits::BitwiseClearAssign};
23
24use core::marker;
25use core::ops::Deref;
26use core::ops::DerefMut;
27
28#[derive(Debug, PartialEq)]
29pub struct BitRef<'a, T> {
30    bit: bool,
31    _marker: marker::PhantomData<&'a T>,
32}
33
34#[derive(Debug, PartialEq)]
35pub struct BitRefMut<'a, T> {
36    bit: bool,
37    mut_bit: bool,
38    byte_ptr: *mut u8,
39    _marker: marker::PhantomData<&'a T>,
40    bit_index: usize,
41}
42
43impl<'a, T> BitRef<'a, T> {
44    pub(super) fn new(bit: bool) -> BitRef<'a, T> {
45        BitRef {
46            bit,
47            _marker: marker::PhantomData,
48        }
49    }
50}
51
52impl<'a, T> BitRefMut<'a, T> {
53    pub(super) fn new(bit: bool, byte_ptr: *mut u8, bit_index: usize) -> BitRefMut<'a, T> {
54        BitRefMut {
55            bit,
56            mut_bit: bit,
57            byte_ptr: byte_ptr,
58            _marker: marker::PhantomData,
59            bit_index: bit_index,
60        }
61    }
62}
63
64impl<'a, T> Drop for BitRefMut<'a, T> {
65    fn drop(&mut self) {
66        if self.bit != self.mut_bit {
67            if self.byte_ptr == core::ptr::null_mut() {
68                panic!("Cannot assign to immutable BitRefMut");
69            }
70
71            if self.mut_bit {
72                unsafe {
73                    bitops::set_msb_n(&mut *self.byte_ptr, (self.bit_index % 8) as u8);
74                }
75            } else {
76                unsafe {
77                    (*self.byte_ptr).clear_msb_nth_assign((self.bit_index % 8) as u8);
78                }
79            }
80        }
81    }
82}
83
84impl<'a, T> Deref for BitRef<'a, T> {
85    type Target = bool;
86    fn deref(&self) -> &Self::Target {
87        &self.bit
88    }
89}
90
91impl<'a, T> Deref for BitRefMut<'a, T> {
92    type Target = bool;
93    fn deref(&self) -> &Self::Target {
94        &self.mut_bit
95    }
96}
97
98impl<'a, T> DerefMut for BitRefMut<'a, T> {
99    fn deref_mut(&mut self) -> &mut Self::Target {
100        &mut self.mut_bit
101    }
102}