1#![no_std]
2#![deny(
3 missing_docs,
4 unused_extern_crates,
5 unused_import_braces,
6 unused_qualifications
7)]
8pub use bitfield_macros::{bitfield_constructor, bitfield_debug, bitfield_fields};
15
16#[macro_export(local_inner_macros)]
32macro_rules! bitfield_impl {
33 (Debug for struct $name:ident([$t:ty]); $($rest:tt)*) => {
34 impl<T: AsRef<[$t]> + $crate::fmt::Debug> $crate::fmt::Debug for $name<T> {
35 bitfield_debug!{struct $name; $($rest)*}
36 }
37 };
38 (Debug for struct $name:ident($t:ty); $($rest:tt)*) => {
39 impl $crate::fmt::Debug for $name {
40 bitfield_debug!{struct $name; $($rest)*}
41 }
42 };
43 (BitAnd for struct $name:ident([$t:ty]); $($rest:tt)*) => {
44 bitfield_impl!{@bitwise BitAnd bitand BitAndAssign bitand_assign $name([$t]) &=}
45 };
46 (BitAnd for struct $name:ident($t:ty); $($rest:tt)*) => {
47 bitfield_impl!{@bitwise BitAnd bitand BitAndAssign bitand_assign $name($t) &=}
48 };
49 (BitOr for struct $name:ident([$t:ty]); $($rest:tt)*) => {
50 bitfield_impl!{@bitwise BitOr bitor BitOrAssign bitor_assign $name([$t]) |=}
51 };
52 (BitOr for struct $name:ident($t:ty); $($rest:tt)*) => {
53 bitfield_impl!{@bitwise BitOr bitor BitOrAssign bitor_assign $name($t) |=}
54 };
55 (BitXor for struct $name:ident([$t:ty]); $($rest:tt)*) => {
56 bitfield_impl!{@bitwise BitXor bitxor BitXorAssign bitxor_assign $name([$t]) ^=}
57 };
58 (BitXor for struct $name:ident($t:ty); $($rest:tt)*) => {
59 bitfield_impl!{@bitwise BitXor bitxor BitXorAssign bitxor_assign $name($t) ^=}
60 };
61 (@bitwise $bitwise:ident $func:ident $bitwise_assign:ident $func_assign:ident $name:ident([$t:ty]) $op:tt) => {
62 impl<T: AsMut<[$t]> + AsRef<[$t]>> $crate::ops::$bitwise for $name<T> {
63 type Output = Self;
64 fn $func(mut self, rhs: Self) -> Self {
65 bitfield_impl!(@mutate self rhs $op);
66 self
67 }
68 }
69 impl<T: AsMut<[$t]> + AsRef<[$t]>> $crate::ops::$bitwise_assign for $name<T> {
70 fn $func_assign(&mut self, rhs: Self) {
71 bitfield_impl!(@mutate self rhs $op);
72 }
73 }
74 };
75 (@bitwise $bitwise:ident $func:ident $bitwise_assign:ident $func_assign:ident $name:ident($t:ty) $op:tt) => {
76 impl $crate::ops::$bitwise for $name {
77 type Output = Self;
78 fn $func(mut self, rhs: Self) -> Self {
79 self.0 $op rhs.0;
80 self
81 }
82 }
83 impl $crate::ops::$bitwise_assign for $name {
84 fn $func_assign(&mut self, rhs: Self) {
85 self.0 $op rhs.0;
86 }
87 }
88 };
89 (@mutate $self:ident $rhs:ident $op:tt) => {{
90 let as_mut = AsMut::<[_]>::as_mut(&mut $self.0);
91 let rhs = AsRef::<[_]>::as_ref(&$rhs.0);
92 for i in 0..as_mut.len() {
93 as_mut[i] $op rhs[i];
94 }
95 }};
96 (new for struct $name:ident([$t:ty]); $($rest:tt)*) => {
97 impl<T: AsMut<[$t]> + Default> $name<T> {
98 bitfield_constructor!{$($rest)*}
99 }
100 };
101 (new for struct $name:ident($t:ty); $($rest:tt)*) => {
102 impl $name {
103 bitfield_constructor!{$($rest)*}
104 }
105 };
106 (new{$new:ident ($($setter_name:ident: $setter_type:ty),*$(,)?)} for struct $name:ident([$t:ty]); $($rest:tt)*) => {
107 impl<T: AsMut<[$t]> + Default> $name<T> {
108 pub fn $new($($setter_name: $setter_type),*) -> Self {
109 let mut value = Self(T::default());
110 $(
111 value.$setter_name($setter_name);
112 )*
113 value
114 }
115 }
116 };
117 (new{$new:ident ($($setter_name:ident: $setter_type:ty),*$(,)?)} for struct $name:ident($t:ty); $($rest:tt)*) => {
118 impl $name {
119 pub fn $new($($setter_name: $setter_type),*) -> Self {
120 let mut value = Self($t::default());
121 $(
122 value.$setter_name($setter_name);
123 )*
124 value
125 }
126 }
127 };
128 ($macro:ident for struct $name:ident $($rest:tt)*) => {
130 ::std::compile_error!(::std::stringify!(Unsupported impl $macro for struct $name));
131 };
132}
133
134#[macro_export(local_inner_macros)]
166macro_rules! bitfield_bitrange {
167 (@impl_bitrange_slice $name:ident, $slice_ty:ty, $bitrange_ty:ty) => {
168 impl<T: AsRef<[$slice_ty]>> $crate::BitRange<$bitrange_ty>
169 for $name<T> {
170 fn bit_range(&self, msb: usize, lsb: usize) -> $bitrange_ty {
171 let bit_len = $crate::size_of::<$slice_ty>()*8;
172 let value_bit_len = $crate::size_of::<$bitrange_ty>()*8;
173 let mut value = 0;
174 for i in (lsb..=msb).rev() {
175 value <<= 1;
176 value |= ((self.0.as_ref()[i/bit_len] >> (i%bit_len)) & 1) as $bitrange_ty;
177 }
178 value << (value_bit_len - (msb - lsb + 1)) >> (value_bit_len - (msb - lsb + 1))
179 }
180 }
181 impl<T: AsMut<[$slice_ty]>> $crate::BitRangeMut<$bitrange_ty>
182 for $name<T> {
183
184 fn set_bit_range(&mut self, msb: usize, lsb: usize, value: $bitrange_ty) {
185 let bit_len = $crate::size_of::<$slice_ty>()*8;
186 let mut value = value;
187 for i in lsb..=msb {
188 self.0.as_mut()[i/bit_len] &= !(1 << (i%bit_len));
189 self.0.as_mut()[i/bit_len] |= (value & 1) as $slice_ty << (i%bit_len);
190 value >>= 1;
191 }
192 }
193 }
194 };
195 (@impl_bitrange_slice_msb0 $name:ident, $slice_ty:ty, $bitrange_ty:ty) => {
196 impl<T: AsRef<[$slice_ty]>> $crate::BitRange<$bitrange_ty>
197 for $name<T> {
198 fn bit_range(&self, msb: usize, lsb: usize) -> $bitrange_ty {
199 let bit_len = $crate::size_of::<$slice_ty>()*8;
200 let value_bit_len = $crate::size_of::<$bitrange_ty>()*8;
201 let mut value = 0;
202 for i in lsb..=msb {
203 value <<= 1;
204 value |= ((self.0.as_ref()[i/bit_len] >> (bit_len - i%bit_len - 1)) & 1)
205 as $bitrange_ty;
206 }
207 value << (value_bit_len - (msb - lsb + 1)) >> (value_bit_len - (msb - lsb + 1))
208 }
209 }
210 impl<T: AsMut<[$slice_ty]>> $crate::BitRangeMut<$bitrange_ty>
211 for $name<T> {
212 fn set_bit_range(&mut self, msb: usize, lsb: usize, value: $bitrange_ty) {
213 let bit_len = $crate::size_of::<$slice_ty>()*8;
214 let mut value = value;
215 for i in (lsb..=msb).rev() {
216 self.0.as_mut()[i/bit_len] &= !(1 << (bit_len - i%bit_len - 1));
217 self.0.as_mut()[i/bit_len] |= (value & 1) as $slice_ty
218 << (bit_len - i%bit_len - 1);
219 value >>= 1;
220 }
221 }
222 }
223 };
224 (struct $name:ident([$t:ty])) => {
225 bitfield_bitrange!(@impl_bitrange_slice $name, $t, u8);
226 bitfield_bitrange!(@impl_bitrange_slice $name, $t, u16);
227 bitfield_bitrange!(@impl_bitrange_slice $name, $t, u32);
228 bitfield_bitrange!(@impl_bitrange_slice $name, $t, u64);
229 bitfield_bitrange!(@impl_bitrange_slice $name, $t, u128);
230 bitfield_bitrange!(@impl_bitrange_slice $name, $t, i8);
231 bitfield_bitrange!(@impl_bitrange_slice $name, $t, i16);
232 bitfield_bitrange!(@impl_bitrange_slice $name, $t, i32);
233 bitfield_bitrange!(@impl_bitrange_slice $name, $t, i64);
234 bitfield_bitrange!(@impl_bitrange_slice $name, $t, i128);
235 };
236 (struct $name:ident(MSB0 [$t:ty])) => {
237 bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, u8);
238 bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, u16);
239 bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, u32);
240 bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, u64);
241 bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, u128);
242 bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, i8);
243 bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, i16);
244 bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, i32);
245 bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, i64);
246 bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, i128);
247 };
248 (struct $name:ident($t:ty)) => {
249 impl<T> $crate::BitRange<T> for $name where $t: $crate::BitRange<T> {
250 fn bit_range(&self, msb: usize, lsb: usize) -> T {
251 self.0.bit_range(msb, lsb)
252 }
253 }
254 impl<T> $crate::BitRangeMut<T> for $name where $t: $crate::BitRangeMut<T> {
255 fn set_bit_range(&mut self, msb: usize, lsb: usize, value: T) {
256 self.0.set_bit_range(msb, lsb, value);
257 }
258 }
259 };
260}
261
262#[macro_export(local_inner_macros)]
323macro_rules! bitfield {
324 ($(#[$attribute:meta])* $vis:vis struct $name:ident($($type:tt)*); $(impl $trait:ident$({$($trait_arg:tt)*})?;)+ no default BitRange; $($rest:tt)*) => {
327 bitfield!{$(#[$attribute])* $vis struct $name($($type)*); no default BitRange; $(impl $trait$({$($trait_arg)*})?;)* $($rest)*}
328 };
329
330 ($(#[$attribute:meta])* $vis:vis struct $name:ident([$t:ty]); no default BitRange; impl $trait:ident$({$($trait_arg:tt)*})?; $($rest:tt)*) => {
333 bitfield_impl!{$trait$({$($trait_arg)*})? for struct $name([$t]); $($rest)*}
334
335 bitfield!{$(#[$attribute])* $vis struct $name([$t]); no default BitRange; $($rest)*}
336 };
337 ($(#[$attribute:meta])* $vis:vis struct $name:ident([$t:ty]); no default BitRange; $($rest:tt)*) => {
338 $(#[$attribute])*
339 $vis struct $name<T>(pub T);
340
341 impl<T: AsRef<[$t]>> $name<T> {
345 bitfield_fields!{only getter; $($rest)*}
346 }
347 impl<T: AsMut<[$t]>> $name<T> {
348 bitfield_fields!{only setter; $($rest)*}
349 }
350 };
351 ($(#[$attribute:meta])* $vis:vis struct $name:ident([$t:ty]); $($rest:tt)*) => {
352 bitfield_bitrange!(struct $name([$t]));
353 bitfield!{$(#[$attribute])* $vis struct $name([$t]); no default BitRange; $($rest)*}
354 };
355
356 ($(#[$attribute:meta])* $vis:vis struct $name:ident(MSB0 [$t:ty]); no default BitRange; $($rest:tt)*) => {
359 bitfield!{$(#[$attribute])* $vis struct $name([$t]); no default BitRange; $($rest)*}
360 };
361 ($(#[$attribute:meta])* $vis:vis struct $name:ident(MSB0 [$t:ty]); $($rest:tt)*) => {
362 bitfield_bitrange!(struct $name(MSB0 [$t]));
363 bitfield!{$(#[$attribute])* $vis struct $name([$t]); no default BitRange; $($rest)*}
364 };
365
366 ($(#[$attribute:meta])* $vis:vis struct $name:ident($t:ty); no default BitRange; impl $trait:ident$({$($trait_arg:tt)*})?; $($rest:tt)*) => {
367 bitfield_impl!{$trait$({$($trait_arg)*})? for struct $name($t); $($rest)*}
368
369 bitfield!{$(#[$attribute])* $vis struct $name($t); no default BitRange; $($rest)*}
370 };
371 ($(#[$attribute:meta])* $vis:vis struct $name:ident($t:ty); no default BitRange; $($rest:tt)*) => {
372 $(#[$attribute])*
373 $vis struct $name(pub $t);
374
375 impl $name {
376 bitfield_fields!{$t; $($rest)*}
377 }
378 };
379 ($(#[$attribute:meta])* $vis:vis struct $name:ident($t:ty); $($rest:tt)*) => {
380 bitfield_bitrange!(struct $name($t));
381 bitfield!{$(#[$attribute])* $vis struct $name($t); no default BitRange; $($rest)*}
382 };
383}
384
385#[doc(hidden)]
386pub use core::convert::Into;
387#[doc(hidden)]
388pub use core::fmt;
389#[doc(hidden)]
390pub use core::mem::size_of;
391#[doc(hidden)]
392pub use core::ops;
393
394pub trait BitRange<T> {
396 fn bit_range(&self, msb: usize, lsb: usize) -> T;
398}
399
400pub trait BitRangeMut<T> {
402 fn set_bit_range(&mut self, msb: usize, lsb: usize, value: T);
404}
405
406pub trait Bit {
410 fn bit(&self, bit: usize) -> bool;
412}
413
414pub trait BitMut {
418 fn set_bit(&mut self, bit: usize, value: bool);
420}
421
422impl<T: BitRange<u8>> Bit for T {
423 fn bit(&self, bit: usize) -> bool {
424 self.bit_range(bit, bit) != 0
425 }
426}
427
428impl<T: BitRangeMut<u8>> BitMut for T {
429 fn set_bit(&mut self, bit: usize, value: bool) {
430 self.set_bit_range(bit, bit, value as u8);
431 }
432}
433
434macro_rules! impl_bitrange_for_u {
435 ($t:ty, $bitrange_ty:ty) => {
436 impl BitRange<$bitrange_ty> for $t {
437 #[inline]
438 #[allow(clippy::cast_lossless)]
439 #[allow(clippy::manual_bits)]
440 fn bit_range(&self, msb: usize, lsb: usize) -> $bitrange_ty {
441 let bit_len = size_of::<$t>()*8;
442 let result_bit_len = size_of::<$bitrange_ty>()*8;
443 let result = ((*self << (bit_len - msb - 1)) >> (bit_len - msb - 1 + lsb))
444 as $bitrange_ty;
445 result << (result_bit_len - (msb - lsb + 1)) >> (result_bit_len - (msb - lsb + 1))
446 }
447 }
448
449 impl BitRangeMut<$bitrange_ty> for $t {
450 #[inline]
451 #[allow(clippy::cast_lossless)]
452 #[allow(clippy::manual_bits)]
453 fn set_bit_range(&mut self, msb: usize, lsb: usize, value: $bitrange_ty) {
454 let bit_len = size_of::<$t>()*8;
455 let mask: $t = !(0 as $t)
456 << (bit_len - msb - 1)
457 >> (bit_len - msb - 1 + lsb)
458 << (lsb);
459 *self &= !mask;
460 *self |= (value as $t << lsb) & mask;
461 }
462 }
463 }
464}
465
466macro_rules! impl_bitrange_for_u_combinations {
467((),($($bitrange_ty:ty),*)) => {
468
469};
470(($t:ty),($($bitrange_ty:ty),*)) => {
471 $(impl_bitrange_for_u!{$t, $bitrange_ty})*
472};
473 (($t_head:ty, $($t_rest:ty),*),($($bitrange_ty:ty),*)) => {
474 impl_bitrange_for_u_combinations!{($t_head), ($($bitrange_ty),*)}
475 impl_bitrange_for_u_combinations!{($($t_rest),*), ($($bitrange_ty),*)}
476 };
477}
478
479impl_bitrange_for_u_combinations! {(u8, u16, u32, u64, u128), (u8, u16, u32, u64, u128)}
480impl_bitrange_for_u_combinations! {(u8, u16, u32, u64, u128), (i8, i16, i32, i64, i128)}