type_const/
impls.rs

1use crate::{Const, DefaultConst};
2
3macro_rules! tuple_doc {
4    ($count:literal $T:ident; $item:item) => {
5        // #[cfg_attr(docsrs, doc(fake_variadic))]
6        // #[cfg_attr(docsrs, doc = ::core::concat!("This trait is implemented for tuples up to ", $count, " items long."))]
7        $item
8    };
9    ($count:literal $_:ident $($T:ident)+; $item:item) => {
10        // #[cfg_attr(docsrs, doc(hidden))]
11        $item
12    };
13}
14macro_rules! impl_tuple {
15    ($count:literal $_:ident) => {};
16    ($count:literal $_:ident $($T:ident)+) => {
17        impl_tuple! { $count $($T)* }
18        tuple_doc! {
19            $count $($T)*;
20            /// Tuples of [`Const`](crate::Const) evaluate to a tuple of the values
21            impl<$($T: $crate::Const),*> $crate::Const for ($($T,)*) {
22                type Type = ($($T::Type,)*);
23                const VALUE: Self::Type = ($($T::VALUE,)*);
24            }
25        }
26        impl<$($T: $crate::DefaultConst),*> $crate::DefaultConst for ($($T,)*) {
27            const DEFAULT: Self = ($($T::DEFAULT,)*);
28        }
29    };
30}
31impl_tuple! {
32    12
33    __
34    A B C
35    D E F
36    G H I
37    J K L
38}
39impl Const for () {
40    type Type = Self;
41    const VALUE: Self::Type = ();
42}
43impl DefaultConst for () {
44    const DEFAULT: Self = ();
45}
46
47/// `[Const; N]` evaluates to `[VALUE; N]`
48impl<C: Const, const N: usize> Const for [C; N] {
49    type Type = [C::Type; N];
50    const VALUE: Self::Type = [C::VALUE; N];
51}
52
53/// ```rust_analyzer_brace_hint
54/// defaults! {}
55/// ```
56macro_rules! defaults {
57    (
58        {$($generics:tt)*}
59        $(#[$meta:meta])*
60        $Self:ty = $default:expr $(;)?
61    ) => {
62        $(#[$meta])*
63        impl<$($generics)*> $crate::DefaultConst for $Self {
64            const DEFAULT: Self = $default;
65        }
66    };
67    (
68        $generics:tt
69        $(
70            $(#[$meta:meta])*
71            $Self:ty = $default:expr
72        );* $(;)?
73    ) => {
74        $(defaults! { $generics $(#[$meta])* $Self = $default })*
75    };
76}
77defaults! {
78    {T: DefaultConst, const N: usize}
79    [T; N] = [T::DEFAULT; N]
80}
81defaults! {
82    {T: DefaultConst}
83    core::mem::ManuallyDrop<T> = Self::new(T::DEFAULT);
84    core::cmp::Reverse<T> = Self(T::DEFAULT);
85    core::num::Saturating<T> = Self(T::DEFAULT);
86    core::num::Wrapping<T> = Self(T::DEFAULT);
87    core::panic::AssertUnwindSafe<T> = Self(T::DEFAULT);
88}
89defaults! {
90    {T}
91    Option<T> = None;
92    &[T] = &[];
93}
94defaults! {
95    {T: ?Sized}
96    core::marker::PhantomData<T> = Self
97}
98defaults! {
99    {}
100    &str = "";
101    &core::ffi::CStr = c"";
102    core::fmt::Error = Self;
103    core::ops::RangeFull = Self;
104    core::time::Duration = Self::ZERO;
105}
106
107macro_rules! nums {
108    ($($t:ty),* $(,)?) => {$(
109        defaults! {
110            {}
111            $t = 0 as _
112        }
113    )*};
114}
115nums! {
116    i8, i16, i32, i64, i128, isize,
117    u8, u16, u32, u64, u128, usize,
118    f32, f64,
119}