1use super::{Bit, Bits, SetBit, SetBits, WithBit, WithBits};
2
3macro_rules! impl_bits_for_int_type {
4 ($storage: ty, $value: ty $(, $const:tt)?) => {
5 impl $($const)* Bits<$value> for $storage {
6 #[inline]
7 fn bits<const START: usize, const END: usize>(&self) -> $value {
8 if START >= END {
9 return 0;
10 }
11 const VALUE_BITS: usize = <$value>::BITS as usize;
12 let read_bits = END - START;
13 ((*self >> START) as $value) << (VALUE_BITS - read_bits) >> (VALUE_BITS - read_bits)
14 }
15 }
16
17 impl $($const)* WithBits<$value> for $storage {
18 #[inline]
19 fn with_bits<const START: usize, const END: usize>(self, value: $value) -> Self {
20 if START >= END {
21 return self;
22 }
23 let written_bits = END - START;
24 let mask = ((1 as $storage) << (written_bits - 1) << 1).wrapping_sub(1) << START;
25 (self & !mask) | ((value as $storage) << START & mask)
26 }
27 }
28
29 impl $($const)* SetBits<$value> for $storage {
30 #[inline]
31 fn set_bits<const START: usize, const END: usize>(&mut self, value: $value) {
32 if START >= END {
33 return;
34 }
35 *self = self.with_bits::<START, END>(value);
36 }
37 }
38 };
39}
40
41macro_rules! impl_bits_for_int_types {
42 (const => $($dst_ty: ty),*) => {};
43 (=> $($dst_ty: ty),*) => {};
44 (const $src_ty: ty $(, $other_src_ty: ty)* => $($dst_ty: ty),*) => {
45 $(
46 impl_bits_for_int_type!($src_ty, $dst_ty, const);
47 )*
48 impl_bits_for_int_types!(const $($other_src_ty),* => $($dst_ty),*);
49 };
50 ($src_ty: ty $(, $other_src_ty: ty)* => $($dst_ty: ty),* $(; $other:tt)*) => {
51 $(
52 impl_bits_for_int_type!($src_ty, $dst_ty);
53 )*
54 impl_bits_for_int_types!($($other_src_ty),* => $($dst_ty),*);
55 };
56}
57
58#[cfg(not(feature = "nightly"))]
59impl_bits_for_int_types!(
60 u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize
61 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize; const
62);
63#[cfg(feature = "nightly")]
64impl_bits_for_int_types!(
65 const u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize
66 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize
67);
68
69macro_rules! impl_bit_for_int_type {
70 ($t: ty $(, $const:tt)?) => {
71 impl $($const)* Bit for $t {
72 #[inline]
73 fn bit<const BIT: usize>(&self) -> bool {
74 *self & 1 << BIT != 0
75 }
76 }
77
78 impl $($const)* WithBit for $t {
79 #[inline]
80 fn with_bit<const BIT: usize>(self, value: bool) -> Self {
81 (self & !(1 << BIT)) | (value as $t) << BIT
82 }
83 }
84
85 impl $($const)* SetBit for $t {
86 #[inline]
87 fn set_bit<const BIT: usize>(&mut self, value: bool) {
88 *self = self.with_bit::<BIT>(value);
89 }
90 }
91 };
92}
93
94macro_rules! impl_bit_for_int_types {
95 (const $($t: ty),*) => {
96 $(impl_bit_for_int_type!($t, const);)*
97 };
98 ($($t: ty),*) => {
99 $(impl_bit_for_int_type!($t);)*
100 };
101}
102
103#[cfg(not(feature = "nightly"))]
104impl_bit_for_int_types!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
105#[cfg(feature = "nightly")]
106impl_bit_for_int_types!(const u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);