1#![warn(missing_docs)]
6
7use std::{marker::PhantomData, ops::RangeBounds};
8
9use mapped_range_bounds::MappedRangeBounds;
10
11#[cfg(feature = "binary-io")]
12mod binary_io;
13mod mapped_range_bounds;
14mod trait_impls;
15
16pub struct TaggedVec<Index, Value> {
20 index_type: PhantomData<Index>,
21 vec: Vec<Value>,
22}
23
24impl<Index, Value> TaggedVec<Index, Value> {
25 pub fn new() -> Self {
27 Self::default()
28 }
29
30 pub fn with_capacity(capacity: usize) -> Self {
32 Self {
33 index_type: PhantomData,
34 vec: Vec::with_capacity(capacity),
35 }
36 }
37
38 pub fn len(&self) -> usize {
40 self.vec.len()
41 }
42
43 pub fn is_empty(&self) -> bool {
45 self.vec.is_empty()
46 }
47
48 pub fn capacity(&self) -> usize {
50 self.vec.capacity()
51 }
52
53 pub fn as_untagged_slice(&self) -> &[Value] {
55 &self.vec
56 }
57
58 pub fn as_untagged_mut_slice(&mut self) -> &mut [Value] {
60 &mut self.vec
61 }
62
63 pub fn push(&mut self, value: Value) -> Index
65 where
66 Index: From<usize>,
67 {
68 let index = self.vec.len().into();
69 self.vec.push(value);
70 index
71 }
72
73 pub fn push_in_place(&mut self, value: impl FnOnce(Index) -> Value) -> Index
78 where
79 Index: From<usize>,
80 {
81 let index = self.vec.len();
82 self.vec.push(value(index.into()));
83 index.into()
84 }
85
86 pub fn pop(&mut self) -> Option<(Index, Value)>
88 where
89 Index: From<usize>,
90 {
91 if let Some(value) = self.vec.pop() {
92 Some((self.vec.len().into(), value))
93 } else {
94 None
95 }
96 }
97
98 pub fn insert(&mut self, index: Index, value: Value)
100 where
101 Index: Into<usize>,
102 {
103 self.vec.insert(index.into(), value);
104 }
105
106 pub fn splice<I: IntoIterator<Item = Value>>(
108 &mut self,
109 range: impl RangeBounds<Index>,
110 replace_with: I,
111 ) -> std::vec::Splice<'_, I::IntoIter>
112 where
113 usize: for<'a> From<&'a Index>,
114 {
115 self.vec.splice(MappedRangeBounds::new(range), replace_with)
116 }
117
118 pub fn retain(&mut self, f: impl FnMut(&Value) -> bool) {
123 self.vec.retain(f);
124 }
125
126 pub fn remove_multi(&mut self, indices: impl IntoIterator<Item = Index>)
130 where
131 Index: Into<usize> + Clone,
132 {
133 let mut indices = indices.into_iter().peekable();
134 let mut current_index = 0;
135 self.vec.retain(|_| {
136 if let Some(next_delete_index) = indices.peek() {
137 let next_delete_index = next_delete_index.clone().into();
138 let result = if next_delete_index == current_index {
139 indices.next();
140
141 if let Some(next_next_delete_index) = indices.peek() {
142 let next_next_delete_index: usize = next_next_delete_index.clone().into();
143 assert!(next_next_delete_index > next_delete_index);
144 }
145
146 false
147 } else {
148 true
149 };
150 current_index += 1;
151 result
152 } else {
153 true
154 }
155 });
156
157 assert!(indices.next().is_none());
158 }
159
160 pub fn get(&self, index: Index) -> Option<&Value>
162 where
163 Index: Into<usize>,
164 {
165 self.vec.get(index.into())
166 }
167
168 pub fn iter(&self) -> impl DoubleEndedIterator<Item = (Index, &Value)> + ExactSizeIterator
170 where
171 Index: From<usize>,
172 {
173 self.vec
174 .iter()
175 .enumerate()
176 .map(|(index, value)| (index.into(), value))
177 }
178
179 pub fn iter_mut(
181 &mut self,
182 ) -> impl DoubleEndedIterator<Item = (Index, &mut Value)> + ExactSizeIterator
183 where
184 Index: From<usize>,
185 {
186 self.vec
187 .iter_mut()
188 .enumerate()
189 .map(|(index, value)| (index.into(), value))
190 }
191
192 pub fn iter_values(&self) -> std::slice::Iter<'_, Value> {
194 self.vec.iter()
195 }
196
197 pub fn iter_values_mut(&mut self) -> std::slice::IterMut<'_, Value> {
199 self.vec.iter_mut()
200 }
201
202 pub fn iter_indices(&self) -> impl DoubleEndedIterator<Item = Index> + ExactSizeIterator
204 where
205 Index: From<usize>,
206 {
207 (0..self.vec.len()).map(Into::into)
208 }
209
210 pub fn into_values_iter(self) -> std::vec::IntoIter<Value> {
212 self.vec.into_iter()
213 }
214}
215
216#[cfg(test)]
217mod tests {
218 use crate::TaggedVec;
219
220 #[test]
221 fn delete_multi() {
222 let mut v = TaggedVec::<usize, _>::from_iter([0, 1, 2, 3, 4]);
223 v.remove_multi([0, 4]);
224 assert_eq!(v, vec![1, 2, 3].into());
225
226 let mut v = TaggedVec::<usize, _>::from_iter([0, 1, 2, 3, 4]);
227 v.remove_multi([0, 2, 4]);
228 assert_eq!(v, vec![1, 3].into());
229
230 let mut v = TaggedVec::<usize, _>::from_iter([0, 1, 2, 3, 4]);
231 v.remove_multi([1, 3]);
232 assert_eq!(v, vec![0, 2, 4].into());
233 }
234}