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}