rune/shared/
fixed_vec.rs
1use core::mem::{self, ManuallyDrop, MaybeUninit};
2use core::ops::{Deref, DerefMut};
3use core::ptr;
4use core::slice;
5
6use crate::alloc;
7
8pub(crate) struct FixedVec<T, const N: usize> {
10 data: [MaybeUninit<T>; N],
11 len: usize,
12}
13
14impl<T, const N: usize> FixedVec<T, N> {
15 pub(crate) const fn new() -> FixedVec<T, N> {
17 unsafe {
18 FixedVec {
19 data: MaybeUninit::uninit().assume_init(),
20 len: 0,
21 }
22 }
23 }
24
25 #[inline]
26 pub(crate) fn as_ptr(&self) -> *const T {
27 self.data.as_ptr() as *const T
28 }
29
30 #[inline]
31 pub(crate) fn as_mut_ptr(&mut self) -> *mut T {
32 self.data.as_mut_ptr() as *mut T
33 }
34
35 #[inline]
36 pub(crate) fn as_slice(&self) -> &[T] {
37 unsafe { slice::from_raw_parts(self.as_ptr(), self.len) }
38 }
39
40 #[inline]
41 pub(crate) fn as_mut_slice(&mut self) -> &mut [T] {
42 unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) }
43 }
44
45 pub(crate) fn try_push(&mut self, element: T) -> alloc::Result<()> {
47 if self.len >= N {
48 return Err(alloc::Error::CapacityOverflow);
49 }
50
51 unsafe {
52 ptr::write(self.as_mut_ptr().wrapping_add(self.len), element);
53 self.len += 1;
54 }
55
56 Ok(())
57 }
58
59 pub(crate) fn clear(&mut self) {
60 if self.len == 0 {
61 return;
62 }
63
64 let len = mem::take(&mut self.len);
65
66 if mem::needs_drop::<T>() {
67 unsafe {
68 let tail = slice::from_raw_parts_mut(self.as_mut_ptr(), len);
69 ptr::drop_in_place(tail);
70 }
71 }
72 }
73
74 pub(crate) fn into_inner(self) -> [T; N] {
76 let len = self.len;
77
78 let Some(array) = self.try_into_inner() else {
79 panic!("into_inner: length mismatch, expected {N} but got {len}");
80 };
81
82 array
83 }
84
85 pub(crate) fn try_into_inner(self) -> Option<[T; N]> {
87 if self.len != N {
88 return None;
89 }
90
91 unsafe {
93 let this = ManuallyDrop::new(self);
94 Some(ptr::read(this.data.as_ptr() as *const [T; N]))
95 }
96 }
97}
98
99impl<T, const N: usize> Deref for FixedVec<T, N> {
100 type Target = [T];
101
102 #[inline]
103 fn deref(&self) -> &Self::Target {
104 self.as_slice()
105 }
106}
107
108impl<T, const N: usize> DerefMut for FixedVec<T, N> {
109 #[inline]
110 fn deref_mut(&mut self) -> &mut Self::Target {
111 self.as_mut_slice()
112 }
113}
114
115impl<T, const N: usize> Drop for FixedVec<T, N> {
116 #[inline]
117 fn drop(&mut self) {
118 self.clear()
119 }
120}