enum_map_internals/lib.rs
1#![no_std]
2
3#[macro_use]
4extern crate array_macro;
5
6/// Enum map constructor.
7///
8/// This macro allows to create a new enum map in a type safe way. It takes
9/// a list of `,` separated pairs separated by `=>`. Left side is `|`
10/// separated list of enum keys, or `_` to match all unmatched enum keys,
11/// while right side is a value.
12///
13/// # Examples
14///
15/// ```
16/// # extern crate enum_map;
17/// use enum_map::{enum_map, Enum};
18///
19/// #[derive(Enum)]
20/// enum Example {
21/// A,
22/// B,
23/// C,
24/// D,
25/// }
26///
27/// fn main() {
28/// let enum_map = enum_map! {
29/// Example::A | Example::B => 1,
30/// Example::C => 2,
31/// _ => 3,
32/// };
33/// assert_eq!(enum_map[Example::A], 1);
34/// assert_eq!(enum_map[Example::B], 1);
35/// assert_eq!(enum_map[Example::C], 2);
36/// assert_eq!(enum_map[Example::D], 3);
37/// }
38/// ```
39#[macro_export]
40macro_rules! enum_map {
41 {$($t:tt)*} => {
42 $crate::from_fn(|k| match k { $($t)* })
43 };
44}
45
46mod enum_map_impls;
47mod internal;
48mod iter;
49mod serde;
50
51pub use internal::Enum;
52pub use iter::{IntoIter, Iter, IterMut, Values, ValuesMut};
53
54/// An enum mapping.
55///
56/// This internally uses an array which stores a value for each possible
57/// enum value. To work, it requires implementation of internal (private,
58/// although public due to macro limitations) trait which allows extracting
59/// information about an enum, which can be automatically generated using
60/// `#[derive(Enum)]` macro.
61///
62/// Additionally, `bool` and `u8` automatically derives from `Enum`. While
63/// `u8` is not technically an enum, it's convenient to consider it like one.
64/// In particular, [reverse-complement in benchmark game] could be using `u8`
65/// as an enum.
66///
67/// # Examples
68///
69/// ```
70/// # extern crate enum_map;
71/// use enum_map::{enum_map, Enum, EnumMap};
72///
73/// #[derive(Enum)]
74/// enum Example {
75/// A,
76/// B,
77/// C,
78/// }
79///
80/// fn main() {
81/// let mut map = EnumMap::new();
82/// // new initializes map with default values
83/// assert_eq!(map[Example::A], 0);
84/// map[Example::A] = 3;
85/// assert_eq!(map[Example::A], 3);
86/// }
87/// ```
88///
89/// [reverse-complement in benchmark game]:
90/// http://benchmarksgame.alioth.debian.org/u64q/program.php?test=revcomp&lang=rust&id=2
91pub struct EnumMap<K: Enum<V>, V> {
92 array: K::Array,
93}
94
95impl<K: Enum<V>, V: Default> EnumMap<K, V> {
96 /// Creates an enum map with default values.
97 ///
98 /// # Examples
99 ///
100 /// ```
101 /// # extern crate enum_map;
102 /// use enum_map::{Enum, EnumMap};
103 ///
104 /// #[derive(Enum)]
105 /// enum Example {
106 /// A,
107 /// }
108 ///
109 /// fn main() {
110 /// let enum_map = EnumMap::<_, i32>::new();
111 /// assert_eq!(enum_map[Example::A], 0);
112 /// }
113 /// ```
114 #[inline]
115 pub fn new() -> Self {
116 EnumMap::default()
117 }
118}
119
120impl<K: Enum<V>, V> EnumMap<K, V> {
121 /// Returns an iterator over enum map.
122 #[inline]
123 pub fn iter(&self) -> Iter<K, V> {
124 self.into_iter()
125 }
126
127 /// Returns a mutable iterator over enum map.
128 #[inline]
129 pub fn iter_mut(&mut self) -> IterMut<K, V> {
130 self.into_iter()
131 }
132
133 /// Returns number of elements in enum map.
134 #[inline]
135 pub fn len(&self) -> usize {
136 self.as_slice().len()
137 }
138
139 /// Returns whether the enum variant set is empty.
140 ///
141 /// This isn't particularly useful, as there is no real reason to use
142 /// enum map for enums without variants. However, it is provided for
143 /// consistency with data structures providing len method (and I will
144 /// admit, to avoid clippy warnings).
145 ///
146 /// # Examples
147 ///
148 /// ```
149 /// # extern crate enum_map;
150 /// use enum_map::{Enum, EnumMap};
151 ///
152 /// #[derive(Enum)]
153 /// enum Void {}
154 ///
155 /// #[derive(Enum)]
156 /// enum SingleVariant {
157 /// Variant,
158 /// }
159 ///
160 /// fn main() {
161 /// assert!(EnumMap::<Void, ()>::new().is_empty());
162 /// assert!(!EnumMap::<SingleVariant, ()>::new().is_empty());
163 /// }
164 #[inline]
165 pub fn is_empty(&self) -> bool {
166 self.as_slice().is_empty()
167 }
168
169 /// Swaps two indexes.
170 ///
171 /// # Examples
172 ///
173 /// ```
174 /// # extern crate enum_map;
175 /// use enum_map::enum_map;
176 ///
177 /// fn main() {
178 /// let mut map = enum_map! { false => 0, true => 1 };
179 /// map.swap(false, true);
180 /// assert_eq!(map[false], 1);
181 /// assert_eq!(map[true], 0);
182 /// }
183 /// ```
184 #[inline]
185 pub fn swap(&mut self, a: K, b: K) {
186 self.as_mut_slice().swap(a.to_usize(), b.to_usize())
187 }
188
189 /// Converts an enum map to a slice representing values.
190 #[inline]
191 pub fn as_slice(&self) -> &[V] {
192 K::slice(&self.array)
193 }
194
195 /// Converts a mutable enum map to a mutable slice representing values.
196 #[inline]
197 pub fn as_mut_slice(&mut self) -> &mut [V] {
198 K::slice_mut(&mut self.array)
199 }
200
201 /// Returns a raw pointer to the enum map's slice.
202 ///
203 /// The caller must ensure that the slice outlives the pointer this
204 /// function returns, or else it will end up pointing to garbage.
205 ///
206 /// # Examples
207 ///
208 /// ```
209 /// # extern crate enum_map;
210 /// use enum_map::{enum_map, EnumMap};
211 ///
212 /// fn main() {
213 /// let map = enum_map! { 5 => 42, _ => 0 };
214 /// assert_eq!(unsafe { *map.as_ptr().offset(5) }, 42);
215 /// }
216 /// ```
217 #[inline]
218 pub fn as_ptr(&self) -> *const V {
219 self.as_slice().as_ptr()
220 }
221
222 /// Returns an unsafe mutable pointer to the enum map's slice.
223 ///
224 /// The caller must ensure that the slice outlives the pointer this
225 /// function returns, or else it will end up pointing to garbage.
226 ///
227 /// # Examples
228 ///
229 /// ```
230 /// # extern crate enum_map;
231 /// use enum_map::{enum_map, EnumMap};
232 ///
233 /// fn main() {
234 /// let mut map = enum_map! { _ => 0 };
235 /// unsafe {
236 /// *map.as_mut_ptr().offset(11) = 23
237 /// };
238 /// assert_eq!(map[11], 23);
239 /// }
240 /// ```
241 #[inline]
242 pub fn as_mut_ptr(&mut self) -> *mut V {
243 self.as_mut_slice().as_mut_ptr()
244 }
245}
246
247impl<F: FnMut(K) -> V, K: Enum<V>, V> From<F> for EnumMap<K, V> {
248 #[inline]
249 fn from(f: F) -> Self {
250 EnumMap {
251 array: K::from_function(f),
252 }
253 }
254}
255
256pub fn from_fn<K, V>(f: impl FnMut(K) -> V) -> EnumMap<K, V>
257where
258 K: Enum<V>,
259{
260 f.into()
261}