Skip to main content

multilinear_parser/
index_map.rs

1use std::{
2    marker::PhantomData,
3    ops::{Index, IndexMut},
4};
5
6/// Stores index based maps.
7pub struct IndexMap<I: Into<usize> + From<usize>, V> {
8    pub(crate) entries: Vec<V>,
9    index: PhantomData<I>,
10}
11
12impl<I: Into<usize> + From<usize>, V> Default for IndexMap<I, V> {
13    fn default() -> Self {
14        Self {
15            entries: Vec::new(),
16            index: PhantomData,
17        }
18    }
19}
20
21impl<I: Into<usize> + From<usize>, V> IndexMap<I, V> {
22    /// Returns if the index map contains no elements.
23    #[must_use]
24    pub const fn is_empty(&self) -> bool {
25        self.entries.is_empty()
26    }
27
28    /// Returns the number of elements.
29    #[must_use]
30    pub const fn len(&self) -> usize {
31        self.entries.len()
32    }
33
34    /// Gets an entry by index.
35    pub fn get(&self, index: I) -> Option<&V> {
36        self.entries.get(index.into())
37    }
38
39    /// Gets a mutable entry by index.
40    pub fn get_mut(&self, index: I) -> Option<&V> {
41        self.entries.get(index.into())
42    }
43
44    /// Returns an iterator over the index map.
45    #[must_use]
46    pub fn iter(&self) -> Iter<'_, I, V> {
47        self.into_iter()
48    }
49
50    pub(crate) fn insert(&mut self, index: I, value: V) {
51        let i = index.into();
52        assert_eq!(i, self.entries.len(), "Wrong insertion order");
53        self.entries.push(value);
54    }
55}
56
57impl<I: Into<usize> + From<usize>, V> Index<I> for IndexMap<I, V> {
58    type Output = V;
59
60    fn index(&self, index: I) -> &V {
61        &self.entries[index.into()]
62    }
63}
64
65impl<I: Into<usize> + From<usize>, V> IndexMut<I> for IndexMap<I, V> {
66    fn index_mut(&mut self, index: I) -> &mut V {
67        &mut self.entries[index.into()]
68    }
69}
70
71/// An iterator over indices and values of an index map.
72pub struct IntoIter<I: Into<usize> + From<usize>, V> {
73    data: std::iter::Enumerate<std::vec::IntoIter<V>>,
74    index: PhantomData<I>,
75}
76
77impl<I: Into<usize> + From<usize>, V> Iterator for IntoIter<I, V> {
78    type Item = (I, V);
79
80    fn next(&mut self) -> Option<(I, V)> {
81        let (i, value) = self.data.next()?;
82        Some((i.into(), value))
83    }
84}
85
86impl<I: Into<usize> + From<usize>, V> IntoIterator for IndexMap<I, V> {
87    type Item = (I, V);
88    type IntoIter = IntoIter<I, V>;
89
90    fn into_iter(self) -> IntoIter<I, V> {
91        IntoIter {
92            data: self.entries.into_iter().enumerate(),
93            index: PhantomData,
94        }
95    }
96}
97
98/// An iterator over indices and values of an index map as references.
99pub struct Iter<'a, I: Into<usize> + From<usize>, V> {
100    data: std::iter::Enumerate<std::slice::Iter<'a, V>>,
101    index: PhantomData<I>,
102}
103
104impl<'a, I: Into<usize> + From<usize>, V> Iterator for Iter<'a, I, V> {
105    type Item = (I, &'a V);
106
107    fn next(&mut self) -> Option<(I, &'a V)> {
108        let (i, value) = self.data.next()?;
109        Some((i.into(), value))
110    }
111}
112
113impl<'a, I: Into<usize> + From<usize>, V> IntoIterator for &'a IndexMap<I, V> {
114    type Item = (I, &'a V);
115    type IntoIter = Iter<'a, I, V>;
116
117    fn into_iter(self) -> Iter<'a, I, V> {
118        Iter {
119            data: self.entries.iter().enumerate(),
120            index: PhantomData,
121        }
122    }
123}