1#![no_std]
2
3extern crate alloc;
4
5use alloc::vec::Vec;
6use core::mem::replace;
7use core::ops::{Index, IndexMut};
8
9#[derive(Debug, 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 #[inline]
275 pub fn clear(&mut self) {
276 self.first = 0;
277 self.inner.clear();
278 }
279}
280
281impl<T: Eq> AllocVec<T> {
282 #[inline]
287 pub fn contains(&self, value: &T) -> bool {
288 for item in self.inner.iter() {
289 if let AllocState::Allocated(value_) = item {
290 if value_ == value {
291 return true;
292 }
293 }
294 }
295 false
296 }
297}
298
299impl<T> Index<usize> for AllocVec<T> {
300 type Output = T;
301 #[inline]
302 fn index(&self, index: usize) -> &Self::Output {
303 match self.inner[index] {
304 AllocState::Allocated(ref val) => val,
305 _ => panic!("Tried to index unallocated value")
306 }
307 }
308}
309
310impl <T> IndexMut<usize> for AllocVec<T> {
311 #[inline]
312 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
313 match self.inner[index] {
314 AllocState::Allocated(ref mut val) => val,
315 _ => panic!("Tried to index unallocated value")
316 }
317 }
318}
319
320impl<T> From<Vec<T>> for AllocVec<T> {
321 #[inline]
322 fn from(value: Vec<T>) -> Self {
323 let mut inner = Vec::with_capacity(value.len());
324 for item in value {
325 inner.push(AllocState::Allocated(item));
326 }
327 Self {
328 first: 0,
329 inner
330 }
331 }
332}
333
334#[derive(Debug, Clone, Copy)]
335enum AllocState<T> {
336 Unallocated(usize),
337 Allocated(T)
338}
339
340#[test]
341fn alloc_vec_new() {
342 let vec: AllocVec<i32> = AllocVec::new();
343 assert_eq!(vec.vec_len(), 0);
344 assert_eq!(vec.capacity(), 0);
345}
346
347#[test]
348fn alloc_vec_with_capacity() {
349 let vec: AllocVec<i32> = AllocVec::with_capacity(15);
350 assert_eq!(vec.vec_len(), 0);
351 assert!(vec.capacity() >= 15);
352}
353
354#[test]
355fn alloc_vec_alloc_access_dealloc() {
356 let mut vec: AllocVec<i32> = AllocVec::new();
357 let (idx1, idx2, idx3) = (vec.alloc(24), vec.alloc(98), vec.alloc(12));
358
359 {
360 let (get1, get2, get3) = (vec.get(idx1), vec.get(idx2), vec.get(idx3));
361 assert!(get1.is_some());
362 assert!(get2.is_some());
363 assert!(get3.is_some());
364 }
365
366 assert_eq!(vec[idx1], 24);
367 assert_eq!(vec[idx2], 98);
368 assert_eq!(vec[idx3], 12);
369
370 vec.dealloc(idx2);
371 assert!(vec.get(idx1).is_some());
372 assert!(vec.get(idx2).is_none());
373 assert!(vec.get(idx3).is_some());
374
375 vec.dealloc(idx1);
376 assert!(vec.get(idx1).is_none());
377 assert!(vec.get(idx2).is_none());
378 assert!(vec.get(idx3).is_some());
379
380 vec.dealloc(idx3);
381 assert!(vec.get(idx1).is_none());
382 assert!(vec.get(idx2).is_none());
383 assert!(vec.get(idx3).is_none());
384}
385
386#[test]
387fn alloc_vec_reallocation() {
388 let mut vec: AllocVec<i32> = AllocVec::new();
389 let (idx1, mut idx2, idx3) = (vec.alloc(456), vec.alloc(10), vec.alloc(14));
390
391 assert_eq!(vec[idx1], 456);
392 assert_eq!(vec[idx2], 10);
393 assert_eq!(vec[idx3], 14);
394
395 vec.dealloc(idx2);
396 idx2 = vec.alloc(145);
397 assert_eq!(vec[idx2], 145);
398}
399
400#[test]
401fn alloc_vec_mut() {
402 let mut vec: AllocVec<i32> = AllocVec::new();
403 let idx = vec.alloc(15);
404
405 assert_eq!(vec[idx], 15);
406 vec[idx] = 20;
407 assert_eq!(vec[idx], 20);
408}
409
410#[test]
411fn alloc_vec_iter() {
412 let mut vec: AllocVec<i32> = AllocVec::new();
413 let idx1 = vec.alloc(15);
414 let idx2 = vec.alloc(90);
415 let idx3 = vec.alloc(75);
416 let idx4 = vec.alloc(42);
417
418 vec.dealloc(idx2);
419 let _ = vec.realloc(idx3, 7);
420
421 let collect: Vec<i32> = vec.iter().map(|x| *x).collect();
422 assert_eq!(collect[0], 15);
423 assert_eq!(collect[1], 7);
424 assert_eq!(collect[2], 42);
425
426 let collect: Vec<(usize, i32)> = vec.enumerate().map(|(i, x)| (i, *x)).collect();
427 assert_eq!(collect[0], (idx1, 15));
428 assert_eq!(collect[1], (idx3, 7));
429 assert_eq!(collect[2], (idx4, 42));
430}
431
432#[test]
433fn alloc_vec_getters() {
434 let mut vec: AllocVec<i32> = AllocVec::new();
435 let idx1 = vec.alloc(15);
436 let idx2 = vec.alloc(90);
437 let idx3 = vec.alloc(75);
438 let idx4 = vec.alloc(42);
439
440 vec.dealloc(idx2);
441 let _ = vec.realloc(idx3, 8);
442
443 assert!(vec.is_allocated(idx1));
444 assert!(!vec.is_allocated(idx2));
445 assert!(vec.is_allocated(idx3));
446 assert!(vec.is_allocated(idx4));
447}
448
449#[test]
450fn alloc_vec_cyclic() {
451 let mut vec: AllocVec<i32> = AllocVec::new();
452 let mut closure_idx = None;
453 let idx = vec.alloc_cyclic(|idx| {
454 closure_idx = Some(idx);
455 42
456 });
457
458 assert_eq!(idx, closure_idx.unwrap());
459}