1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use std::{
alloc::{alloc_zeroed, Layout},
marker::PhantomData,
slice::from_raw_parts_mut,
};
use crate::Enumerated;
pub struct EnumMap<'a, K, V>
where
K: Enumerated,
{
values: &'a mut [Option<V>],
_key_phantom_data: PhantomData<K>,
}
impl<'a, K, V> EnumMap<'a, K, V>
where
K: Enumerated,
{
pub fn new() -> Self {
Self {
values: unsafe {
let raw_memory = alloc_zeroed(Layout::array::<Option<V>>(K::len()).unwrap());
from_raw_parts_mut(raw_memory as *mut Option<V>, K::len())
},
_key_phantom_data: PhantomData {},
}
}
#[inline]
pub fn get(&self, key: K) -> Option<&V> {
self.values[key.position()].as_ref()
}
#[inline]
pub fn insert(&mut self, key: K, value: V) {
self.values[key.position()] = Some(value);
}
#[inline]
pub fn remove(&mut self, key: K) {
self.values[key.position()] = None;
}
}
impl<'a, K, V> Default for EnumMap<'a, K, V>
where
K: Enumerated,
{
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use crate::Enumerated;
use enum_collections_macros::enum_collections;
use super::EnumMap;
#[enum_collections]
enum Letter {
A,
B,
}
#[test]
fn new_all_none() {
let enum_map = EnumMap::<Letter, i32>::new();
for index in 0..Letter::len() {
assert_eq!(None, enum_map.values[index]);
}
}
#[test]
fn inserts() {
let mut enum_map = EnumMap::<Letter, i32>::new();
enum_map.insert(Letter::A, 42);
assert_eq!(Some(&42), enum_map.get(Letter::A));
assert_eq!(None, enum_map.get(Letter::B));
}
}