enum_map/
enum_map_impls.rs

1// SPDX-FileCopyrightText: 2017 - 2021 Kamila Borowska <kamila@borowska.pw>
2// SPDX-FileCopyrightText: 2021 Bruno Corrêa Zimmermann <brunoczim@gmail.com>
3// SPDX-FileCopyrightText: 2021 micycle
4// SPDX-FileCopyrightText: 2023 Nicolas Carranza <nicarran@yandex.com>
5//
6// SPDX-License-Identifier: MIT OR Apache-2.0
7
8use crate::{enum_map, EnumArray, EnumMap};
9use core::fmt::{self, Debug, Formatter};
10use core::hash::{Hash, Hasher};
11use core::iter::{Extend, FromIterator};
12use core::ops::{Index, IndexMut};
13
14impl<K: EnumArray<V> + Debug, V: Debug> Debug for EnumMap<K, V> {
15    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
16        f.debug_map().entries(self).finish()
17    }
18}
19
20impl<K: EnumArray<V>, V> Extend<(K, V)> for EnumMap<K, V> {
21    fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
22        for (key, value) in iter {
23            self[key] = value;
24        }
25    }
26}
27
28impl<'a, K, V> Extend<(&'a K, &'a V)> for EnumMap<K, V>
29where
30    K: EnumArray<V> + Copy,
31    V: Copy,
32{
33    fn extend<I: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: I) {
34        self.extend(iter.into_iter().map(|(&key, &value)| (key, value)));
35    }
36}
37
38impl<K, V> FromIterator<(K, V)> for EnumMap<K, V>
39where
40    Self: Default,
41    K: EnumArray<V>,
42{
43    fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
44        let mut map = EnumMap::default();
45        map.extend(iter);
46        map
47    }
48}
49
50impl<K: EnumArray<V>, V> Index<K> for EnumMap<K, V> {
51    type Output = V;
52
53    #[inline]
54    fn index(&self, key: K) -> &V {
55        &self.as_slice()[key.into_usize()]
56    }
57}
58
59impl<K: EnumArray<V>, V> IndexMut<K> for EnumMap<K, V> {
60    #[inline]
61    fn index_mut(&mut self, key: K) -> &mut V {
62        &mut self.as_mut_slice()[key.into_usize()]
63    }
64}
65
66// Implementations provided by derive attribute are too specific, and put requirements on K.
67// This is caused by rust-lang/rust#26925.
68impl<K: EnumArray<V>, V> Clone for EnumMap<K, V>
69where
70    K::Array: Clone,
71{
72    #[inline]
73    fn clone(&self) -> Self {
74        EnumMap {
75            array: self.array.clone(),
76        }
77    }
78}
79
80impl<K: EnumArray<V>, V> Copy for EnumMap<K, V> where K::Array: Copy {}
81
82impl<K: EnumArray<V>, V: PartialEq> PartialEq for EnumMap<K, V> {
83    #[inline]
84    fn eq(&self, other: &Self) -> bool {
85        self.as_slice() == other.as_slice()
86    }
87}
88
89impl<K: EnumArray<V>, V: Eq> Eq for EnumMap<K, V> {}
90
91impl<K: EnumArray<V>, V: Hash> Hash for EnumMap<K, V> {
92    #[inline]
93    fn hash<H: Hasher>(&self, state: &mut H) {
94        self.as_slice().hash(state);
95    }
96}
97
98impl<K: EnumArray<V>, V: Default> Default for EnumMap<K, V> {
99    #[inline]
100    fn default() -> Self {
101        enum_map! { _ => V::default() }
102    }
103}
104
105impl<K: EnumArray<V>, V: PartialOrd> PartialOrd for EnumMap<K, V> {
106    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
107        self.as_slice().partial_cmp(other.as_slice())
108    }
109}
110
111impl<K: EnumArray<V>, V: Ord> Ord for EnumMap<K, V> {
112    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
113        self.as_slice().cmp(other.as_slice())
114    }
115}