modular_decomposition/
index.rs1macro_rules! make_index {
2 ($vis:vis $name:ident) => {
3 #[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 #[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 #[inline(always)]
26 $vis fn index(&self) -> usize { self.0 as usize }
27
28 #[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}