1use crate::EnumIndex;
2use crate::base::EnumArrayHelper;
3use crate::base::EnumSetHelper;
4use crate::base::EnumSize;
5use crate::iter::EnumSliceIter;
6use crate::iter::EnumSliceIterMut;
7use crate::opt_map::EnumOptionMap;
8use crate::sub_base::RawSizeWord;
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 let _ = vec.try_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 #[inline]
141 pub fn swap_by_index(&mut self, a: EnumIndex<T>, b: EnumIndex<T>) {
142 self.as_slice_mut().swap(a.into_usize(), b.into_usize())
143 }
144
145 #[inline]
150 pub fn swap(&mut self, a: T, b: T) {
151 self.swap_by_index(a.into(), b.into())
152 }
153
154 pub fn swap_remove_at_index(&mut self, index: EnumIndex<T>) -> Option<V> {
156 if index.into_word() < self.len {
157 let slice = T::partial_slice_mut(&mut self.data);
158 self.len = self.len.dec();
159 let idx = index.into_usize();
160 unsafe {
161 let value = slice[idx].assume_init_read();
162 if idx != self.len.as_() {
163 slice[idx].write(slice[self.len.as_()].assume_init_read());
164 }
165 Some(value)
166 }
167 } else {
168 None
169 }
170 }
171
172 pub fn swap_remove(&mut self, key: T) -> Option<V> {
174 self.swap_remove_at_index(key.into())
175 }
176
177 pub fn remove_at_index(&mut self, index: EnumIndex<T>) -> Option<V> {
179 if index.into_word() < self.len {
180 let slice = T::partial_slice_mut(&mut self.data);
181 let idx = index.into_usize();
182 let value = unsafe {
183 let value = slice[idx].assume_init_read();
184 let ptr = slice.as_mut_ptr().add(idx);
185 ptr::copy(ptr.add(1), ptr, self.len.as_() - idx - 1);
186 value
187 };
188 self.len = self.len.dec();
189 Some(value)
190 } else {
191 None
192 }
193 }
194
195 pub fn remove(&mut self, key: T) -> Option<V> {
197 self.remove_at_index(key.into())
198 }
199
200 pub fn clear(&mut self) {
202 for cell in
203 T::partial_slice_mut(&mut self.data)[0..self.len.as_()].iter_mut()
204 {
205 unsafe { cell.assume_init_drop() };
206 }
207 self.len = T::Word::ZERO;
208 }
209
210 pub fn try_push(&mut self, value: V) -> Result<(), V> {
212 let len = self.len.as_();
213 if len >= T::SIZE {
214 return Err(value);
215 }
216 T::partial_slice_mut(&mut self.data)[len] =
217 mem::MaybeUninit::<V>::new(value);
218 self.len = self.len.inc();
219 Ok(())
220 }
221
222 pub fn pop(&mut self) -> Option<V> {
225 if self.len == T::Word::ZERO {
226 None
227 } else {
228 let i = self.len.as_() - 1;
229 let cell = &T::partial_slice_mut(&mut self.data)[i];
230 self.len = self.len.dec();
231 Some(unsafe { cell.assume_init_read() })
232 }
233 }
234
235 #[inline]
237 pub fn iter(&self) -> EnumSliceIter<'_, T, V> {
238 EnumSliceIter {
239 _phantom: Default::default(),
240 word: T::Word::ZERO,
241 iter: self.as_slice().iter(),
242 }
243 }
244
245 #[inline]
247 pub fn iter_mut(&mut self) -> EnumSliceIterMut<'_, T, V> {
248 EnumSliceIterMut {
249 _phantom: Default::default(),
250 word: T::Word::ZERO,
251 iter: self.as_slice_mut().iter_mut(),
252 }
253 }
254}
255
256impl<T: EnumArrayHelper<V> + Debug, V: Debug> Debug for EnumVec<T, V> {
257 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
258 fmt.debug_map().entries(self.iter()).finish()
259 }
260}
261
262impl<T: EnumArrayHelper<V>, V> Default for EnumVec<T, V> {
263 fn default() -> Self {
264 Self::new()
265 }
266}
267
268impl<T: EnumArrayHelper<V>, V> Drop for EnumVec<T, V> {
269 fn drop(&mut self) {
270 self.clear()
271 }
272}
273
274impl<T: EnumArrayHelper<V>, V: Clone> Clone for EnumVec<T, V> {
275 fn clone(&self) -> Self {
276 let mut clone = Self::new();
277 for value in self.as_slice() {
278 let _ = clone.try_push(value.clone());
279 }
280 clone
281 }
282}
283
284impl<T: EnumArrayHelper<V>, V: PartialEq> PartialEq for EnumVec<T, V> {
285 fn eq(&self, other: &Self) -> bool {
286 self.as_slice() == other.as_slice()
287 }
288}
289
290impl<T: EnumArrayHelper<V>, V: Eq> Eq for EnumVec<T, V> {}
291
292impl<T: EnumArrayHelper<V>, V: Hash> Hash for EnumVec<T, V> {
293 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
294 self.as_slice().hash(state);
295 }
296}
297
298impl<T: EnumArrayHelper<V>, V> Index<EnumIndex<T>> for EnumVec<T, V> {
299 type Output = V;
300
301 #[inline]
302 fn index(&self, index: EnumIndex<T>) -> &V {
303 &self.as_slice()[index.into_usize()]
304 }
305}
306
307impl<T: EnumArrayHelper<V>, V> Index<T> for EnumVec<T, V> {
308 type Output = V;
309
310 #[inline]
311 fn index(&self, key: T) -> &V {
312 &self[EnumIndex::from_value(key)]
313 }
314}
315
316impl<T: EnumArrayHelper<V>, V> IndexMut<EnumIndex<T>> for EnumVec<T, V> {
317 #[inline]
318 fn index_mut(&mut self, index: EnumIndex<T>) -> &mut V {
319 &mut self.as_slice_mut()[index.into_usize()]
320 }
321}
322
323impl<T: EnumArrayHelper<V>, V> IndexMut<T> for EnumVec<T, V> {
324 #[inline]
325 fn index_mut(&mut self, key: T) -> &mut V {
326 &mut self[EnumIndex::from_value(key)]
327 }
328}
329
330impl<T: EnumArrayHelper<V>, V> iter::FromIterator<V> for EnumVec<T, V> {
331 fn from_iter<I: iter::IntoIterator<Item = V>>(iter: I) -> Self {
332 let mut c = EnumVec::<T, V>::new();
333 for i in iter {
334 if c.try_push(i).is_err() {
335 break;
336 }
337 }
338 c
339 }
340}
341
342impl<T: EnumArrayHelper<V>, V> iter::Extend<V> for EnumVec<T, V> {
343 fn extend<I: iter::IntoIterator<Item = V>>(&mut self, iter: I) {
344 for i in iter {
345 if self.try_push(i).is_err() {
346 break;
347 }
348 }
349 }
350}
351
352impl<'a, T: EnumArrayHelper<V>, V> iter::IntoIterator for &'a EnumVec<T, V> {
353 type Item = (T, &'a V);
354 type IntoIter = EnumSliceIter<'a, T, V>;
355
356 #[inline]
357 fn into_iter(self) -> Self::IntoIter {
358 self.iter()
359 }
360}
361
362impl<'a, T: EnumArrayHelper<V>, V> iter::IntoIterator
363 for &'a mut EnumVec<T, V>
364{
365 type Item = (T, &'a mut V);
366 type IntoIter = EnumSliceIterMut<'a, T, V>;
367
368 #[inline]
369 fn into_iter(self) -> Self::IntoIter {
370 self.iter_mut()
371 }
372}
373
374impl<T: EnumArrayHelper<V>, V> iter::IntoIterator for EnumVec<T, V> {
375 type Item = V;
376 type IntoIter = EnumVecIntoIter<T, V>;
377
378 #[inline]
379 fn into_iter(self) -> Self::IntoIter {
380 let mut this = mem::ManuallyDrop::new(self);
382 let len = this.len;
383 let data = mem::replace(&mut this.data, T::new_partial());
384 EnumVecIntoIter {
385 data,
386 front: T::Word::ZERO,
387 back: len,
388 }
389 }
390}
391
392pub struct EnumVecIntoIter<T: EnumArrayHelper<V>, V> {
399 data: T::PartialArray,
400 front: T::Word,
401 back: T::Word,
402}
403
404impl<T: EnumArrayHelper<V>, V> Iterator for EnumVecIntoIter<T, V> {
405 type Item = V;
406
407 fn next(&mut self) -> Option<Self::Item> {
408 if self.front == self.back {
409 return None;
410 }
411 let value = unsafe {
412 T::partial_slice_mut(&mut self.data)[self.front.as_()].assume_init_read()
413 };
414 self.front = self.front.inc();
415 Some(value)
416 }
417
418 fn size_hint(&self) -> (usize, Option<usize>) {
419 let remaining = self.back.as_() - self.front.as_();
420 (remaining, Some(remaining))
421 }
422}
423
424impl<T: EnumArrayHelper<V>, V> DoubleEndedIterator for EnumVecIntoIter<T, V> {
425 fn next_back(&mut self) -> Option<Self::Item> {
426 if self.front == self.back {
427 return None;
428 }
429 self.back = self.back.dec();
430 let value = unsafe {
431 T::partial_slice_mut(&mut self.data)[self.back.as_()].assume_init_read()
432 };
433 Some(value)
434 }
435}
436
437impl<T: EnumArrayHelper<V>, V> ExactSizeIterator for EnumVecIntoIter<T, V> {}
438
439impl<T: EnumArrayHelper<V>, V> iter::FusedIterator for EnumVecIntoIter<T, V> {}
440
441impl<T: EnumArrayHelper<V>, V> Drop for EnumVecIntoIter<T, V> {
442 fn drop(&mut self) {
443 let slice = T::partial_slice_mut(&mut self.data);
444 for cell in slice[self.front.as_()..self.back.as_()].iter_mut() {
445 unsafe { cell.assume_init_drop() };
446 }
447 }
448}
449
450impl<T: EnumArrayHelper<V> + EnumSetHelper<u8>, V> TryFrom<EnumOptionMap<T, V>>
451 for EnumVec<T, V>
452{
453 type Error = ();
454 fn try_from(from: EnumOptionMap<T, V>) -> Result<Self, Self::Error> {
455 match from.is_vec() {
456 Some(size) => Ok(EnumVec {
457 len: size.into_word(),
458 data: from.into_partial(),
459 }),
460 None => Err(()),
461 }
462 }
463}