bitpiece/
check.rs

1#[macro_export]
2macro_rules! bitpiece_check_const_assert_bits_eq {
3    {$t: ty, $a: expr, $b: expr} => {
4        if !<$t as $crate::BitPiece>::Converter::const_eq($a, $b) {
5            panic!()
6        }
7    };
8}
9
10#[macro_export]
11macro_rules! bitpiece_check_gen_values_to_check {
12    ($t: ty, $supports_any_bit_pattern: literal) => {{
13        type Converter = <$t as $crate::BitPiece>::Converter;
14
15        const MAX_VAL: u64 = Converter::to_bits(<$t as $crate::BitPiece>::ONES) as u64;
16
17        const VALUES_TO_CHECK: &[$t] = if $supports_any_bit_pattern {
18            &[
19                <$t as $crate::BitPiece>::ZEROES,
20                <$t as $crate::BitPiece>::ONES,
21                <$t as $crate::BitPiece>::MIN,
22                <$t as $crate::BitPiece>::MAX,
23                Converter::from_bits(
24                    (0x31d6b601fb4faeb8u64 & MAX_VAL) as <$t as $crate::BitPiece>::Bits,
25                ),
26                Converter::from_bits(
27                    (0xe9bd79bf8ca99263u64 & MAX_VAL) as <$t as $crate::BitPiece>::Bits,
28                ),
29            ]
30        } else {
31            &[
32                <$t as $crate::BitPiece>::ZEROES,
33                <$t as $crate::BitPiece>::ONES,
34                <$t as $crate::BitPiece>::MIN,
35                <$t as $crate::BitPiece>::MAX,
36            ]
37        };
38        VALUES_TO_CHECK
39    }};
40}
41
42#[macro_export]
43macro_rules! bitpiece_check_do_for_each_value {
44    {$t: ty, $value_var_name: ident, $supports_any_bit_pattern: literal, $body: block} => {
45        let values_to_check = $crate::bitpiece_check_gen_values_to_check!{$t, $supports_any_bit_pattern};
46        // can't use qualified path for `const_for`, must instead import it, since the `const_for` macro calls itself
47        // in a non-hygiene way inside of its body.
48        use $crate::const_for;
49        const_for!(i in 0..values_to_check.len() => {
50            let $value_var_name = values_to_check[i];
51            $body
52        });
53    };
54}
55#[macro_export]
56macro_rules! bitpiece_check_base_impl {
57    {$t: ty, $supports_any_bit_pattern: literal} => {
58        const _: () = {
59            type Converter = <$t as $crate::BitPiece>::Converter;
60            $crate::bitpiece_check_do_for_each_value!($t, value, $supports_any_bit_pattern, {
61                $crate::bitpiece_check_const_assert_bits_eq!{
62                    $t,
63                    value,
64                    Converter::from_bits(Converter::to_bits(value))
65                };
66                $crate::bitpiece_check_const_assert_bits_eq!{
67                    $t,
68                    value,
69                    Converter::try_from_bits(Converter::to_bits(value)).unwrap()
70                };
71            });
72        };
73    };
74}
75
76#[macro_export]
77macro_rules! bitpiece_check_fields_impl {
78    {$t: ty, $supports_any_bit_pattern: literal} => {
79        const _: () = {
80            type Converter = <$t as $crate::BitPiece>::Converter;
81            $crate::bitpiece_check_do_for_each_value!($t, value, $supports_any_bit_pattern, {
82                $crate::bitpiece_check_const_assert_bits_eq!(
83                    $t,
84                    value,
85                    Converter::from_fields(Converter::to_fields(value))
86                );
87            });
88        };
89    };
90}
91
92#[macro_export]
93macro_rules! bitpiece_check_mut_impl {
94    {$t: ty, $supports_any_bit_pattern: literal} => {
95        const _: () = {
96            type Converter = <$t as $crate::BitPiece>::Converter;
97            type MutRefTy<'a> = <$t as $crate::BitPieceHasMutRef>::MutRef<'a>;
98            $crate::bitpiece_check_do_for_each_value!($t, value, $supports_any_bit_pattern, {
99                $crate::bitpiece_check_do_for_each_value!($t, value2, $supports_any_bit_pattern, {
100                    let mut storage = Converter::to_bits(value) as u64;
101                    let mut mut_ref = MutRefTy::new(BitPieceStorageMutRef::U64(&mut storage), 0);
102                    $crate::bitpiece_check_const_assert_bits_eq!(
103                        $t,
104                        value,
105                        mut_ref.get()
106                    );
107                    mut_ref.set(value2);
108                    $crate::bitpiece_check_const_assert_bits_eq!(
109                        $t,
110                        value2,
111                        mut_ref.get()
112                    );
113                });
114            });
115        };
116    };
117}
118
119#[macro_export]
120macro_rules! bitpiece_check_full_impl {
121    {$t: ty, $supports_any_bit_pattern: literal} => {
122        #[cfg(test)]
123        const _: () = {
124            bitpiece_check_base_impl! { $t, $supports_any_bit_pattern }
125            bitpiece_check_fields_impl! { $t, $supports_any_bit_pattern }
126            bitpiece_check_mut_impl! { $t, $supports_any_bit_pattern }
127        };
128    };
129}