1#![warn(missing_docs)]
6
7use std::{
8 marker::PhantomData,
9 ops::{Bound, RangeBounds},
10};
11
12use mapped_range_bounds::MappedRangeBounds;
13
14#[cfg(feature = "binary-io")]
15mod binary_io;
16mod mapped_range_bounds;
17#[cfg(test)]
18mod tests;
19mod trait_impls;
20
21pub struct TaggedVec<Index, Value> {
25 index_type: PhantomData<Index>,
26 vec: Vec<Value>,
27}
28
29impl<Index, Value> TaggedVec<Index, Value> {
30 pub fn new() -> Self {
32 Self::default()
33 }
34
35 pub fn with_capacity(capacity: usize) -> Self {
37 Self {
38 index_type: PhantomData,
39 vec: Vec::with_capacity(capacity),
40 }
41 }
42
43 pub fn len(&self) -> usize {
45 self.vec.len()
46 }
47
48 pub fn is_empty(&self) -> bool {
50 self.vec.is_empty()
51 }
52
53 pub fn capacity(&self) -> usize {
55 self.vec.capacity()
56 }
57
58 pub fn as_untagged_slice(&self) -> &[Value] {
60 &self.vec
61 }
62
63 pub fn as_untagged_mut_slice(&mut self) -> &mut [Value] {
65 &mut self.vec
66 }
67
68 pub fn push(&mut self, value: Value) -> Index
70 where
71 Index: From<usize>,
72 {
73 let index = self.vec.len().into();
74 self.vec.push(value);
75 index
76 }
77
78 pub fn push_in_place(&mut self, value: impl FnOnce(Index) -> Value) -> Index
83 where
84 Index: From<usize>,
85 {
86 let index = self.vec.len();
87 self.vec.push(value(index.into()));
88 index.into()
89 }
90
91 pub fn pop(&mut self) -> Option<(Index, Value)>
93 where
94 Index: From<usize>,
95 {
96 if let Some(value) = self.vec.pop() {
97 Some((self.vec.len().into(), value))
98 } else {
99 None
100 }
101 }
102
103 pub fn insert(&mut self, index: Index, value: Value)
105 where
106 Index: Into<usize>,
107 {
108 self.vec.insert(index.into(), value);
109 }
110
111 pub fn splice<I: IntoIterator<Item = Value>>(
113 &mut self,
114 range: impl RangeBounds<Index>,
115 replace_with: I,
116 ) -> std::vec::Splice<'_, I::IntoIter>
117 where
118 usize: From<Index>,
119 Index: Copy,
120 {
121 self.vec.splice(MappedRangeBounds::new(range), replace_with)
122 }
123
124 pub fn retain(&mut self, f: impl FnMut(&Value) -> bool) {
129 self.vec.retain(f);
130 }
131
132 pub fn remove_multi(&mut self, indices: impl IntoIterator<Item = Index>)
136 where
137 Index: Into<usize> + Clone,
138 {
139 let mut indices = indices.into_iter().peekable();
140 let mut current_index = 0;
141 self.vec.retain(|_| {
142 if let Some(next_delete_index) = indices.peek() {
143 let next_delete_index = next_delete_index.clone().into();
144 let result = if next_delete_index == current_index {
145 indices.next();
146
147 if let Some(next_next_delete_index) = indices.peek() {
148 let next_next_delete_index: usize = next_next_delete_index.clone().into();
149 assert!(next_next_delete_index > next_delete_index);
150 }
151
152 false
153 } else {
154 true
155 };
156 current_index += 1;
157 result
158 } else {
159 true
160 }
161 });
162
163 assert!(indices.next().is_none());
164 }
165
166 pub fn get(&self, index: Index) -> Option<&Value>
168 where
169 Index: Into<usize>,
170 {
171 self.vec.get(index.into())
172 }
173
174 pub fn iter(
179 &self,
180 range: impl RangeBounds<Index>,
181 ) -> impl DoubleEndedIterator<Item = (Index, &Value)> + ExactSizeIterator
182 where
183 Index: From<usize> + Copy,
184 usize: From<Index>,
185 {
186 let range = MappedRangeBounds::new(range);
187 let start_index_inclusive = match range.start_bound() {
188 Bound::Included(index) => *index,
189 Bound::Excluded(index) => (*index).checked_add(1).expect("start index overflow"),
190 Bound::Unbounded => 0,
191 };
192 let end_index_exclusive = match range.end_bound() {
193 Bound::Included(index) => (*index).checked_add(1).expect("end index overflow"),
194 Bound::Excluded(index) => *index,
195 Bound::Unbounded => self.vec.len(),
196 };
197
198 self.vec
199 .iter()
200 .enumerate()
201 .skip(start_index_inclusive)
202 .take(end_index_exclusive - start_index_inclusive)
203 .map(|(index, value)| (index.into(), value))
204 }
205
206 pub fn iter_mut(
211 &mut self,
212 range: impl RangeBounds<Index>,
213 ) -> impl DoubleEndedIterator<Item = (Index, &mut Value)> + ExactSizeIterator
214 where
215 Index: From<usize> + Copy,
216 usize: From<Index>,
217 {
218 let range = MappedRangeBounds::new(range);
219 let start_index_inclusive = match range.start_bound() {
220 Bound::Included(index) => *index,
221 Bound::Excluded(index) => (*index).checked_add(1).expect("start index overflow"),
222 Bound::Unbounded => 0,
223 };
224 let end_index_exclusive = match range.end_bound() {
225 Bound::Included(index) => (*index).checked_add(1).expect("end index overflow"),
226 Bound::Excluded(index) => *index,
227 Bound::Unbounded => self.vec.len(),
228 };
229
230 self.vec
231 .iter_mut()
232 .enumerate()
233 .skip(start_index_inclusive)
234 .take(end_index_exclusive - start_index_inclusive)
235 .map(|(index, value)| (index.into(), value))
236 }
237
238 pub fn iter_values(&self) -> std::slice::Iter<'_, Value> {
240 self.vec.iter()
241 }
242
243 pub fn iter_values_mut(&mut self) -> std::slice::IterMut<'_, Value> {
245 self.vec.iter_mut()
246 }
247
248 pub fn iter_indices(
253 &self,
254 range: impl RangeBounds<Index>,
255 ) -> impl DoubleEndedIterator<Item = Index> + ExactSizeIterator
256 where
257 Index: From<usize> + Copy,
258 usize: From<Index>,
259 {
260 let range = MappedRangeBounds::new(range);
261 let start_index_inclusive = match range.start_bound() {
262 Bound::Included(index) => *index,
263 Bound::Excluded(index) => (*index).checked_add(1).expect("start index overflow"),
264 Bound::Unbounded => 0,
265 };
266 let end_index_exclusive = match range.end_bound() {
267 Bound::Included(index) => (*index).checked_add(1).expect("end index overflow"),
268 Bound::Excluded(index) => *index,
269 Bound::Unbounded => self.vec.len(),
270 };
271
272 (start_index_inclusive..end_index_exclusive).map(Into::into)
273 }
274
275 pub fn into_iter(
280 self,
281 range: impl RangeBounds<Index>,
282 ) -> impl DoubleEndedIterator<Item = (Index, Value)> + ExactSizeIterator
283 where
284 Index: From<usize> + Copy,
285 usize: From<Index>,
286 {
287 let range = MappedRangeBounds::new(range);
288 let start_index_inclusive = match range.start_bound() {
289 Bound::Included(index) => *index,
290 Bound::Excluded(index) => (*index).checked_add(1).expect("start index overflow"),
291 Bound::Unbounded => 0,
292 };
293 let end_index_exclusive = match range.end_bound() {
294 Bound::Included(index) => (*index).checked_add(1).expect("end index overflow"),
295 Bound::Excluded(index) => *index,
296 Bound::Unbounded => self.vec.len(),
297 };
298
299 self.vec
300 .into_iter()
301 .enumerate()
302 .skip(start_index_inclusive)
303 .take(end_index_exclusive - start_index_inclusive)
304 .map(|(index, value)| (index.into(), value))
305 }
306
307 pub fn into_values_iter(self) -> std::vec::IntoIter<Value> {
309 self.vec.into_iter()
310 }
311}