14697
|
1 |
use std::{
|
|
2 |
iter,
|
14698
|
3 |
mem::replace,
|
14697
|
4 |
ops::{Index, IndexMut},
|
|
5 |
};
|
|
6 |
|
|
7 |
pub struct IndexSlab<T> {
|
|
8 |
data: Vec<Option<T>>,
|
|
9 |
}
|
|
10 |
|
|
11 |
impl<T> IndexSlab<T> {
|
|
12 |
pub fn new() -> Self {
|
|
13 |
Self { data: Vec::new() }
|
|
14 |
}
|
|
15 |
|
|
16 |
pub fn with_capacity(capacity: usize) -> Self {
|
|
17 |
Self {
|
|
18 |
data: Vec::with_capacity(capacity),
|
|
19 |
}
|
|
20 |
}
|
|
21 |
|
|
22 |
pub fn insert(&mut self, index: usize, value: T) {
|
|
23 |
if index >= self.data.len() {
|
|
24 |
self.data.reserve(index - self.data.len() + 1);
|
|
25 |
self.data.extend((self.data.len()..index).map(|_| None));
|
|
26 |
self.data.push(Some(value))
|
|
27 |
} else {
|
|
28 |
self.data[index] = Some(value);
|
|
29 |
}
|
|
30 |
}
|
|
31 |
|
|
32 |
pub fn contains(&self, index: usize) -> bool {
|
|
33 |
self.data.get(index).and_then(|x| x.as_ref()).is_some()
|
|
34 |
}
|
|
35 |
|
14698
|
36 |
pub fn remove(&mut self, index: usize) -> Option<T> {
|
14697
|
37 |
if let Some(x) = self.data.get_mut(index) {
|
14698
|
38 |
replace(x, None)
|
|
39 |
} else {
|
|
40 |
None
|
14697
|
41 |
}
|
|
42 |
}
|
|
43 |
|
|
44 |
pub fn iter(&self) -> impl Iterator<Item = (usize, &T)> {
|
|
45 |
self.data
|
|
46 |
.iter()
|
|
47 |
.enumerate()
|
|
48 |
.filter_map(|(index, opt)| opt.as_ref().and_then(|x| Some((index, x))))
|
|
49 |
}
|
|
50 |
|
|
51 |
pub fn iter_mut(&mut self) -> impl Iterator<Item = (usize, &mut T)> {
|
|
52 |
self.data
|
|
53 |
.iter_mut()
|
|
54 |
.enumerate()
|
|
55 |
.filter_map(|(index, opt)| opt.as_mut().and_then(|x| Some((index, x))))
|
|
56 |
}
|
|
57 |
}
|
|
58 |
|
|
59 |
impl<T> Index<usize> for IndexSlab<T> {
|
|
60 |
type Output = T;
|
|
61 |
|
|
62 |
fn index(&self, index: usize) -> &Self::Output {
|
|
63 |
self.data[index].as_ref().unwrap()
|
|
64 |
}
|
|
65 |
}
|
|
66 |
|
|
67 |
impl<T> IndexMut<usize> for IndexSlab<T> {
|
|
68 |
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
|
69 |
self.data[index].as_mut().unwrap()
|
|
70 |
}
|
|
71 |
}
|