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
84
85
86
87
88
/// For types that represent constants.
/// 
/// # Examples
/// 
/// ### Quasiconstants
/// 
/// Using the [`quasiconst`] macro to declare types that implement this trait,
/// and emulate generic constants.
/// 
/// This example requires Rust 1.46.0, because it uses a while loop in a const context.
/// 
#[cfg_attr(not(feature = "rust_1_46"), doc = " ```ignore")]
#[cfg_attr(feature = "rust_1_46", doc = " ```rust")]
/// use core_extensions::{ConstVal, getconst, quasiconst};
/// 
/// const LEN: usize = 8;
///
/// quasiconst!{
///     const FIBNUMS[T: ConstVal<Ty = u128>]: &'static [u128; LEN] = {
///         let mut ret = [T::VAL; LEN];
///         let mut i = 2;
///         while i < LEN {
///             ret[i] = ret[i - 1] + ret[i - 2];
///             i += 1;
///         }
///         &{ret}
///     };
///     
///     const ONE: u128 = 1;
///     const FOUR: u128 = 4;
///     const SEVEN: u128 = 7;
/// }
/// 
/// assert_eq!(getconst!(FIBNUMS<ONE>), &[1, 1, 2, 3, 5, 8, 13, 21]);
/// assert_eq!(getconst!(FIBNUMS<FOUR>), &[4, 4, 8, 12, 20, 32, 52, 84]);
/// assert_eq!(getconst!(FIBNUMS<SEVEN>), &[7, 7, 14, 21, 35, 56, 91, 147]);
/// 
/// 
/// ```
/// 
/// ### Manual impl
/// 
/// ```rust
/// use core_extensions::{ConstVal, getconst};
/// 
/// struct Foo;
///
/// struct Bar<T>(std::marker::PhantomData<T>);
/// 
/// impl ConstVal for Foo {
///     type Ty = u32;
///     const VAL: Self::Ty = 3;
/// }
/// 
/// impl<T> ConstVal for Bar<T> 
/// where
///     T: ConstVal<Ty = u32>,
/// {
///     type Ty = u32;
///
///     const VAL: Self::Ty = T::VAL * 3 / 2;
/// }
/// 
/// assert_eq!(getconst!(Foo), 3);
/// assert_eq!(getconst!(Bar<Foo>), 4);
/// assert_eq!(getconst!(Bar<Bar<Foo>>), 6);
/// assert_eq!(getconst!(Bar<Bar<Bar<Foo>>>), 9);
/// 
/// ```
/// 
/// 
/// [`quasiconst`]: ./macro.quasiconst.html
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "const_val")))]
pub trait ConstVal {
    /// The type of the constant this represents.
    type Ty;

    /// The constant this represents.
    const VAL: Self::Ty;

    #[doc(hidden)]
    const __CORE_EXTENSIONS__05FFE5XDEJHD07CTUSQMW: Self::Ty = Self::VAL;

    /// Gets the constant this represents.
    fn const_val(&self) -> Self::Ty {
        Self::VAL
    }
}