1use std::{
2 borrow::Borrow,
3 collections::{BTreeMap, HashMap},
4 fmt::Debug,
5 hash::{BuildHasher, Hash},
6 marker::PhantomData,
7 mem::MaybeUninit,
8 ops::{Index, IndexMut},
9};
10
11use crate::{
12 finite::{Finite, FiniteExt},
13 IterAll,
14};
15
16#[repr(transparent)]
33pub struct ExhaustiveMap<K: Finite, V> {
34 array: Box<[V]>,
36 _phantom: PhantomData<K>,
37}
38
39impl<K: Finite, V> ExhaustiveMap<K, V> {
40 #[must_use]
44 pub fn from_fn(f: impl FnMut(K) -> V) -> Self {
45 Self {
46 array: K::iter_all().map(f).collect(),
47 _phantom: PhantomData,
48 }
49 }
50
51 pub fn try_from_fn<E>(f: impl FnMut(K) -> Result<V, E>) -> Result<Self, E> {
57 Ok(Self {
58 array: K::iter_all().map(f).collect::<Result<_, E>>()?,
59 _phantom: PhantomData,
60 })
61 }
62
63 #[must_use]
82 pub fn from_usize_fn(f: impl FnMut(usize) -> V) -> Self {
83 Self {
84 array: (0..K::INHABITANTS).map(f).collect(),
85 _phantom: PhantomData,
86 }
87 }
88
89 #[must_use]
93 pub const fn len(&self) -> usize {
94 K::INHABITANTS
95 }
96
97 #[must_use]
102 pub const fn is_empty(&self) -> bool {
103 K::INHABITANTS == 0
104 }
105
106 pub fn replace<Q: Borrow<K>>(&mut self, k: Q, v: V) -> V {
108 std::mem::replace(&mut self[k], v)
109 }
110
111 pub fn swap<Q1: Borrow<K>, Q2: Borrow<K>>(&mut self, k1: Q1, k2: Q2) {
113 self.array
114 .swap(k1.borrow().to_usize(), k2.borrow().to_usize());
115 }
116
117 pub fn take<Q: Borrow<K>>(&mut self, k: Q) -> V
119 where
120 V: Default,
121 {
122 std::mem::take(&mut self[k])
123 }
124
125 #[must_use]
137 pub fn map_values<U>(self, f: impl FnMut(V) -> U) -> ExhaustiveMap<K, U> {
138 ExhaustiveMap {
139 array: self.into_values().map(f).collect(),
140 _phantom: PhantomData,
141 }
142 }
143
144 pub fn keys() -> IterAll<K> {
148 K::iter_all()
149 }
150
151 pub fn values(&self) -> Values<'_, V> {
153 Values(self.array.iter())
154 }
155
156 pub fn values_mut(&mut self) -> ValuesMut<'_, V> {
158 ValuesMut(self.array.iter_mut())
159 }
160
161 pub fn into_values(self) -> IntoValues<V> {
164 IntoValues(self.array.into_vec().into_iter())
165 }
166
167 pub fn iter(&self) -> Iter<'_, K, V> {
171 Iter(Self::keys().zip(self.values()))
172 }
173
174 pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
178 IterMut(Self::keys().zip(self.values_mut()))
179 }
180
181 #[must_use]
186 pub fn new_uninit() -> ExhaustiveMap<K, MaybeUninit<V>> {
187 ExhaustiveMap::from_usize_fn(|_| MaybeUninit::uninit())
188 }
189}
190
191impl<K: Finite, V> ExhaustiveMap<K, Option<V>> {
192 pub fn try_unwrap_values(self) -> Result<ExhaustiveMap<K, V>, ExhaustiveMap<K, Option<V>>> {
198 if !self.array.iter().all(Option::is_some) {
199 return Err(self);
200 }
201 #[allow(clippy::missing_panics_doc)]
202 let values: Box<[V]> = self
203 .array
204 .into_vec()
205 .into_iter()
206 .map(|v| v.unwrap())
207 .collect();
208 Ok(unsafe { values.try_into().unwrap_unchecked() })
210 }
211}
212
213impl<K: Finite, V> ExhaustiveMap<K, MaybeUninit<V>> {
214 #[must_use]
218 pub unsafe fn assume_init(self) -> ExhaustiveMap<K, V> {
219 ExhaustiveMap {
220 array: std::mem::transmute::<Box<[MaybeUninit<V>]>, Box<[V]>>(self.array),
221 _phantom: PhantomData,
222 }
223 }
224}
225
226impl<K: Finite, V> TryFrom<Box<[V]>> for ExhaustiveMap<K, V> {
227 type Error = Box<[V]>;
228
229 fn try_from(value: Box<[V]>) -> Result<Self, Self::Error> {
230 if value.len() != K::INHABITANTS {
231 return Err(value);
232 }
233 Ok(Self {
234 array: value,
235 _phantom: PhantomData,
236 })
237 }
238}
239
240impl<K: Finite, V> From<ExhaustiveMap<K, V>> for Box<[V]> {
241 fn from(value: ExhaustiveMap<K, V>) -> Self {
242 value.array
243 }
244}
245
246impl<K: Finite, V> TryFrom<Vec<V>> for ExhaustiveMap<K, V> {
247 type Error = Vec<V>;
248
249 fn try_from(value: Vec<V>) -> Result<Self, Self::Error> {
250 if value.len() != K::INHABITANTS {
251 return Err(value);
252 }
253 Ok(Self {
254 array: value.into(),
255 _phantom: PhantomData,
256 })
257 }
258}
259
260impl<const N: usize, K: Finite, V> TryFrom<[V; N]> for ExhaustiveMap<K, V> {
261 type Error = [V; N];
262
263 fn try_from(value: [V; N]) -> Result<Self, Self::Error> {
264 if N != K::INHABITANTS {
265 return Err(value);
266 }
267 Ok(Self {
268 array: value.into(),
269 _phantom: PhantomData,
270 })
271 }
272}
273
274impl<K: Finite + Eq + Hash, V> TryFrom<HashMap<K, V>> for ExhaustiveMap<K, V> {
275 type Error = K;
276
277 fn try_from(mut value: HashMap<K, V>) -> Result<Self, Self::Error> {
278 Self::try_from_fn(|k| value.remove(&k).ok_or(k))
279 }
280}
281
282impl<K: Finite + Eq + Hash, V, S: BuildHasher + Default> From<ExhaustiveMap<K, V>>
283 for HashMap<K, V, S>
284{
285 fn from(value: ExhaustiveMap<K, V>) -> Self {
286 Self::from_iter(value)
287 }
288}
289
290impl<K: Finite + Ord, V> From<ExhaustiveMap<K, V>> for BTreeMap<K, V> {
291 fn from(value: ExhaustiveMap<K, V>) -> Self {
292 Self::from_iter(value)
293 }
294}
295
296#[must_use = "iterators are lazy and do nothing unless consumed"]
300pub struct Values<'a, V>(std::slice::Iter<'a, V>);
301
302impl<'a, V> Iterator for Values<'a, V> {
303 type Item = &'a V;
304
305 fn next(&mut self) -> Option<Self::Item> {
306 self.0.next()
307 }
308
309 fn size_hint(&self) -> (usize, Option<usize>) {
310 (self.0.len(), Some(self.0.len()))
311 }
312}
313
314impl<T> ExactSizeIterator for Values<'_, T> {
315 fn len(&self) -> usize {
316 self.0.len()
317 }
318}
319
320impl<T> DoubleEndedIterator for Values<'_, T> {
321 fn next_back(&mut self) -> Option<Self::Item> {
322 self.0.next_back()
323 }
324}
325
326#[must_use = "iterators are lazy and do nothing unless consumed"]
330pub struct ValuesMut<'a, V>(std::slice::IterMut<'a, V>);
331
332impl<'a, V> Iterator for ValuesMut<'a, V> {
333 type Item = &'a mut V;
334
335 fn next(&mut self) -> Option<Self::Item> {
336 self.0.next()
337 }
338
339 fn size_hint(&self) -> (usize, Option<usize>) {
340 (self.0.len(), Some(self.0.len()))
341 }
342}
343
344impl<T> ExactSizeIterator for ValuesMut<'_, T> {
345 fn len(&self) -> usize {
346 self.0.len()
347 }
348}
349
350impl<T> DoubleEndedIterator for ValuesMut<'_, T> {
351 fn next_back(&mut self) -> Option<Self::Item> {
352 self.0.next_back()
353 }
354}
355
356#[must_use = "iterators are lazy and do nothing unless consumed"]
360pub struct IntoValues<V>(std::vec::IntoIter<V>);
361
362impl<V> Iterator for IntoValues<V> {
363 type Item = V;
364
365 fn next(&mut self) -> Option<Self::Item> {
366 self.0.next()
367 }
368
369 fn size_hint(&self) -> (usize, Option<usize>) {
370 (self.0.len(), Some(self.0.len()))
371 }
372}
373
374impl<T> ExactSizeIterator for IntoValues<T> {
375 fn len(&self) -> usize {
376 self.0.len()
377 }
378}
379
380impl<T> DoubleEndedIterator for IntoValues<T> {
381 fn next_back(&mut self) -> Option<Self::Item> {
382 self.0.next_back()
383 }
384}
385
386impl<K: Finite, V: Default> Default for ExhaustiveMap<K, V> {
387 fn default() -> Self {
388 Self::from_fn(|_| V::default())
389 }
390}
391
392#[must_use = "iterators are lazy and do nothing unless consumed"]
396pub struct Iter<'a, K, V>(std::iter::Zip<IterAll<K>, Values<'a, V>>);
397
398impl<'a, K, V> Iterator for Iter<'a, K, V> {
399 type Item = (K, &'a V);
400
401 fn next(&mut self) -> Option<Self::Item> {
402 self.0.next()
403 }
404
405 fn size_hint(&self) -> (usize, Option<usize>) {
406 (self.0.len(), Some(self.0.len()))
407 }
408}
409
410impl<K, V> ExactSizeIterator for Iter<'_, K, V> {
411 fn len(&self) -> usize {
412 self.0.len()
413 }
414}
415
416impl<K, V> DoubleEndedIterator for Iter<'_, K, V> {
417 fn next_back(&mut self) -> Option<Self::Item> {
418 self.0.next_back()
419 }
420}
421
422#[must_use = "iterators are lazy and do nothing unless consumed"]
426pub struct IterMut<'a, K, V>(std::iter::Zip<IterAll<K>, ValuesMut<'a, V>>);
427
428impl<'a, K, V> Iterator for IterMut<'a, K, V> {
429 type Item = (K, &'a mut V);
430
431 fn next(&mut self) -> Option<Self::Item> {
432 self.0.next()
433 }
434
435 fn size_hint(&self) -> (usize, Option<usize>) {
436 (self.0.len(), Some(self.0.len()))
437 }
438}
439
440impl<K, V> ExactSizeIterator for IterMut<'_, K, V> {
441 fn len(&self) -> usize {
442 self.0.len()
443 }
444}
445
446impl<K, V> DoubleEndedIterator for IterMut<'_, K, V> {
447 fn next_back(&mut self) -> Option<Self::Item> {
448 self.0.next_back()
449 }
450}
451
452#[must_use = "iterators are lazy and do nothing unless consumed"]
457pub struct IntoIter<K, V>(std::iter::Zip<IterAll<K>, IntoValues<V>>);
458
459impl<K, V> Iterator for IntoIter<K, V> {
460 type Item = (K, V);
461
462 fn next(&mut self) -> Option<Self::Item> {
463 self.0.next()
464 }
465
466 fn size_hint(&self) -> (usize, Option<usize>) {
467 (self.0.len(), Some(self.0.len()))
468 }
469}
470
471impl<K, V> ExactSizeIterator for IntoIter<K, V> {
472 fn len(&self) -> usize {
473 self.0.len()
474 }
475}
476
477impl<K, V> DoubleEndedIterator for IntoIter<K, V> {
478 fn next_back(&mut self) -> Option<Self::Item> {
479 self.0.next_back()
480 }
481}
482
483impl<K: Finite, V> IntoIterator for ExhaustiveMap<K, V> {
484 type Item = (K, V);
485
486 type IntoIter = IntoIter<K, V>;
487
488 fn into_iter(self) -> Self::IntoIter {
489 IntoIter(Self::keys().zip(self.into_values()))
490 }
491}
492
493impl<'a, K: Finite, V> IntoIterator for &'a ExhaustiveMap<K, V> {
494 type Item = (K, &'a V);
495
496 type IntoIter = Iter<'a, K, V>;
497
498 fn into_iter(self) -> Self::IntoIter {
499 self.iter()
500 }
501}
502
503impl<'a, K: Finite, V> IntoIterator for &'a mut ExhaustiveMap<K, V> {
504 type Item = (K, &'a mut V);
505
506 type IntoIter = IterMut<'a, K, V>;
507
508 fn into_iter(self) -> Self::IntoIter {
509 self.iter_mut()
510 }
511}
512
513impl<K: Finite + Debug, V: Debug> Debug for ExhaustiveMap<K, V> {
514 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
515 f.debug_map().entries(self).finish()
516 }
517}
518
519impl<K: Finite, V, Q: Borrow<K>> Index<Q> for ExhaustiveMap<K, V> {
520 type Output = V;
521
522 fn index(&self, index: Q) -> &Self::Output {
523 &self.array[K::to_usize(index.borrow())]
524 }
525}
526
527impl<K: Finite, V, Q: Borrow<K>> IndexMut<Q> for ExhaustiveMap<K, V> {
528 fn index_mut(&mut self, index: Q) -> &mut Self::Output {
529 &mut self.array[K::to_usize(index.borrow())]
530 }
531}
532
533impl<K: Finite, V: Clone> Clone for ExhaustiveMap<K, V> {
537 fn clone(&self) -> Self {
538 Self {
539 array: self.array.clone(),
540 _phantom: PhantomData,
541 }
542 }
543}
544
545impl<K: Finite, V: PartialEq> PartialEq for ExhaustiveMap<K, V> {
546 fn eq(&self, other: &Self) -> bool {
547 self.array.eq(&other.array)
548 }
549}
550
551impl<K: Finite, V: Eq> Eq for ExhaustiveMap<K, V> {}
552
553impl<K: Finite, V: PartialOrd> PartialOrd for ExhaustiveMap<K, V> {
554 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
555 self.array.partial_cmp(&other.array)
556 }
557}
558
559impl<K: Finite, V: Ord> Ord for ExhaustiveMap<K, V> {
560 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
561 self.array.cmp(&other.array)
562 }
563}
564
565impl<K: Finite, V: Hash> Hash for ExhaustiveMap<K, V> {
566 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
567 self.array.hash(state);
568 }
569}
570
571unsafe impl<K: Finite, V> Send for ExhaustiveMap<K, V> where Box<[V]>: Send {}
573unsafe impl<K: Finite, V> Sync for ExhaustiveMap<K, V> where Box<[V]>: Sync {}
575
576#[cfg(test)]
577mod test {
578 use super::*;
579
580 #[derive(Finite)]
581 struct Key(PhantomData<*mut u8>);
582
583 #[allow(unused)]
584 const fn assert_implements_traits<
585 T: Send + Sync + Default + Clone + PartialEq + Eq + PartialOrd + Ord + Hash,
586 >() {
587 }
588
589 const _: () = assert_implements_traits::<ExhaustiveMap<Key, bool>>();
590
591 #[test]
592 fn test_uninit() {
593 let mut m = ExhaustiveMap::<bool, u8>::new_uninit();
594 m[true].write(123);
595 m[false].write(45);
596 let m = unsafe { m.assume_init() };
598 println!("{m:?}");
599 }
600
601 #[test]
602 fn test_conversion() {
603 let m: ExhaustiveMap<bool, u8> = [2, 3].try_into().unwrap();
604 assert_eq!(m[false], 2);
605 assert_eq!(m[true], 3);
606 }
607
608 #[test]
609 fn test_try_unrwap_values() {
610 let m: ExhaustiveMap<bool, Option<u8>> = ExhaustiveMap::from_fn(|_| None);
611 let mut m = m.try_unwrap_values().unwrap_err();
612 m[false] = Some(2);
613 let mut m = m.try_unwrap_values().unwrap_err();
614 m[true] = Some(3);
615 let m = m.try_unwrap_values().unwrap();
616 let expected: ExhaustiveMap<bool, u8> = [2, 3].try_into().unwrap();
617 assert_eq!(m, expected);
618 }
619}