proc_bitfield/traits/
int_impls.rs

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);