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