1use crate::*;
2
3macro_rules! sb_type_impl_from_int_type {
4 { $sb_type_ident: ident, $sb_type_storage_signed: ty, $uint_type: ty } => {
5 impl From<$uint_type> for $sb_type_ident {
6 fn from(x: $uint_type) -> Self {
7 Self::new(x as $sb_type_storage_signed)
8 }
9 }
10 }
11}
12
13macro_rules! sb_type_impl_from_int_types {
14 { $sb_type_ident: ident, $sb_type_storage_signed: ty } => {
15 sb_type_impl_from_int_type! { $sb_type_ident, $sb_type_storage_signed, u8 }
16 sb_type_impl_from_int_type! { $sb_type_ident, $sb_type_storage_signed, u16 }
17 sb_type_impl_from_int_type! { $sb_type_ident, $sb_type_storage_signed, u32 }
18 sb_type_impl_from_int_type! { $sb_type_ident, $sb_type_storage_signed, u64 }
19 sb_type_impl_from_int_type! { $sb_type_ident, $sb_type_storage_signed, i8 }
20 sb_type_impl_from_int_type! { $sb_type_ident, $sb_type_storage_signed, i16 }
21 sb_type_impl_from_int_type! { $sb_type_ident, $sb_type_storage_signed, i32 }
22 sb_type_impl_from_int_type! { $sb_type_ident, $sb_type_storage_signed, i64 }
23 }
24}
25
26macro_rules! define_sb_type {
27 { $bit_len: literal, $ident: ident, $storage: ty, $storage_signed: ty, $mut_ref_ty_name: ident } => {
28 #[derive(Clone, Copy, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
30 pub struct $ident($storage_signed);
31 impl BitPiece for $ident {
32 const BITS: usize = $bit_len;
33 const ZEROES: Self = Self(0);
34 const ONES: Self = Self::from_bits(Self::STORAGE_MASK);
35 const MIN: Self = Self(((1 as $storage) << ($bit_len - 1)).wrapping_neg() as $storage_signed);
36 const MAX: Self = Self(((1 as $storage) << ($bit_len - 1)).wrapping_sub(1) as $storage_signed);
37 type Bits = $storage;
38 type Converter = Self;
39 fn try_from_bits(bits: Self::Bits) -> Option<Self> {
40 <Self as BitPiece>::Converter::try_from_bits(bits)
41 }
42 fn from_bits(bits: Self::Bits) -> Self {
43 <Self as BitPiece>::Converter::from_bits(bits)
44 }
45 fn to_bits(self) -> Self::Bits {
46 <Self as BitPiece>::Converter::to_bits(self)
47 }
48 }
49
50 sb_type_impl_from_int_types! { $ident, $storage_signed }
51
52 impl BitPieceHasFields for $ident {
53 type Fields = Self;
54 fn from_fields(fields: Self::Fields) -> Self {
55 <Self as BitPiece>::Converter::from_fields(fields)
56 }
57 fn to_fields(self) -> Self::Fields {
58 <Self as BitPiece>::Converter::to_fields(self)
59 }
60 }
61
62 impl BitPieceHasMutRef for $ident {
63 type MutRef<'s> = $mut_ref_ty_name<'s>;
64 }
65
66 impl $ident {
67 pub const fn from_fields(fields: Self) -> Self {
68 fields
69 }
70 pub const fn to_fields(x: Self) -> Self {
71 x
72 }
73 pub const fn try_from_bits(bits: $storage) -> Option<Self> {
74 let sign_bit = (bits >> ($bit_len - 1)) & 1;
76
77 let sign_extended = if sign_bit != 0 {
79 bits | (!Self::STORAGE_MASK)
81 } else {
82 bits
83 };
84 Self::try_new(sign_extended as $storage_signed)
85 }
86 pub const fn from_bits(bits: $storage) -> Self {
87 Self::try_from_bits(bits).unwrap()
88 }
89 pub const fn to_bits(self) -> $storage {
90 (self.0 as $storage) & Self::STORAGE_MASK
91 }
92 pub const fn const_eq(a: Self, b: Self) -> bool {
93 a.0 == b.0
94 }
95 }
96 impl $ident {
97 const STORAGE_MASK: $storage = (
99 if $bit_len == <$storage>::BITS {
100 <$storage>::MAX
104 } else {
105 ((1 as $storage) << $bit_len).wrapping_sub(1)
106 }
107 );
108
109 pub const fn new(value: $storage_signed) -> Self {
113 Self::try_new(value).unwrap()
114 }
115
116 pub const fn try_new(value: $storage_signed) -> Option<Self> {
120 if value <= Self::MAX.0 && value >= Self::MIN.0 {
121 Some(Self(value))
122 } else {
123 None
124 }
125 }
126
127 pub const unsafe fn new_unchecked(value: $storage_signed) -> Self {
133 Self(value)
134 }
135
136 pub const fn get(&self) -> $storage_signed {
138 self.0
139 }
140 }
141 impl core::fmt::Display for $ident {
142 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
143 core::fmt::Display::fmt(&self.0, f)
144 }
145 }
146 impl core::fmt::Debug for $ident {
147 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
148 core::fmt::Debug::fmt(&self.0, f)
149 }
150 }
151 bitpiece_check_full_impl! { $ident, true }
152 bitpiece_define_mut_ref_type! { $ident, $mut_ref_ty_name, pub }
153 };
154}
155macro_rules! define_sb_types {
156 { $($bit_len: literal),+ $(,)? } => {
157 $(
158 paste!{
159 define_sb_type! {
160 $bit_len,
161 [<SB $bit_len>],
162 <BitLength<$bit_len> as AssociatedStorage>::Storage,
163 <<BitLength<$bit_len> as AssociatedStorage>::Storage as BitStorage>::Signed,
164 [<SB $bit_len MutRef>]
165 }
166 }
167 )+
168 };
169}
170define_sb_types! {
171 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
172 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
173}