16
16
Storage : AsRef < [ u8 ] > + AsMut < [ u8 ] > ,
17
17
{
18
18
#[ inline]
19
- pub fn get_bit ( & self , index : usize ) -> bool {
20
- debug_assert ! ( index / 8 < self . storage. as_ref( ) . len( ) ) ;
21
-
22
- let byte_index = index / 8 ;
23
- let byte = self . storage . as_ref ( ) [ byte_index] ;
24
-
19
+ fn extract_bit ( byte : u8 , index : usize ) -> bool {
25
20
let bit_index = if cfg ! ( target_endian = "big" ) {
26
21
7 - ( index % 8 )
27
22
} else {
@@ -34,12 +29,28 @@ where
34
29
}
35
30
36
31
#[ inline]
37
- pub fn set_bit ( & mut self , index : usize , val : bool ) {
32
+ pub fn get_bit ( & self , index : usize ) -> bool {
38
33
debug_assert ! ( index / 8 < self . storage. as_ref( ) . len( ) ) ;
39
34
40
35
let byte_index = index / 8 ;
41
- let byte = & mut self . storage . as_mut ( ) [ byte_index] ;
36
+ let byte = self . storage . as_ref ( ) [ byte_index] ;
37
+
38
+ Self :: extract_bit ( byte, index)
39
+ }
40
+
41
+ #[ inline]
42
+ pub unsafe fn raw_get_bit ( this : * const Self , index : usize ) -> bool {
43
+ debug_assert ! ( index / 8 < std:: mem:: size_of:: <Storage >( ) ) ;
44
+
45
+ let byte_index = index / 8 ;
46
+ let byte = * ( std:: ptr:: addr_of!( ( * this) . storage) as * const u8 )
47
+ . offset ( byte_index as isize ) ;
48
+
49
+ Self :: extract_bit ( byte, index)
50
+ }
42
51
52
+ #[ inline]
53
+ fn change_bit ( byte : u8 , index : usize , val : bool ) -> u8 {
43
54
let bit_index = if cfg ! ( target_endian = "big" ) {
44
55
7 - ( index % 8 )
45
56
} else {
@@ -48,12 +59,33 @@ where
48
59
49
60
let mask = 1 << bit_index;
50
61
if val {
51
- * byte |= mask;
62
+ byte | mask
52
63
} else {
53
- * byte &= !mask;
64
+ byte & !mask
54
65
}
55
66
}
56
67
68
+ #[ inline]
69
+ pub fn set_bit ( & mut self , index : usize , val : bool ) {
70
+ debug_assert ! ( index / 8 < self . storage. as_ref( ) . len( ) ) ;
71
+
72
+ let byte_index = index / 8 ;
73
+ let byte = & mut self . storage . as_mut ( ) [ byte_index] ;
74
+
75
+ * byte = Self :: change_bit ( * byte, index, val) ;
76
+ }
77
+
78
+ #[ inline]
79
+ pub unsafe fn raw_set_bit ( this : * mut Self , index : usize , val : bool ) {
80
+ debug_assert ! ( index / 8 < std:: mem:: size_of:: <Storage >( ) ) ;
81
+
82
+ let byte_index = index / 8 ;
83
+ let byte = ( std:: ptr:: addr_of_mut!( ( * this) . storage) as * mut u8 )
84
+ . offset ( byte_index as isize ) ;
85
+
86
+ * byte = Self :: change_bit ( * byte, index, val) ;
87
+ }
88
+
57
89
#[ inline]
58
90
pub fn get ( & self , bit_offset : usize , bit_width : u8 ) -> u64 {
59
91
debug_assert ! ( bit_width <= 64 ) ;
@@ -79,6 +111,35 @@ where
79
111
val
80
112
}
81
113
114
+ #[ inline]
115
+ pub unsafe fn raw_get (
116
+ this : * const Self ,
117
+ bit_offset : usize ,
118
+ bit_width : u8 ,
119
+ ) -> u64 {
120
+ debug_assert ! ( bit_width <= 64 ) ;
121
+ debug_assert ! ( bit_offset / 8 < std:: mem:: size_of:: <Storage >( ) ) ;
122
+ debug_assert ! (
123
+ ( bit_offset + ( bit_width as usize ) ) / 8 <=
124
+ std:: mem:: size_of:: <Storage >( )
125
+ ) ;
126
+
127
+ let mut val = 0 ;
128
+
129
+ for i in 0 ..( bit_width as usize ) {
130
+ if Self :: raw_get_bit ( this, i + bit_offset) {
131
+ let index = if cfg ! ( target_endian = "big" ) {
132
+ bit_width as usize - 1 - i
133
+ } else {
134
+ i
135
+ } ;
136
+ val |= 1 << index;
137
+ }
138
+ }
139
+
140
+ val
141
+ }
142
+
82
143
#[ inline]
83
144
pub fn set ( & mut self , bit_offset : usize , bit_width : u8 , val : u64 ) {
84
145
debug_assert ! ( bit_width <= 64 ) ;
@@ -99,4 +160,30 @@ where
99
160
self . set_bit ( index + bit_offset, val_bit_is_set) ;
100
161
}
101
162
}
163
+
164
+ #[ inline]
165
+ pub unsafe fn raw_set (
166
+ this : * mut Self ,
167
+ bit_offset : usize ,
168
+ bit_width : u8 ,
169
+ val : u64 ,
170
+ ) {
171
+ debug_assert ! ( bit_width <= 64 ) ;
172
+ debug_assert ! ( bit_offset / 8 < std:: mem:: size_of:: <Storage >( ) ) ;
173
+ debug_assert ! (
174
+ ( bit_offset + ( bit_width as usize ) ) / 8 <=
175
+ std:: mem:: size_of:: <Storage >( )
176
+ ) ;
177
+
178
+ for i in 0 ..( bit_width as usize ) {
179
+ let mask = 1 << i;
180
+ let val_bit_is_set = val & mask == mask;
181
+ let index = if cfg ! ( target_endian = "big" ) {
182
+ bit_width as usize - 1 - i
183
+ } else {
184
+ i
185
+ } ;
186
+ Self :: raw_set_bit ( this, index + bit_offset, val_bit_is_set) ;
187
+ }
188
+ }
102
189
}
0 commit comments