1#![no_std]
2#![deny(
3 missing_docs,
4 unused_extern_crates,
5 unused_import_braces,
6 unused_qualifications
7)]
8
9#[macro_export(local_inner_macros)]
82macro_rules! bitfield_fields {
83 (@field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, _, $setter:ident: $msb:expr,
84 $lsb:expr, $count:expr) => {
85 $(#[$attribute])*
86 #[allow(unknown_lints)]
87 #[allow(eq_op)]
88 $($vis)* fn $setter(&mut self, index: usize, value: $from) {
89 use $crate::BitRange;
90 __bitfield_debug_assert!(index < $count);
91 let width = $msb - $lsb + 1;
92 let lsb = $lsb + index*width;
93 let msb = lsb + width - 1;
94 self.set_bit_range(msb, lsb, $crate::Into::<$t>::into(value));
95 }
96 };
97 (@field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, _, $setter:ident: $msb:expr,
98 $lsb:expr) => {
99 $(#[$attribute])*
100 $($vis)* fn $setter(&mut self, value: $from) {
101 use $crate::BitRange;
102 self.set_bit_range($msb, $lsb, $crate::Into::<$t>::into(value));
103 }
104 };
105 (@field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, _, $setter:ident: $bit:expr) => {
106 $(#[$attribute])*
107 $($vis)* fn $setter(&mut self, value: bool) {
108 use $crate::Bit;
109 self.set_bit($bit, value);
110 }
111 };
112 (@field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, $getter:ident, _: $msb:expr,
113 $lsb:expr, $count:expr) => {
114 $(#[$attribute])*
115 #[allow(unknown_lints)]
116 #[allow(eq_op)]
117 $($vis)* fn $getter(&self, index: usize) -> $into {
118 use $crate::BitRange;
119 __bitfield_debug_assert!(index < $count);
120 let width = $msb - $lsb + 1;
121 let lsb = $lsb + index*width;
122 let msb = lsb + width - 1;
123 let raw_value: $t = self.bit_range(msb, lsb);
124 $crate::Into::into(raw_value)
125 }
126 };
127 (@field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, $getter:ident, _: $msb:expr,
128 $lsb:expr) => {
129 $(#[$attribute])*
130 $($vis)* fn $getter(&self) -> $into {
131 use $crate::BitRange;
132 let raw_value: $t = self.bit_range($msb, $lsb);
133 $crate::Into::into(raw_value)
134 }
135 };
136 (@field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, $getter:ident, _: $bit:expr) => {
137 $(#[$attribute])*
138 $($vis)* fn $getter(&self) -> bool {
139 use $crate::Bit;
140 self.bit($bit)
141 }
142 };
143 (@field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, $getter:ident, $setter:ident:
144 $($exprs:expr),*) => {
145 bitfield_fields!(@field $(#[$attribute])* ($($vis)*) $t, $from, $into, $getter, _: $($exprs),*);
146 bitfield_fields!(@field $(#[$attribute])* ($($vis)*) $t, $from, $into, _, $setter: $($exprs),*);
147 };
148
149 ($t:ty;) => {};
150 ($default_ty:ty; pub $($rest:tt)*) => {
151 bitfield_fields!{$default_ty; () pub $($rest)*}
152 };
153 ($default_ty:ty; #[$attribute:meta] $($rest:tt)*) => {
154 bitfield_fields!{$default_ty; (#[$attribute]) $($rest)*}
155 };
156 ($default_ty:ty; ($(#[$attributes:meta])*) #[$attribute:meta] $($rest:tt)*) => {
157 bitfield_fields!{$default_ty; ($(#[$attributes])* #[$attribute]) $($rest)*}
158 };
159 ($default_ty:ty; ($(#[$attribute:meta])*) pub $t:ty, from into $into:ty, $getter:tt, $setter:tt:
160 $($exprs:expr),*; $($rest:tt)*) => {
161 bitfield_fields!{@field $(#[$attribute])* (pub) $t, $into, $into, $getter, $setter: $($exprs),*}
162 bitfield_fields!{$default_ty; $($rest)*}
163 };
164 ($default_ty:ty; ($(#[$attribute:meta])*) pub $t:ty, into $into:ty, $getter:tt, $setter:tt:
165 $($exprs:expr),*; $($rest:tt)*) => {
166 bitfield_fields!{@field $(#[$attribute])* (pub) $t, $t, $into, $getter, $setter: $($exprs),*}
167 bitfield_fields!{$default_ty; $($rest)*}
168 };
169 ($default_ty:ty; ($(#[$attribute:meta])*) pub $t:ty, $getter:tt, $setter:tt: $($exprs:expr),*;
170 $($rest:tt)*) => {
171 bitfield_fields!{@field $(#[$attribute])* (pub) $t, $t, $t, $getter, $setter: $($exprs),*}
172 bitfield_fields!{$default_ty; $($rest)*}
173 };
174 ($default_ty:ty; ($(#[$attribute:meta])*) pub from into $into:ty, $getter:tt, $setter:tt:
175 $($exprs:expr),*; $($rest:tt)*) => {
176 bitfield_fields!{@field $(#[$attribute])* (pub) $default_ty, $into, $into, $getter, $setter:
177 $($exprs),*}
178 bitfield_fields!{$default_ty; $($rest)*}
179 };
180 ($default_ty:ty; ($(#[$attribute:meta])*) pub into $into:ty, $getter:tt, $setter:tt:
181 $($exprs:expr),*; $($rest:tt)*) => {
182 bitfield_fields!{@field $(#[$attribute])* (pub) $default_ty, $default_ty, $into, $getter, $setter:
183 $($exprs),*}
184 bitfield_fields!{$default_ty; $($rest)*}
185 };
186 ($default_ty:ty; ($(#[$attribute:meta])*) pub $getter:tt, $setter:tt: $($exprs:expr),*;
187 $($rest:tt)*) => {
188 bitfield_fields!{@field $(#[$attribute])* (pub) $default_ty, $default_ty, $default_ty, $getter, $setter:
189 $($exprs),*}
190 bitfield_fields!{$default_ty; $($rest)*}
191 };
192
193 ($default_ty:ty; ($(#[$attribute:meta])*) $t:ty, from into $into:ty, $getter:tt, $setter:tt:
194 $($exprs:expr),*; $($rest:tt)*) => {
195 bitfield_fields!{@field $(#[$attribute])* () $t, $into, $into, $getter, $setter: $($exprs),*}
196 bitfield_fields!{$default_ty; $($rest)*}
197 };
198
199 ($default_ty:ty; ($(#[$attribute:meta])*) $t:ty, into $into:ty, $getter:tt, $setter:tt:
200 $($exprs:expr),*; $($rest:tt)*) => {
201 bitfield_fields!{@field $(#[$attribute])* () $t, $t, $into, $getter, $setter: $($exprs),*}
202 bitfield_fields!{$default_ty; $($rest)*}
203 };
204
205 ($default_ty:ty; ($(#[$attribute:meta])*) $t:ty, $getter:tt, $setter:tt: $($exprs:expr),*;
206 $($rest:tt)*) => {
207 bitfield_fields!{@field $(#[$attribute])* () $t, $t, $t, $getter, $setter: $($exprs),*}
208 bitfield_fields!{$default_ty; $($rest)*}
209 };
210 ($default_ty:ty; ($(#[$attribute:meta])*) from into $into:ty, $getter:tt, $setter:tt:
211 $($exprs:expr),*; $($rest:tt)*) => {
212 bitfield_fields!{@field $(#[$attribute])* () $default_ty, $into, $into, $getter, $setter:
213 $($exprs),*}
214 bitfield_fields!{$default_ty; $($rest)*}
215 };
216 ($default_ty:ty; ($(#[$attribute:meta])*) into $into:ty, $getter:tt, $setter:tt:
217 $($exprs:expr),*; $($rest:tt)*) => {
218 bitfield_fields!{@field $(#[$attribute])* () $default_ty, $default_ty, $into, $getter, $setter:
219 $($exprs),*}
220 bitfield_fields!{$default_ty; $($rest)*}
221 };
222 ($default_ty:ty; ($(#[$attribute:meta])*) $getter:tt, $setter:tt: $($exprs:expr),*;
223 $($rest:tt)*) => {
224 bitfield_fields!{@field $(#[$attribute])* () $default_ty, $default_ty, $default_ty, $getter, $setter:
225 $($exprs),*}
226 bitfield_fields!{$default_ty; $($rest)*}
227 };
228 ($previous_default_ty:ty; $default_ty:ty; $($rest:tt)*) => {
229 bitfield_fields!{$default_ty; $($rest)*}
230 };
231 ($default_ty:ty; $($rest:tt)*) => {
232 bitfield_fields!{$default_ty; () $($rest)*}
233 };
234 ($($rest:tt)*) => {
235 bitfield_fields!{SET_A_DEFAULT_TYPE_OR_SPECIFY_THE_TYPE_FOR_EACH_FIELDS; $($rest)*}
236 }
237}
238
239#[macro_export(local_inner_macros)]
278macro_rules! bitfield_debug {
279 (struct $name:ident; $($rest:tt)*) => {
280 fn fmt(&self, f: &mut $crate::fmt::Formatter) -> $crate::fmt::Result {
281 let mut debug_struct = f.debug_struct(__bitfield_stringify!($name));
282 debug_struct.field(".0", &self.0);
283 bitfield_debug!{debug_struct, self, $($rest)*}
284 debug_struct.finish()
285 }
286 };
287 ($debug_struct:ident, $self:ident, #[$attribute:meta] $($rest:tt)*) => {
288 bitfield_debug!{$debug_struct, $self, $($rest)*}
289 };
290 ($debug_struct:ident, $self:ident, pub $($rest:tt)*) => {
291 bitfield_debug!{$debug_struct, $self, $($rest)*}
292 };
293 ($debug_struct:ident, $self:ident, _, $setter:tt: $($exprs:expr),*; $($rest:tt)*) => {
294 bitfield_debug!{$debug_struct, $self, $($rest)*}
295 };
296 ($debug_struct:ident, $self:ident, $type:ty; $($rest:tt)*) => {
297 bitfield_debug!{$debug_struct, $self, $($rest)*}
298 };
299 ($debug_struct:ident, $self:ident, $getter:ident, $setter:tt: $msb:expr, $lsb:expr, $count:expr;
300 $($rest:tt)*) => {
301 let mut array = [$self.$getter(0); $count];
302 for (i, e) in (&mut array).into_iter().enumerate() {
303 *e = $self.$getter(i);
304 }
305 $debug_struct.field(__bitfield_stringify!($getter), &array);
306 bitfield_debug!{$debug_struct, $self, $($rest)*}
307 };
308 ($debug_struct:ident, $self:ident, $getter:ident, $setter:tt: $($exprs:expr),*; $($rest:tt)*)
309 => {
310 $debug_struct.field(__bitfield_stringify!($getter), &$self.$getter());
311 bitfield_debug!{$debug_struct, $self, $($rest)*}
312 };
313 ($debug_struct:ident, $self:ident, from into $into:ty, $($rest:tt)*) => {
314 bitfield_debug!{$debug_struct, $self, $($rest)*}
315 };
316 ($debug_struct:ident, $self:ident, into $into:ty, $($rest:tt)*) => {
317 bitfield_debug!{$debug_struct, $self, $($rest)*}
318 };
319 ($debug_struct:ident, $self:ident, $type:ty, $($rest:tt)*) => {
320 bitfield_debug!{$debug_struct, $self, $($rest)*}
321 };
322 ($debug_struct:ident, $self:ident, ) => {};
323}
324
325#[macro_export(local_inner_macros)]
357macro_rules! bitfield_bitrange {
358 (@impl_bitrange_slice $name:ident, $slice_ty:ty, $bitrange_ty:ty) => {
359 impl<T: AsMut<[$slice_ty]> + AsRef<[$slice_ty]>> $crate::BitRange<$bitrange_ty>
360 for $name<T> {
361 fn bit_range(&self, msb: usize, lsb: usize) -> $bitrange_ty {
362 let bit_len = $crate::size_of::<$slice_ty>()*8;
363 let value_bit_len = $crate::size_of::<$bitrange_ty>()*8;
364 let mut value = 0;
365 for i in (lsb..=msb).rev() {
366 value <<= 1;
367 value |= ((self.0.as_ref()[i/bit_len] >> (i%bit_len)) & 1) as $bitrange_ty;
368 }
369 value << (value_bit_len - (msb - lsb + 1)) >> (value_bit_len - (msb - lsb + 1))
370 }
371
372 fn set_bit_range(&mut self, msb: usize, lsb: usize, value: $bitrange_ty) {
373 let bit_len = $crate::size_of::<$slice_ty>()*8;
374 let mut value = value;
375 for i in lsb..=msb {
376 self.0.as_mut()[i/bit_len] &= !(1 << (i%bit_len));
377 self.0.as_mut()[i/bit_len] |= (value & 1) as $slice_ty << (i%bit_len);
378 value >>= 1;
379 }
380 }
381 }
382 };
383 (@impl_bitrange_slice_msb0 $name:ident, $slice_ty:ty, $bitrange_ty:ty) => {
384 impl<T: AsMut<[$slice_ty]> + AsRef<[$slice_ty]>> $crate::BitRange<$bitrange_ty>
385 for $name<T> {
386 fn bit_range(&self, msb: usize, lsb: usize) -> $bitrange_ty {
387 let bit_len = $crate::size_of::<$slice_ty>()*8;
388 let value_bit_len = $crate::size_of::<$bitrange_ty>()*8;
389 let mut value = 0;
390 for i in lsb..=msb {
391 value <<= 1;
392 value |= ((self.0.as_ref()[i/bit_len] >> (bit_len - i%bit_len - 1)) & 1)
393 as $bitrange_ty;
394 }
395 value << (value_bit_len - (msb - lsb + 1)) >> (value_bit_len - (msb - lsb + 1))
396 }
397
398 fn set_bit_range(&mut self, msb: usize, lsb: usize, value: $bitrange_ty) {
399 let bit_len = $crate::size_of::<$slice_ty>()*8;
400 let mut value = value;
401 for i in (lsb..=msb).rev() {
402 self.0.as_mut()[i/bit_len] &= !(1 << (bit_len - i%bit_len - 1));
403 self.0.as_mut()[i/bit_len] |= (value & 1) as $slice_ty
404 << (bit_len - i%bit_len - 1);
405 value >>= 1;
406 }
407 }
408 }
409 };
410 (struct $name:ident([$t:ty])) => {
411 bitfield_bitrange!(@impl_bitrange_slice $name, $t, u8);
412 bitfield_bitrange!(@impl_bitrange_slice $name, $t, u16);
413 bitfield_bitrange!(@impl_bitrange_slice $name, $t, u32);
414 bitfield_bitrange!(@impl_bitrange_slice $name, $t, u64);
415 bitfield_bitrange!(@impl_bitrange_slice $name, $t, u128);
416 bitfield_bitrange!(@impl_bitrange_slice $name, $t, i8);
417 bitfield_bitrange!(@impl_bitrange_slice $name, $t, i16);
418 bitfield_bitrange!(@impl_bitrange_slice $name, $t, i32);
419 bitfield_bitrange!(@impl_bitrange_slice $name, $t, i64);
420 bitfield_bitrange!(@impl_bitrange_slice $name, $t, i128);
421 };
422 (struct $name:ident(MSB0 [$t:ty])) => {
423 bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, u8);
424 bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, u16);
425 bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, u32);
426 bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, u64);
427 bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, u128);
428 bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, i8);
429 bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, i16);
430 bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, i32);
431 bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, i64);
432 bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, i128);
433 };
434 (struct $name:ident($t:ty)) => {
435 impl<T> $crate::BitRange<T> for $name where $t: $crate::BitRange<T> {
436 fn bit_range(&self, msb: usize, lsb: usize) -> T {
437 self.0.bit_range(msb, lsb)
438 }
439 fn set_bit_range(&mut self, msb: usize, lsb: usize, value: T) {
440 self.0.set_bit_range(msb, lsb, value);
441 }
442 }
443 };
444}
445
446#[macro_export(local_inner_macros)]
503macro_rules! bitfield {
504 ($(#[$attribute:meta])* pub struct $($rest:tt)*) => {
505 bitfield!($(#[$attribute])* (pub) struct $($rest)*);
506 };
507 ($(#[$attribute:meta])* struct $($rest:tt)*) => {
508 bitfield!($(#[$attribute])* () struct $($rest)*);
509 };
510 ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($($type:tt)*); impl Debug; no default BitRange; $($rest:tt)*) => {
513 bitfield!{$(#[$attribute])* ($($vis)*) struct $name($($type)*); no default BitRange; impl Debug; $($rest)*}
514 };
515
516 ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident([$t:ty]); no default BitRange; impl Debug; $($rest:tt)*) => {
519 impl<T: AsMut<[$t]> + AsRef<[$t]> + $crate::fmt::Debug> $crate::fmt::Debug for $name<T> {
520 bitfield_debug!{struct $name; $($rest)*}
521 }
522
523 bitfield!{$(#[$attribute])* ($($vis)*) struct $name([$t]); no default BitRange; $($rest)*}
524 };
525 ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident([$t:ty]); no default BitRange; $($rest:tt)*) => {
526 $(#[$attribute])*
527 $($vis)* struct $name<T>(pub T);
528
529 impl<T: AsMut<[$t]> + AsRef<[$t]>> $name<T> {
530 bitfield_fields!{$($rest)*}
531 }
532 };
533 ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident([$t:ty]); $($rest:tt)*) => {
534 bitfield_bitrange!(struct $name([$t]));
535 bitfield!{$(#[$attribute])* ($($vis)*) struct $name([$t]); no default BitRange; $($rest)*}
536 };
537
538 ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident(MSB0 [$t:ty]); no default BitRange; $($rest:tt)*) => {
541 bitfield!{$(#[$attribute])* ($($vis)*) struct $name([$t]); no default BitRange; $($rest)*}
542 };
543 ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident(MSB0 [$t:ty]); $($rest:tt)*) => {
544 bitfield_bitrange!(struct $name(MSB0 [$t]));
545 bitfield!{$(#[$attribute])* ($($vis)*) struct $name([$t]); no default BitRange; $($rest)*}
546 };
547
548 ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($t:ty); no default BitRange; impl Debug; $($rest:tt)*) => {
549 impl $crate::fmt::Debug for $name {
550 bitfield_debug!{struct $name; $($rest)*}
551 }
552
553 bitfield!{$(#[$attribute])* ($($vis)*) struct $name($t); no default BitRange; $($rest)*}
554 };
555 ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($t:ty); no default BitRange; $($rest:tt)*) => {
556 $(#[$attribute])*
557 $($vis)* struct $name(pub $t);
558
559 impl $name {
560 bitfield_fields!{$t; $($rest)*}
561 }
562 };
563 ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($t:ty); $($rest:tt)*) => {
564 bitfield_bitrange!(struct $name($t));
565 bitfield!{$(#[$attribute])* ($($vis)*) struct $name($t); no default BitRange; $($rest)*}
566 };
567}
568
569#[doc(hidden)]
570pub use core::convert::Into;
571#[doc(hidden)]
572pub use core::fmt;
573#[doc(hidden)]
574pub use core::mem::size_of;
575
576pub trait BitRange<T> {
578 fn bit_range(&self, msb: usize, lsb: usize) -> T;
580 fn set_bit_range(&mut self, msb: usize, lsb: usize, value: T);
582}
583
584pub trait Bit {
588 fn bit(&self, bit: usize) -> bool;
590
591 fn set_bit(&mut self, bit: usize, value: bool);
593}
594
595impl<T: BitRange<u8>> Bit for T {
596 fn bit(&self, bit: usize) -> bool {
597 self.bit_range(bit, bit) != 0
598 }
599 fn set_bit(&mut self, bit: usize, value: bool) {
600 self.set_bit_range(bit, bit, value as u8);
601 }
602}
603
604macro_rules! impl_bitrange_for_u {
605 ($t:ty, $bitrange_ty:ty) => {
606 impl BitRange<$bitrange_ty> for $t {
607 #[inline]
608 #[allow(unknown_lints)]
609 #[allow(cast_lossless)]
610 fn bit_range(&self, msb: usize, lsb: usize) -> $bitrange_ty {
611 let bit_len = size_of::<$t>()*8;
612 let result_bit_len = size_of::<$bitrange_ty>()*8;
613 let result = ((*self << (bit_len - msb - 1)) >> (bit_len - msb - 1 + lsb))
614 as $bitrange_ty;
615 result << (result_bit_len - (msb - lsb + 1)) >> (result_bit_len - (msb - lsb + 1))
616 }
617
618 #[inline]
619 #[allow(unknown_lints)]
620 #[allow(cast_lossless)]
621 fn set_bit_range(&mut self, msb: usize, lsb: usize, value: $bitrange_ty) {
622 let bit_len = size_of::<$t>()*8;
623 let mask: $t = !(0 as $t)
624 << (bit_len - msb - 1)
625 >> (bit_len - msb - 1 + lsb)
626 << (lsb);
627 *self &= !mask;
628 *self |= (value as $t << lsb) & mask;
629 }
630 }
631 }
632}
633
634macro_rules! impl_bitrange_for_u_combinations {
635((),($($bitrange_ty:ty),*)) => {
636
637};
638(($t:ty),($($bitrange_ty:ty),*)) => {
639 $(impl_bitrange_for_u!{$t, $bitrange_ty})*
640};
641 (($t_head:ty, $($t_rest:ty),*),($($bitrange_ty:ty),*)) => {
642 impl_bitrange_for_u_combinations!{($t_head), ($($bitrange_ty),*)}
643 impl_bitrange_for_u_combinations!{($($t_rest),*), ($($bitrange_ty),*)}
644 };
645}
646
647impl_bitrange_for_u_combinations! {(u8, u16, u32, u64, u128), (u8, u16, u32, u64, u128)}
648impl_bitrange_for_u_combinations! {(u8, u16, u32, u64, u128), (i8, i16, i32, i64, i128)}
649
650#[macro_export]
653#[doc(hidden)]
654macro_rules! __bitfield_stringify {
655 ($s:ident) => {
656 stringify!($s)
657 };
658}
659
660#[macro_export]
663#[doc(hidden)]
664macro_rules! __bitfield_debug_assert {
665 ($e:expr) => {
666 debug_assert!($e)
667 };
668}