enumoid/
vec.rs

1use crate::base::EnumArrayHelper;
2use crate::base::EnumSetHelper;
3use crate::base::EnumSize;
4use crate::iter::EnumSliceIter;
5use crate::iter::EnumSliceIterMut;
6use crate::opt_map::EnumOptionMap;
7use crate::sub_base::RawSizeWord;
8use crate::EnumIndex;
9use std::convert::TryFrom;
10use std::fmt;
11use std::fmt::Debug;
12use std::hash::Hash;
13use std::iter;
14use std::mem;
15use std::ops::{Index, IndexMut};
16use std::ptr;
17
18/// A vector of values `V` indexed by enumoid `T`.
19pub struct EnumVec<T: EnumArrayHelper<V>, V> {
20  pub(crate) len: T::Word,
21  pub(crate) data: T::PartialArray,
22}
23
24impl<T: EnumArrayHelper<V>, V> EnumVec<T, V> {
25  /// Creates a new vector with no elements.
26  pub fn new() -> Self {
27    EnumVec {
28      len: T::Word::ZERO,
29      data: T::new_partial(),
30    }
31  }
32
33  /// Creates a new vector with a specified number of elements generated by a
34  /// callback function.
35  pub fn new_with<F>(size: EnumSize<T>, mut f: F) -> Self
36  where
37    F: FnMut(T) -> V,
38  {
39    let mut vec = Self::new();
40    for key in size.iter() {
41      vec.push(f(key));
42    }
43    vec
44  }
45
46  /// Returns a slice containing all the values in the vector.
47  #[inline]
48  pub fn as_slice(&self) -> &[V] {
49    unsafe {
50      hint_assert!(
51        self.len <= T::SIZE_WORD,
52        "Length out of bounds: {:?} > {:?}",
53        self.len,
54        T::SIZE
55      );
56      let inited =
57        T::partial_slice(&self.data).get_unchecked(0..self.len.as_());
58      &*(inited as *const [std::mem::MaybeUninit<V>] as *const [V])
59    }
60  }
61
62  /// Returns a mutable slice containing all the values in the vector.
63  #[inline]
64  pub fn as_slice_mut(&mut self) -> &mut [V] {
65    unsafe {
66      hint_assert!(
67        self.len <= T::SIZE_WORD,
68        "Length out of bounds: {:?} > {:?}",
69        self.len,
70        T::SIZE
71      );
72      let inited = T::partial_slice_mut(&mut self.data)
73        .get_unchecked_mut(0..self.len.as_());
74      &mut *(inited as *mut [std::mem::MaybeUninit<V>] as *mut [V])
75    }
76  }
77
78  /// Returns a reference to the value associated with a given index,
79  /// or `None` if the index is beyond the end of the vector.
80  #[inline]
81  pub fn get_by_index(&self, index: EnumIndex<T>) -> Option<&V> {
82    self.as_slice().get(index.into_usize())
83  }
84
85  /// Returns a reference to the value associated with a given key,
86  /// or `None` if the key is beyond the end of the vector.
87  #[inline]
88  pub fn get(&self, key: T) -> Option<&V> {
89    self.get_by_index(key.into())
90  }
91
92  /// Returns a mutable reference to the value associated with a given index,
93  /// or `None` if the index is beyond the end of the vector.
94  #[inline]
95  pub fn get_by_index_mut(&mut self, index: EnumIndex<T>) -> Option<&mut V> {
96    self.as_slice_mut().get_mut(index.into_usize())
97  }
98
99  /// Returns a mutable reference to the value associated with a given key,
100  /// or `None` if the key is beyond the end of the vector.
101  #[inline]
102  pub fn get_mut(&mut self, key: T) -> Option<&mut V> {
103    self.get_by_index_mut(key.into())
104  }
105
106  /// Returns true if the vector is empty.
107  #[inline]
108  pub fn is_empty(&self) -> bool {
109    self.len == T::Word::ZERO
110  }
111
112  /// Returns true if the vector is fully populated.
113  #[inline]
114  pub fn is_full(&self) -> bool {
115    self.len == T::SIZE_WORD
116  }
117
118  /// Returns true if the vector contains the index.
119  #[inline]
120  pub fn contains_index(&self, index: EnumIndex<T>) -> bool {
121    index.into_word() < self.len
122  }
123
124  /// Returns true if the vector contains the key.
125  #[inline]
126  pub fn contains(&self, value: T) -> bool {
127    value.into_word() < self.len
128  }
129
130  /// Returns the size of the vector.
131  #[inline]
132  pub fn size(&self) -> EnumSize<T> {
133    unsafe { EnumSize::from_word_unchecked(self.len) }
134  }
135
136  /// Swaps two elements in the vector.
137  ///
138  /// # Panics
139  /// Panics if `a` or `b` are beyond the end of the vector.
140  pub fn swap(&mut self, a: T, b: T) {
141    self
142      .as_slice_mut()
143      .swap(T::into_word(a).as_(), T::into_word(b).as_())
144  }
145
146  /// Removes an element and returns it, replacing it with the last element.
147  pub fn swap_remove(&mut self, key: T) -> Option<V> {
148    let index = T::into_word(key).as_();
149    if index < self.len.as_() {
150      let slice = T::partial_slice_mut(&mut self.data);
151      self.len = self.len.dec();
152      unsafe {
153        let value = slice[index].assume_init_read();
154        slice[index].write(slice[self.len.as_()].assume_init_read());
155        Some(value)
156      }
157    } else {
158      None
159    }
160  }
161
162  /// Removes an element and returns it.
163  pub fn remove(&mut self, key: T) -> Option<V> {
164    let index = T::into_word(key).as_();
165    if index < self.len.as_() {
166      let slice = T::partial_slice_mut(&mut self.data);
167      let value = unsafe {
168        let value = slice[index].assume_init_read();
169        let ptr = slice.as_mut_ptr().add(index);
170        ptr::copy(ptr.add(1), ptr, self.len.as_() - index - 1);
171        value
172      };
173      self.len = self.len.dec();
174      Some(value)
175    } else {
176      None
177    }
178  }
179
180  /// Clears all the elements from the vector.
181  pub fn clear(&mut self) {
182    for cell in
183      T::partial_slice_mut(&mut self.data)[0..self.len.as_()].iter_mut()
184    {
185      unsafe { cell.assume_init_drop() };
186    }
187    self.len = T::Word::ZERO;
188  }
189
190  /// Adds an element to the end of the vector.
191  ///
192  /// # Panics
193  /// Panics if the vector is already full.
194  pub fn push(&mut self, value: V) {
195    let len = self.len.as_();
196    T::partial_slice_mut(&mut self.data)[len] =
197      mem::MaybeUninit::<V>::new(value);
198    self.len = self.len.inc();
199  }
200
201  /// Removes an element from the end of the vector and returns it,
202  /// or `None` if the vector is empty.
203  pub fn pop(&mut self) -> Option<V> {
204    if self.len == T::Word::ZERO {
205      None
206    } else {
207      let i = self.len.as_() - 1;
208      let cell = &T::partial_slice_mut(&mut self.data)[i];
209      self.len = self.len.dec();
210      Some(unsafe { cell.assume_init_read() })
211    }
212  }
213
214  /// Returns an iterator over the keys and elements.
215  #[inline]
216  pub fn iter(&self) -> EnumSliceIter<T, V> {
217    EnumSliceIter {
218      _phantom: Default::default(),
219      word: T::Word::ZERO,
220      iter: self.as_slice().iter(),
221    }
222  }
223
224  /// Returns a mutable iterator over the keys and elements.
225  #[inline]
226  pub fn iter_mut(&mut self) -> EnumSliceIterMut<T, V> {
227    EnumSliceIterMut {
228      _phantom: Default::default(),
229      word: T::Word::ZERO,
230      iter: self.as_slice_mut().iter_mut(),
231    }
232  }
233}
234
235impl<T: EnumArrayHelper<V> + Debug, V: Debug> Debug for EnumVec<T, V> {
236  fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
237    fmt.debug_map().entries(self.iter()).finish()
238  }
239}
240
241impl<T: EnumArrayHelper<V>, V> Default for EnumVec<T, V> {
242  fn default() -> Self {
243    Self::new()
244  }
245}
246
247impl<T: EnumArrayHelper<V>, V> Drop for EnumVec<T, V> {
248  fn drop(&mut self) {
249    self.clear()
250  }
251}
252
253impl<T: EnumArrayHelper<V>, V: Clone> Clone for EnumVec<T, V> {
254  fn clone(&self) -> Self {
255    let mut clone = Self::new();
256    for (_, value) in self.iter() {
257      clone.push(value.clone())
258    }
259    clone
260  }
261}
262
263impl<T: EnumArrayHelper<V>, V: PartialEq> PartialEq for EnumVec<T, V> {
264  fn eq(&self, other: &Self) -> bool {
265    self.as_slice() == other.as_slice()
266  }
267}
268
269impl<T: EnumArrayHelper<V>, V: Eq> Eq for EnumVec<T, V> {}
270
271impl<T: EnumArrayHelper<V>, V: Hash> Hash for EnumVec<T, V> {
272  fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
273    self.as_slice().hash(state);
274  }
275}
276
277impl<T: EnumArrayHelper<V>, V> Index<EnumIndex<T>> for EnumVec<T, V> {
278  type Output = V;
279
280  #[inline]
281  fn index(&self, index: EnumIndex<T>) -> &V {
282    &self.as_slice()[index.into_usize()]
283  }
284}
285
286impl<T: EnumArrayHelper<V>, V> Index<T> for EnumVec<T, V> {
287  type Output = V;
288
289  #[inline]
290  fn index(&self, key: T) -> &V {
291    &self[EnumIndex::from_value(key)]
292  }
293}
294
295impl<T: EnumArrayHelper<V>, V> IndexMut<EnumIndex<T>> for EnumVec<T, V> {
296  #[inline]
297  fn index_mut(&mut self, index: EnumIndex<T>) -> &mut V {
298    &mut self.as_slice_mut()[index.into_usize()]
299  }
300}
301
302impl<T: EnumArrayHelper<V>, V> IndexMut<T> for EnumVec<T, V> {
303  #[inline]
304  fn index_mut(&mut self, key: T) -> &mut V {
305    &mut self[EnumIndex::from_value(key)]
306  }
307}
308
309impl<T: EnumArrayHelper<V>, V> iter::FromIterator<V> for EnumVec<T, V> {
310  fn from_iter<I: iter::IntoIterator<Item = V>>(iter: I) -> Self {
311    let mut c = EnumVec::<T, V>::new();
312    for i in iter {
313      c.push(i);
314    }
315    c
316  }
317}
318
319impl<'a, T: EnumArrayHelper<V>, V> iter::IntoIterator for &'a EnumVec<T, V> {
320  type Item = (T, &'a V);
321  type IntoIter = EnumSliceIter<'a, T, V>;
322
323  #[inline]
324  fn into_iter(self) -> Self::IntoIter {
325    self.iter()
326  }
327}
328
329impl<T: EnumArrayHelper<V> + EnumSetHelper<u8>, V> TryFrom<EnumOptionMap<T, V>>
330  for EnumVec<T, V>
331{
332  type Error = ();
333  fn try_from(from: EnumOptionMap<T, V>) -> Result<Self, Self::Error> {
334    match from.is_vec() {
335      Some(size) => Ok(EnumVec {
336        len: size.into_word(),
337        data: from.into_partial(),
338      }),
339      None => Err(()),
340    }
341  }
342}