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
18pub 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 pub fn new() -> Self {
27 EnumVec {
28 len: T::Word::ZERO,
29 data: T::new_partial(),
30 }
31 }
32
33 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 #[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 #[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 #[inline]
81 pub fn get_by_index(&self, index: EnumIndex<T>) -> Option<&V> {
82 self.as_slice().get(index.into_usize())
83 }
84
85 #[inline]
88 pub fn get(&self, key: T) -> Option<&V> {
89 self.get_by_index(key.into())
90 }
91
92 #[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 #[inline]
102 pub fn get_mut(&mut self, key: T) -> Option<&mut V> {
103 self.get_by_index_mut(key.into())
104 }
105
106 #[inline]
108 pub fn is_empty(&self) -> bool {
109 self.len == T::Word::ZERO
110 }
111
112 #[inline]
114 pub fn is_full(&self) -> bool {
115 self.len == T::SIZE_WORD
116 }
117
118 #[inline]
120 pub fn contains_index(&self, index: EnumIndex<T>) -> bool {
121 index.into_word() < self.len
122 }
123
124 #[inline]
126 pub fn contains(&self, value: T) -> bool {
127 value.into_word() < self.len
128 }
129
130 #[inline]
132 pub fn size(&self) -> EnumSize<T> {
133 unsafe { EnumSize::from_word_unchecked(self.len) }
134 }
135
136 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 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 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 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 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 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 #[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 #[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}