Skip to main content

nekolib/traits/
min.rs

1//! 最小元に関するトレイトです。
2
3/// 最小元を持つ。
4///
5/// # Examples
6/// ```
7/// use nekolib::traits::Min;
8///
9/// let min: i8 = Min::min();
10/// for x in std::i8::MIN..=std::i8::MAX {
11///     assert!(x >= min);
12/// }
13/// ```
14pub trait Min: Ord {
15    /// 最小元を返す。
16    fn min() -> Self;
17}
18
19macro_rules! impl_min {
20    (
21        $( $t:ident ),*
22    ) => {
23        $(
24            impl Min for $t {
25                fn min() -> Self {
26                    std::$t::MIN
27                }
28            }
29        )*
30    }
31}
32
33impl_min! {
34    i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize
35}
36
37impl Min for bool {
38    fn min() -> Self { false }
39}
40
41impl Min for char {
42    fn min() -> Self { '\0' }
43}
44
45impl Min for () {
46    fn min() -> Self { () }
47}
48
49impl<A: Min> Min for (A,) {
50    fn min() -> Self { (Min::min(),) }
51}
52
53macro_rules! impl_tuple {
54    (
55        ( $( $t:ident ),+ )
56    ) => {
57        impl < $( $t: Min ),+ > Min for ( $( $t ),+ ) {
58            fn min() -> Self { ( $( <$t as Min>::min() ),+ ) }
59        }
60    };
61    ( $( ( $( $t:ident ),+ ), )+ ) => {
62        $( impl_tuple! { ( $( $t ),+ ) } )+
63    }
64}
65
66impl_tuple! {
67    (A, B),
68    (A, B, C),
69    (A, B, C, D),
70    (A, B, C, D, E),
71    (A, B, C, D, E, F),
72    (A, B, C, D, E, F, G),
73    (A, B, C, D, E, F, G, H),
74    (A, B, C, D, E, F, G, H, I),
75    (A, B, C, D, E, F, G, H, I, J),
76    (A, B, C, D, E, F, G, H, I, J, K),
77    (A, B, C, D, E, F, G, H, I, J, K, L),
78}
79
80#[test]
81fn test() {
82    assert_eq!(<() as Min>::min(), ());
83    assert_eq!(<u8 as Min>::min(), 0);
84    assert_eq!(<char as Min>::min(), '\0');
85
86    let i32_min: i32 = Min::min();
87    let char_min: char = Min::min();
88    let u128_min: u128 = Min::min();
89    assert_eq!(
90        <(i32, char, u128) as Min>::min(),
91        (i32_min, char_min, u128_min)
92    );
93}