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