Skip to main content

ordinal_map/ordinal/impls/
primitive.rs

1use crate::Ordinal;
2
3impl Ordinal for bool {
4    const ORDINAL_SIZE: usize = 2;
5
6    fn ordinal(&self) -> usize {
7        *self as usize
8    }
9
10    fn from_ordinal(ordinal: usize) -> Option<Self> {
11        match ordinal {
12            0 => Some(false),
13            1 => Some(true),
14            _ => None,
15        }
16    }
17}
18
19impl Ordinal for u8 {
20    const ORDINAL_SIZE: usize = u8::MAX as usize + 1;
21
22    #[inline]
23    fn ordinal(&self) -> usize {
24        *self as usize
25    }
26
27    #[inline]
28    fn from_ordinal(ordinal: usize) -> Option<Self> {
29        u8::try_from(ordinal).ok()
30    }
31}
32
33impl Ordinal for i8 {
34    const ORDINAL_SIZE: usize = (i8::MAX as i16 - i8::MIN as i16 + 1) as usize;
35
36    #[inline]
37    fn ordinal(&self) -> usize {
38        self.abs_diff(i8::MIN) as usize
39    }
40
41    #[inline]
42    fn from_ordinal(ordinal: usize) -> Option<Self> {
43        i8::MIN.checked_add_unsigned(u8::try_from(ordinal).ok()?)
44    }
45}
46
47impl Ordinal for u16 {
48    const ORDINAL_SIZE: usize = u16::MAX as usize + 1;
49
50    #[inline]
51    fn ordinal(&self) -> usize {
52        *self as usize
53    }
54
55    #[inline]
56    fn from_ordinal(ordinal: usize) -> Option<Self> {
57        u16::try_from(ordinal).ok()
58    }
59}
60
61impl Ordinal for i16 {
62    const ORDINAL_SIZE: usize = (i16::MAX as isize - i16::MIN as isize + 1) as usize;
63
64    #[inline]
65    fn ordinal(&self) -> usize {
66        self.abs_diff(i16::MIN) as usize
67    }
68
69    #[inline]
70    fn from_ordinal(ordinal: usize) -> Option<Self> {
71        i16::MIN.checked_add_unsigned(u16::try_from(ordinal).ok()?)
72    }
73}
74
75/// Accessing this type is compile time error on 32-bit platforms.
76impl Ordinal for u32 {
77    const ORDINAL_SIZE: usize = u32::MAX as usize + 1;
78
79    #[inline]
80    fn ordinal(&self) -> usize {
81        const { Self::ORDINAL_SIZE };
82        *self as usize
83    }
84
85    #[inline]
86    fn from_ordinal(ordinal: usize) -> Option<Self> {
87        u32::try_from(ordinal).ok()
88    }
89}
90
91impl Ordinal for i32 {
92    const ORDINAL_SIZE: usize = u32::ORDINAL_SIZE;
93
94    #[inline]
95    fn ordinal(&self) -> usize {
96        const { Self::ORDINAL_SIZE };
97        self.abs_diff(i32::MIN) as usize
98    }
99
100    #[inline]
101    fn from_ordinal(ordinal: usize) -> Option<Self> {
102        const { Self::ORDINAL_SIZE };
103        i32::MIN.checked_add_unsigned(u32::try_from(ordinal).ok()?)
104    }
105}
106
107#[cfg(test)]
108mod tests {
109    use crate::tests::util::test_ordinal;
110    use crate::Ordinal;
111
112    #[test]
113    fn test_bool() {
114        test_ordinal::<bool>([false, true]);
115    }
116
117    #[test]
118    fn test_u8() {
119        test_ordinal::<u8>(0..=255);
120    }
121
122    #[test]
123    fn test_i8() {
124        test_ordinal::<i8>(i8::MIN..=i8::MAX);
125    }
126
127    #[test]
128    fn test_u16() {
129        test_ordinal::<u16>(0..=u16::MAX);
130    }
131
132    #[test]
133    fn test_i16() {
134        test_ordinal::<i16>(i16::MIN..=i16::MAX);
135    }
136
137    #[test]
138    fn test_u32() {
139        if cfg!(target_pointer_width = "64") {
140            let mut iter = u32::all_values();
141            assert_eq!(u32::MAX as usize + 1, iter.len());
142            assert_eq!(Some(0), iter.next());
143            assert_eq!(Some(1), iter.next());
144            assert_eq!(Some(u32::MAX), iter.next_back());
145        }
146    }
147
148    #[test]
149    fn test_i32() {
150        if cfg!(target_pointer_width = "64") {
151            let mut iter = i32::all_values();
152            assert_eq!(u32::MAX as usize + 1, iter.len());
153            assert_eq!(Some(i32::MIN), iter.next());
154            assert_eq!(Some(i32::MAX), iter.next_back());
155        }
156    }
157}