modular_decomposition/
index.rs

1macro_rules! make_index {
2    ($vis:vis $name:ident) => {
3        /// Index type.
4        #[derive(
5            Copy,
6            Clone,
7            Debug,
8            Hash,
9            Eq,
10            PartialEq,
11            Ord,
12            PartialOrd,
13        )]
14        $vis struct $name(u32);
15
16        impl $name {
17            /// Create new index from `usize`.
18            #[inline(always)]
19            $vis fn new(x: usize) -> Self {
20                debug_assert!(x < u32::MAX as usize);
21                Self(x as u32)
22            }
23
24            /// Returns the index as `usize`.
25            #[inline(always)]
26            $vis fn index(&self) -> usize { self.0 as usize }
27
28            /// Create the maximum possible index.
29            #[inline(always)]
30            $vis fn end() -> Self { Self(u32::MAX) }
31        }
32
33        impl ::std::default::Default for $name {
34            #[inline(always)]
35            fn default() -> Self {
36                Self::end()
37            }
38        }
39
40        impl ::std::convert::From<usize> for $name {
41            #[inline(always)]
42            fn from(x: usize) -> Self {
43                Self::new(x)
44            }
45        }
46
47        impl ::std::convert::From<u32> for $name {
48            #[inline(always)]
49            fn from(x: u32) -> Self {
50                Self(x)
51            }
52        }
53
54        impl ::std::convert::From<$name> for usize {
55            #[inline(always)]
56            fn from(x: $name) -> Self {
57                x.index()
58            }
59        }
60
61        impl ::std::fmt::Display for $name {
62            fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
63                write!(f, "{}", self.0)
64            }
65        }
66    };
67}
68
69pub(crate) use make_index;
70
71#[cfg(test)]
72mod test {
73    #[test]
74    fn make_index() {
75        make_index!(TestIndex);
76
77        let idx = TestIndex::new(42);
78
79        assert_eq!(idx.index(), 42);
80        assert_eq!(TestIndex::end().index(), u32::MAX as usize);
81        assert_eq!(TestIndex::default(), TestIndex::end());
82        assert_eq!(TestIndex::from(42_u32), idx);
83        assert_eq!(TestIndex::from(42_usize), idx);
84        assert_eq!(usize::from(idx), 42_usize);
85        assert_eq!(format!("{:?}", idx), "TestIndex(42)".to_string());
86        assert_eq!(format!("{}", idx), "42".to_string());
87    }
88}