multilinear_parser/
index_map.rs1use std::{
2 marker::PhantomData,
3 ops::{Index, IndexMut},
4};
5
6pub 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 #[must_use]
24 pub const fn is_empty(&self) -> bool {
25 self.entries.is_empty()
26 }
27
28 #[must_use]
30 pub const fn len(&self) -> usize {
31 self.entries.len()
32 }
33
34 pub fn get(&self, index: I) -> Option<&V> {
36 self.entries.get(index.into())
37 }
38
39 pub fn get_mut(&self, index: I) -> Option<&V> {
41 self.entries.get(index.into())
42 }
43
44 #[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 #[expect(clippy::indexing_slicing)]
61 fn index(&self, index: I) -> &V {
62 &self.entries[index.into()]
63 }
64}
65
66impl<I: Into<usize> + From<usize>, V> IndexMut<I> for IndexMap<I, V> {
67 #[expect(clippy::indexing_slicing)]
68 fn index_mut(&mut self, index: I) -> &mut V {
69 &mut self.entries[index.into()]
70 }
71}
72
73pub struct IntoIter<I: Into<usize> + From<usize>, V> {
75 data: std::iter::Enumerate<std::vec::IntoIter<V>>,
76 index: PhantomData<I>,
77}
78
79impl<I: Into<usize> + From<usize>, V> Iterator for IntoIter<I, V> {
80 type Item = (I, V);
81
82 fn next(&mut self) -> Option<(I, V)> {
83 let (i, value) = self.data.next()?;
84 Some((i.into(), value))
85 }
86
87 fn size_hint(&self) -> (usize, Option<usize>) {
88 self.data.size_hint()
89 }
90}
91
92impl<I: Into<usize> + From<usize>, V> ExactSizeIterator for IntoIter<I, V> {}
93
94impl<I: Into<usize> + From<usize>, V> IntoIterator for IndexMap<I, V> {
95 type Item = (I, V);
96 type IntoIter = IntoIter<I, V>;
97
98 fn into_iter(self) -> IntoIter<I, V> {
99 IntoIter {
100 data: self.entries.into_iter().enumerate(),
101 index: PhantomData,
102 }
103 }
104}
105
106pub struct Iter<'a, I: Into<usize> + From<usize>, V> {
108 data: std::iter::Enumerate<std::slice::Iter<'a, V>>,
109 index: PhantomData<I>,
110}
111
112impl<'a, I: Into<usize> + From<usize>, V> Iterator for Iter<'a, I, V> {
113 type Item = (I, &'a V);
114
115 fn next(&mut self) -> Option<(I, &'a V)> {
116 let (i, value) = self.data.next()?;
117 Some((i.into(), value))
118 }
119
120 fn size_hint(&self) -> (usize, Option<usize>) {
121 self.data.size_hint()
122 }
123}
124
125impl<I: Into<usize> + From<usize>, V> ExactSizeIterator for Iter<'_, I, V> {}
126
127impl<'a, I: Into<usize> + From<usize>, V> IntoIterator for &'a IndexMap<I, V> {
128 type Item = (I, &'a V);
129 type IntoIter = Iter<'a, I, V>;
130
131 fn into_iter(self) -> Iter<'a, I, V> {
132 Iter {
133 data: self.entries.iter().enumerate(),
134 index: PhantomData,
135 }
136 }
137}