Skip to main content

nekolib/traits/
max.rs

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