crypto_bigint/
macros.rs

1//! Macro definitions which are a part of the public API.
2
3/// Internal implementation detail of [`const_assert_eq`] and [`const_assert_ne`].
4#[doc(hidden)]
5#[macro_export]
6macro_rules! const_assert_n {
7    ($n:expr, $($arg:tt)*) => {{
8        // TODO(tarcieri): gensym a name so it's unique per invocation of the macro?
9        mod __const_assert {
10            pub(super) struct Assert<const N: usize>;
11
12            impl<const N: usize> Assert<N> {
13                pub(super) const ASSERT: () = assert!($($arg)*);
14            }
15        }
16
17        __const_assert::Assert::<$n>::ASSERT
18    }};
19}
20
21/// Const-friendly assertion that two values are equal.
22///
23/// ```
24/// const _: () = crypto_bigint::const_assert_eq!(0, 0, "zero equals zero");
25/// ```
26#[macro_export]
27macro_rules! const_assert_eq {
28    ($left:expr, $right:expr $(,)?) => (
29        $crate::const_assert_n!($left, $left == $right)
30    );
31    ($left:expr, $right:expr, $($arg:tt)+) => (
32        $crate::const_assert_n!($left, $left == $right, $($arg)+)
33    );
34}
35
36/// Const-friendly assertion that two values are NOT equal.
37///
38/// ```
39/// const _: () = crypto_bigint::const_assert_ne!(0, 1, "zero is NOT equal to one");
40/// ```
41#[macro_export]
42macro_rules! const_assert_ne {
43    ($left:expr, $right:expr $(,)?) => (
44        $crate::const_assert_n!($left, $left != $right)
45    );
46    ($left:expr, $right:expr, $($arg:tt)+) => (
47        $crate::const_assert_n!($left, $left != $right, $($arg)+)
48    );
49}
50
51/// Calculate the number of limbs required to represent the given number of bits.
52// TODO(tarcieri): replace with `generic_const_exprs` (rust-lang/rust#76560) when stable
53#[macro_export]
54macro_rules! nlimbs {
55    ($bits:expr) => {
56        $bits / $crate::Limb::BITS
57    };
58}
59
60#[cfg(test)]
61mod tests {
62    #[cfg(target_pointer_width = "32")]
63    #[test]
64    fn nlimbs_for_bits_macro() {
65        assert_eq!(nlimbs!(64), 2);
66        assert_eq!(nlimbs!(128), 4);
67        assert_eq!(nlimbs!(192), 6);
68        assert_eq!(nlimbs!(256), 8);
69    }
70
71    #[cfg(target_pointer_width = "64")]
72    #[test]
73    fn nlimbs_for_bits_macro() {
74        assert_eq!(nlimbs!(64), 1);
75        assert_eq!(nlimbs!(128), 2);
76        assert_eq!(nlimbs!(192), 3);
77        assert_eq!(nlimbs!(256), 4);
78    }
79}