linearize/impls/
enums.rs
1macro_rules! impl_enum {
2 ($ty:ty, $num:literal: $($name:ident => $idx:expr,)*) => {
3 unsafe impl crate::Linearize for $ty {
5 type Storage<T> = [T; Self::LENGTH];
6 type CopyStorage<T>
7 = [T; Self::LENGTH]
8 where
9 T: Copy;
10 const LENGTH: usize = $num;
11
12 #[inline]
13 fn linearize(&self) -> usize {
14 match self {
15 $(<$ty>::$name => $idx,)*
16 }
17 }
18
19 #[inline]
20 unsafe fn from_linear_unchecked(linear: usize) -> Self
21 where
22 Self: Sized,
23 {
24 match linear {
25 $($idx => <$ty>::$name,)*
26 _ => unsafe {
27 cold_unreachable!();
29 },
30 }
31 }
32 }
33
34 impl_assert!($ty, $num);
35
36 #[test]
37 fn test() {
38 use crate::Linearize;
39 $(
40 assert_roundtrip!(<$ty>::$name, $idx);
41 )*
42 let variants = [$(<$ty>::$name),*];
43 assert_eq!(variants.len(), $num);
44 for (idx, variant) in variants.into_iter().enumerate() {
45 assert_eq!(variant.linearize(), idx);
46 }
47 }
48 };
49}
50
51mod core {
52 mod cmp {
53 mod ordering {
54 impl_enum! {
55 core::cmp::Ordering, 3:
56 Less => 0,
57 Equal => 1,
58 Greater => 2,
59 }
60 }
61 }
62
63 mod fmt {
64 mod alignment {
65 impl_enum! {
66 core::fmt::Alignment, 3:
67 Left => 0,
68 Right => 1,
69 Center => 2,
70 }
71 }
72 }
73
74 mod num {
75 mod fp_category {
76 impl_enum! {
77 core::num::FpCategory, 5:
78 Nan => 0,
79 Infinite => 1,
80 Zero => 2,
81 Subnormal => 3,
82 Normal => 4,
83 }
84 }
85 }
86}
87
88#[cfg(feature = "std")]
89mod std {
90 mod net {
91 mod shutdown {
92 impl_enum! {
93 std::net::Shutdown, 3:
94 Read => 0,
95 Write => 1,
96 Both => 2,
97 }
98 }
99 }
100}