ruint/
const_for.rs

1/// Compile time for loops with a `const` variable for testing.
2///
3/// Repeats a block of code with different values assigned to a constant.
4///
5/// ```rust
6/// # use ruint::{const_for, nlimbs, Uint};
7/// const_for!(BITS in [0, 10, 100] {
8///     const LIMBS: usize = nlimbs(BITS);
9///     println!("{:?}", Uint::<BITS, LIMBS>::MAX);
10/// });
11/// ```
12///
13/// is equivalent to
14///
15/// ```rust
16/// # use ruint::{const_for, Uint};
17/// println!("{:?}", Uint::<0, 0>::MAX);
18/// println!("{:?}", Uint::<10, 1>::MAX);
19/// println!("{:?}", Uint::<100, 2>::MAX);
20/// ```
21///
22/// It comes with two built-in lists: `NON_ZERO` which is equivalent to
23///
24/// ```text
25/// [1, 2, 63, 64, 65, 127, 128, 129, 256, 384, 512, 4096]
26/// ```
27///
28/// and `SIZES` which is the same but also has `0` as a value.
29///
30/// In combination with [`proptest!`][proptest::proptest] this allows for
31/// testing over a large range of [`Uint`][crate::Uint] types and values:
32///
33/// ```rust
34/// # use proptest::prelude::*;
35/// # use ruint::{const_for, nlimbs, Uint};
36/// const_for!(BITS in SIZES {
37///    const LIMBS: usize = nlimbs(BITS);
38///    proptest!(|(value: Uint<BITS, LIMBS>)| {
39///         // ... test code
40///     });
41/// });
42/// ```
43#[macro_export]
44macro_rules! const_for {
45    ($C:ident in [ $( $n:literal ),* ] $x:block) => {
46        $({
47            const $C: usize = $n;
48            $x
49        })*
50    };
51    ($C:ident in SIZES $x:block) => {
52        $crate::const_for!($C in [0] $x);
53        $crate::const_for!($C in NON_ZERO $x);
54    };
55    ($C:ident in NON_ZERO $x:block) => {
56        $crate::const_for!($C in [1, 2, 63, 64, 65, 127, 128, 129, 256, 384, 512, 4096] $x);
57    };
58    ($C:ident in BENCH $x:block) => {
59        $crate::const_for!($C in [0, 64, 128, 192, 256, 384, 512, 4096] $x);
60    };
61    ($C:ident in $S:ident if ( $c:expr ) $x:block) => {
62        $crate::const_for!($C in $S {
63            if $c {
64                $x
65            }
66        });
67    };
68}