1#![no_std]
2
3extern crate alloc;
4
5use alloc::vec::Vec;
6use core::mem::replace;
7use core::ops::{Index, IndexMut};
8
9#[derive(Clone)]
16pub struct AllocVec<T> {
17 first: usize,
18 inner: Vec<AllocState<T>>
19}
20
21impl<T> AllocVec<T> {
22 #[inline]
24 pub const fn new() -> Self {
25 Self {
26 first: 0,
27 inner: Vec::new()
28 }
29 }
30
31 #[inline]
33 pub fn with_capacity(capacity: usize) -> Self {
34 Self {
35 first: 0,
36 inner: Vec::with_capacity(capacity)
37 }
38 }
39
40 #[inline]
49 pub fn get(&self, index: usize) -> Option<&T> {
50 self.inner
51 .get(index)
52 .and_then(|x| match x {
53 AllocState::Unallocated(_) => None,
54 AllocState::Allocated(elem) => Some(elem)
55 })
56 }
57
58 #[inline]
67 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
68 self.inner
69 .get_mut(index)
70 .and_then(|x| match x {
71 AllocState::Unallocated(_) => None,
72 AllocState::Allocated(elem) => Some(elem)
73 })
74 }
75
76 #[inline]
79 pub fn into_vec(self) -> Vec<T> {
80 self.inner
81 .into_iter()
82 .map(|x| match x {
83 AllocState::Unallocated(_) => None,
84 AllocState::Allocated(elem) => Some(elem),
85 })
86 .flatten()
87 .collect()
88 }
89
90 #[inline]
100 pub fn alloc(&mut self, item: T) -> usize {
101 self.alloc_cyclic(move |_| item)
102 }
103
104 #[inline]
114 pub fn alloc_cyclic<F>(&mut self, f: F) -> usize
115 where F: FnOnce(usize) -> T
116 {
117 let free_slot = self.inner.get(self.first).and_then(|x| {
118 match x {
119 AllocState::Unallocated(next) => Some(replace(&mut self.first, *next)),
120 AllocState::Allocated(_) => None
121 }
122 });
123
124 match free_slot {
125 Some(index) => {
126 self.inner.insert(index, AllocState::Allocated(f(index)));
127 index
128 },
129 None => {
130 let index = self.inner.len();
131 self.first = index + 1;
132 self.inner.push(AllocState::Allocated(f(index)));
133 index
134 }
135 }
136 }
137
138 #[inline]
147 pub fn dealloc(&mut self, index: usize) -> Option<T> {
148 self.inner.get_mut(index).and_then(|state| {
149 match state {
150 AllocState::Unallocated(_) => None,
151 AllocState::Allocated(_) => {
152 let old_first = replace(&mut self.first, index);
153 let old_state = replace(state, AllocState::Unallocated(old_first));
154 match old_state {
155 AllocState::Unallocated(_) => unreachable!(),
156 AllocState::Allocated(old) => Some(old)
157 }
158 }
159 }
160 })
161 }
162
163 #[inline]
174 pub fn realloc(&mut self, index: usize, item: T) -> Result<T, T> {
175 match self.inner.get_mut(index) {
176 Some(state) => {
177 match state {
178 AllocState::Unallocated(_) => Err(item),
179 AllocState::Allocated(old) => {
180 let old = replace(old, item);
181 Ok(old)
182 }
183 }
184 },
185 None => Err(item)
186 }
187 }
188
189 #[inline]
195 pub fn is_allocated(&self, index: usize) -> bool {
196 self.inner
197 .get(index)
198 .is_some_and(|x| match x {
199 AllocState::Unallocated(_) => false,
200 AllocState::Allocated(_) => true
201 })
202 }
203
204 #[inline]
207 pub fn len(&self) -> usize {
208 self.inner.iter().filter(|x| match x {
209 AllocState::Unallocated(_) => false,
210 AllocState::Allocated(_) => true
211 }).count()
212 }
213
214 #[inline]
217 pub fn is_empty(&self) -> bool {
218 self.len() == 0
219 }
220
221 #[inline]
224 pub fn vec_len(&self) -> usize {
225 self.inner.len()
226 }
227
228 #[inline]
231 pub fn capacity(&self) -> usize {
232 self.inner.capacity()
233 }
234
235 #[inline]
238 pub fn enumerate(&self) -> impl Iterator<Item = (usize, &T)> + '_ {
239 self.inner.iter()
240 .enumerate()
241 .filter(|(_, x)| if let AllocState::Allocated(_) = x { true } else { false })
242 .map(|(i, x)| if let AllocState::Allocated(x) = x { (i, x) } else { unreachable!() })
243 }
244
245 #[inline]
248 pub fn enumerate_mut(&mut self) -> impl Iterator<Item = (usize, &mut T)> + '_ {
249 self.inner.iter_mut()
250 .enumerate()
251 .filter(|(_, x)| if let AllocState::Allocated(_) = x { true } else { false })
252 .map(|(i, x)| if let AllocState::Allocated(x) = x { (i, x) } else { unreachable!() })
253 }
254
255 #[inline]
257 pub fn iter(&self) -> impl Iterator<Item = &T> + '_ {
258 self.inner.iter()
259 .filter(|x| if let AllocState::Allocated(_) = x { true } else { false })
260 .map(|x| if let AllocState::Allocated(x) = x { x } else { unreachable!() })
261 }
262
263 #[inline]
265 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> + '_ {
266 self.inner.iter_mut()
267 .filter(|x| if let AllocState::Allocated(_) = x { true } else { false })
268 .map(|x| if let AllocState::Allocated(x) = x { x } else { unreachable!() })
269 }
270}
271
272impl<T: Eq> AllocVec<T> {
273 #[inline]
278 pub fn contains(&self, value: &T) -> bool {
279 for item in self.inner.iter() {
280 if let AllocState::Allocated(value_) = item {
281 if value_ == value {
282 return true;
283 }
284 }
285 }
286 false
287 }
288}
289
290impl<T> Index<usize> for AllocVec<T> {
291 type Output = T;
292 #[inline]
293 fn index(&self, index: usize) -> &Self::Output {
294 match self.inner[index] {
295 AllocState::Allocated(ref val) => val,
296 _ => panic!("Tried to index unallocated value")
297 }
298 }
299}
300
301impl <T> IndexMut<usize> for AllocVec<T> {
302 #[inline]
303 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
304 match self.inner[index] {
305 AllocState::Allocated(ref mut val) => val,
306 _ => panic!("Tried to index unallocated value")
307 }
308 }
309}
310
311impl<T> From<Vec<T>> for AllocVec<T> {
312 #[inline]
313 fn from(value: Vec<T>) -> Self {
314 let mut inner = Vec::with_capacity(value.len());
315 for item in value {
316 inner.push(AllocState::Allocated(item));
317 }
318 Self {
319 first: 0,
320 inner
321 }
322 }
323}
324
325#[derive(Clone)]
326enum AllocState<T> {
327 Unallocated(usize),
328 Allocated(T)
329}
330
331#[test]
332fn alloc_vec_new() {
333 let vec: AllocVec<i32> = AllocVec::new();
334 assert_eq!(vec.vec_len(), 0);
335 assert_eq!(vec.capacity(), 0);
336}
337
338#[test]
339fn alloc_vec_with_capacity() {
340 let vec: AllocVec<i32> = AllocVec::with_capacity(15);
341 assert_eq!(vec.vec_len(), 0);
342 assert!(vec.capacity() >= 15);
343}
344
345#[test]
346fn alloc_vec_alloc_access_dealloc() {
347 let mut vec: AllocVec<i32> = AllocVec::new();
348 let (idx1, idx2, idx3) = (vec.alloc(24), vec.alloc(98), vec.alloc(12));
349
350 {
351 let (get1, get2, get3) = (vec.get(idx1), vec.get(idx2), vec.get(idx3));
352 assert!(get1.is_some());
353 assert!(get2.is_some());
354 assert!(get3.is_some());
355 }
356
357 assert_eq!(vec[idx1], 24);
358 assert_eq!(vec[idx2], 98);
359 assert_eq!(vec[idx3], 12);
360
361 vec.dealloc(idx2);
362 assert!(vec.get(idx1).is_some());
363 assert!(vec.get(idx2).is_none());
364 assert!(vec.get(idx3).is_some());
365
366 vec.dealloc(idx1);
367 assert!(vec.get(idx1).is_none());
368 assert!(vec.get(idx2).is_none());
369 assert!(vec.get(idx3).is_some());
370
371 vec.dealloc(idx3);
372 assert!(vec.get(idx1).is_none());
373 assert!(vec.get(idx2).is_none());
374 assert!(vec.get(idx3).is_none());
375}
376
377#[test]
378fn alloc_vec_reallocation() {
379 let mut vec: AllocVec<i32> = AllocVec::new();
380 let (idx1, mut idx2, idx3) = (vec.alloc(456), vec.alloc(10), vec.alloc(14));
381
382 assert_eq!(vec[idx1], 456);
383 assert_eq!(vec[idx2], 10);
384 assert_eq!(vec[idx3], 14);
385
386 vec.dealloc(idx2);
387 idx2 = vec.alloc(145);
388 assert_eq!(vec[idx2], 145);
389}
390
391#[test]
392fn alloc_vec_mut() {
393 let mut vec: AllocVec<i32> = AllocVec::new();
394 let idx = vec.alloc(15);
395
396 assert_eq!(vec[idx], 15);
397 vec[idx] = 20;
398 assert_eq!(vec[idx], 20);
399}
400
401#[test]
402fn alloc_vec_iter() {
403 let mut vec: AllocVec<i32> = AllocVec::new();
404 let idx1 = vec.alloc(15);
405 let idx2 = vec.alloc(90);
406 let idx3 = vec.alloc(75);
407 let idx4 = vec.alloc(42);
408
409 vec.dealloc(idx2);
410 let _ = vec.realloc(idx3, 7);
411
412 let collect: Vec<i32> = vec.iter().map(|x| *x).collect();
413 assert_eq!(collect[0], 15);
414 assert_eq!(collect[1], 7);
415 assert_eq!(collect[2], 42);
416
417 let collect: Vec<(usize, i32)> = vec.enumerate().map(|(i, x)| (i, *x)).collect();
418 assert_eq!(collect[0], (idx1, 15));
419 assert_eq!(collect[1], (idx3, 7));
420 assert_eq!(collect[2], (idx4, 42));
421}
422
423#[test]
424fn alloc_vec_getters() {
425 let mut vec: AllocVec<i32> = AllocVec::new();
426 let idx1 = vec.alloc(15);
427 let idx2 = vec.alloc(90);
428 let idx3 = vec.alloc(75);
429 let idx4 = vec.alloc(42);
430
431 vec.dealloc(idx2);
432 let _ = vec.realloc(idx3, 8);
433
434 assert!(vec.is_allocated(idx1));
435 assert!(!vec.is_allocated(idx2));
436 assert!(vec.is_allocated(idx3));
437 assert!(vec.is_allocated(idx4));
438}
439
440#[test]
441fn alloc_vec_cyclic() {
442 let mut vec: AllocVec<i32> = AllocVec::new();
443 let mut closure_idx = None;
444 let idx = vec.alloc_cyclic(|idx| {
445 closure_idx = Some(idx);
446 42
447 });
448
449 assert_eq!(idx, closure_idx.unwrap());
450}