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
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#[cfg(feature = "cloneable-secret")]
macro_rules! impl_cloneable_secret_for_numbers {
    ($($t:ty),*) => {
        $(
            impl $crate::traits::CloneableSecret for $t {}
        )*
    };
}

#[cfg(feature = "cloneable-secret")]
pub(crate) use impl_cloneable_secret_for_numbers;

#[cfg(feature = "debug-secret")]
macro_rules! impl_debug_secret_for_numbers {
    ($($t:ty),*) => {
        $(
            impl $crate::traits::DebugSecret for $t {}
        )*
    };
}

#[cfg(feature = "debug-secret")]
pub(crate) use impl_debug_secret_for_numbers;

macro_rules! impl_sealed_trait_for_uint {
    ($($t:ty),*) => {
        $(
            impl $crate::traits::__private::SealedTrait for $t {}
        )*
    };
}
pub(crate) use impl_sealed_trait_for_uint;

macro_rules! impl_choose_int {
    // Entry point
    ($($arg:ident => $out:ty;)*) => {
        impl_choose_int! {
            @prev_args ();
            @prev_num $crate::prelude::typenum::UTerm;
            @rest_args ($($arg,)*);
            @rest_out ($($out;)*);
        }
    };

    // Implement one
    (
        @prev_args ($($prev_args:ident,)*);
        @prev_num $prev_num:ty;
        @rest_args ($arg:ident, $($rest_args:ident,)*);
        @rest_out ($out:ty; $($rest_out:ty;)*);
    )
    => {
        impl<$($prev_args,)* $arg> $crate::traits::__private::SealedTrait for $crate::prelude::typenum::uint::UInt<$prev_num, $arg> {}

        impl<$($prev_args,)* $arg> $crate::traits::ChooseMinimallyRepresentableUInt for $crate::prelude::typenum::uint::UInt<$prev_num, $arg> {
            type Output = $out;
            type AtomicOutput = <$out as $crate::traits::AsAtomic>::Output;
            const ZERO: Self::Output = Self::Output::MIN;
            const ONE: Self::Output = 1;

            fn cast_unsigned_to_self_type<T: $crate::prelude::typenum::uint::Unsigned>(_: $crate::traits::__private::SealedToken) -> Self::Output {
                <T as $crate::prelude::typenum::uint::Unsigned>::USIZE as Self::Output
            }
        }

        impl_choose_int!{
            @prev_args ($($prev_args,)* $arg,);
            @prev_num $crate::prelude::typenum::uint::UInt<$prev_num, $arg>;
            @rest_args ($($rest_args,)*);
            @rest_out ($($rest_out;)*);
        }
    };

    // Base case; stop iteration
    (
        @prev_args ($($prev_args:ident,)*);
        @prev_num $prev_num:ty;
        @rest_args ();
        @rest_out ();
    ) => {};
}

pub(crate) use impl_choose_int;