1use std::convert::Infallible;
2use std::fmt::Debug;
3use std::marker::PhantomData;
4use std::mem;
5use std::ops::Index;
6use std::ops::IndexMut;
7use std::slice;
8
9use crate::array_as_mut::array_as_mut;
10use crate::array_builder::ArrayBuilder;
11use crate::array_from_iter::array_from_iter;
12use crate::map::total::IntoIterArray;
13use crate::map::total::Iter;
14use crate::map::total::IterMut;
15use crate::Ordinal;
16
17#[repr(C)]
40pub struct OrdinalTotalArrayMap<K, V, const S: usize> {
41 map: [V; S],
42 _phantom: PhantomData<K>,
43}
44
45impl<K: Ordinal, V, const S: usize> OrdinalTotalArrayMap<K, V, S> {
46 const ASSERT: () = {
47 assert!(K::ORDINAL_SIZE == S, "K::ORDINAL_SIZE != S");
48 };
49
50 pub fn try_new<E>(mut init: impl FnMut(K) -> Result<V, E>) -> Result<Self, E> {
52 const { Self::ASSERT };
53 let mut a = ArrayBuilder::new();
54 for v in K::all_values() {
55 a.push(init(v)?);
56 }
57 Ok(OrdinalTotalArrayMap {
58 map: a.finish(),
59 _phantom: PhantomData,
60 })
61 }
62
63 pub fn new(mut init: impl FnMut(K) -> V) -> Self {
65 const { Self::ASSERT };
66 match Self::try_new(move |k| Ok::<_, Infallible>(init(k))) {
67 Ok(map) => map,
68 Err(infallible) => match infallible {},
69 }
70 }
71
72 pub fn from_array(array: [V; S]) -> Self {
74 OrdinalTotalArrayMap {
75 map: array,
76 _phantom: PhantomData,
77 }
78 }
79
80 pub const fn len(&self) -> usize {
83 S
84 }
85
86 pub const fn is_empty(&self) -> bool {
88 self.len() == 0
89 }
90
91 pub fn get<'a>(&'a self, key: &K) -> &'a V {
93 &self.map[key.ordinal()]
94 }
95
96 pub fn get_mut<'a>(&'a mut self, key: &K) -> &'a mut V {
98 &mut self.map[key.ordinal()]
99 }
100
101 pub fn as_ref(&self) -> OrdinalTotalArrayMap<K, &V, S> {
103 OrdinalTotalArrayMap::new(|k| self.get(&k))
104 }
105
106 pub fn as_mut(&mut self) -> OrdinalTotalArrayMap<K, &mut V, S> {
108 OrdinalTotalArrayMap::from_array(array_as_mut(&mut self.map))
109 }
110
111 pub fn zip<W>(
113 self,
114 other: OrdinalTotalArrayMap<K, W, S>,
115 ) -> OrdinalTotalArrayMap<K, (V, W), S> {
116 OrdinalTotalArrayMap {
117 map: array_from_iter(self.map.into_iter().zip(other.map)),
118 _phantom: PhantomData,
119 }
120 }
121
122 pub fn map<W>(self, mut f: impl FnMut(K, V) -> W) -> OrdinalTotalArrayMap<K, W, S> {
124 OrdinalTotalArrayMap {
125 map: array_from_iter(self.into_iter().map(|(k, v)| f(k, v))),
126 _phantom: PhantomData,
127 }
128 }
129
130 pub fn map_values<W>(self, mut f: impl FnMut(V) -> W) -> OrdinalTotalArrayMap<K, W, S> {
132 self.map(|_k, v| f(v))
133 }
134
135 pub fn iter<'a>(&'a self) -> Iter<'a, K, V> {
137 Iter::new(self.map.iter(), 0)
138 }
139
140 pub fn iter_mut<'a>(&'a mut self) -> IterMut<'a, K, V> {
142 IterMut::new(self.map.iter_mut())
143 }
144
145 pub fn keys(&self) -> crate::OrdinalValues<K> {
147 K::all_values()
148 }
149
150 pub fn into_keys(self) -> crate::OrdinalValues<K> {
155 self.keys()
156 }
157
158 pub fn values<'a>(&'a self) -> slice::Iter<'a, V> {
160 self.map.iter()
161 }
162
163 pub fn values_array(&self) -> &[V; S] {
165 &self.map
166 }
167
168 pub fn values_mut<'a>(&'a mut self) -> slice::IterMut<'a, V> {
170 self.map.iter_mut()
171 }
172
173 pub fn values_array_mut(&mut self) -> &mut [V; S] {
175 &mut self.map
176 }
177
178 pub fn into_values(self) -> [V; S] {
180 self.map
181 }
182
183 #[inline]
185 pub fn insert(&mut self, key: K, value: V) -> V {
186 mem::replace(&mut self.map[key.ordinal()], value)
187 }
188}
189
190impl<'a, K: Ordinal, V, const S: usize> Index<&'a K> for OrdinalTotalArrayMap<K, V, S> {
191 type Output = V;
192
193 fn index(&self, index: &'a K) -> &Self::Output {
194 &self.map[index.ordinal()]
195 }
196}
197
198impl<'a, K: Ordinal, V, const S: usize> IndexMut<&'a K> for OrdinalTotalArrayMap<K, V, S> {
199 fn index_mut(&mut self, index: &'a K) -> &mut Self::Output {
200 &mut self.map[index.ordinal()]
201 }
202}
203
204impl<K, V: Clone, const S: usize> Clone for OrdinalTotalArrayMap<K, V, S> {
205 fn clone(&self) -> Self {
206 OrdinalTotalArrayMap {
207 map: self.map.clone(),
208 _phantom: PhantomData,
209 }
210 }
211}
212
213impl<K: Ordinal, V: Default, const S: usize> Default for OrdinalTotalArrayMap<K, V, S> {
214 fn default() -> Self {
215 OrdinalTotalArrayMap::new(|_| V::default())
216 }
217}
218
219impl<K: Ordinal + Debug, V: Debug, const S: usize> Debug for OrdinalTotalArrayMap<K, V, S> {
220 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
221 f.debug_map().entries(self.iter()).finish()
222 }
223}
224
225impl<K: Ordinal, V, const S: usize> IntoIterator for OrdinalTotalArrayMap<K, V, S> {
226 type Item = (K, V);
227 type IntoIter = IntoIterArray<K, V, S>;
228
229 fn into_iter(self) -> Self::IntoIter {
230 IntoIterArray::new(self.map.into_iter())
231 }
232}
233
234impl<'a, K: Ordinal, V, const S: usize> IntoIterator for &'a OrdinalTotalArrayMap<K, V, S> {
235 type Item = (K, &'a V);
236 type IntoIter = Iter<'a, K, V>;
237
238 fn into_iter(self) -> Self::IntoIter {
239 self.iter()
240 }
241}
242
243#[cfg(test)]
244mod tests {
245 #[test]
246 fn test() {}
247}