bump_scope/
raw_fixed_bump_vec.rs1use core::{
2 mem::transmute,
3 ptr::{self, NonNull},
4};
5
6use crate::{
7 BumpAllocatorExt, FixedBumpVec, MutBumpAllocatorExt, SizedTypeProperties,
8 error_behavior::ErrorBehavior,
9 polyfill::{non_null, transmute_mut, transmute_ref},
10 raw_bump_box::RawBumpBox,
11 set_len_on_drop_by_ptr::SetLenOnDropByPtr,
12};
13
14#[repr(C)]
16pub struct RawFixedBumpVec<T> {
17 initialized: RawBumpBox<[T]>,
18 capacity: usize,
19}
20
21impl<T> RawFixedBumpVec<T> {
22 pub(crate) const EMPTY: Self = RawFixedBumpVec {
23 initialized: RawBumpBox::EMPTY,
24 capacity: if T::IS_ZST { usize::MAX } else { 0 },
25 };
26
27 pub(crate) const unsafe fn new_zst(len: usize) -> Self {
28 assert!(T::IS_ZST);
29
30 RawFixedBumpVec {
31 initialized: unsafe { RawBumpBox::from_ptr(NonNull::slice_from_raw_parts(NonNull::dangling(), len)) },
32 capacity: usize::MAX,
33 }
34 }
35
36 #[inline(always)]
37 pub(crate) const unsafe fn cook<'a>(self) -> FixedBumpVec<'a, T> {
38 unsafe { transmute(self) }
39 }
40
41 #[inline(always)]
42 pub(crate) const unsafe fn cook_ref<'a>(&self) -> &FixedBumpVec<'a, T> {
43 unsafe { transmute_ref(self) }
44 }
45
46 #[inline(always)]
47 pub(crate) unsafe fn cook_mut<'a>(&mut self) -> &mut FixedBumpVec<'a, T> {
48 unsafe { transmute_mut(self) }
49 }
50
51 #[inline(always)]
52 pub(crate) unsafe fn from_cooked(cooked: FixedBumpVec<'_, T>) -> Self {
53 unsafe {
54 let (initialized, capacity) = cooked.into_raw_parts();
55 let initialized = RawBumpBox::from_cooked(initialized);
56 Self { initialized, capacity }
57 }
58 }
59
60 #[inline(always)]
61 pub(crate) unsafe fn allocate<B: ErrorBehavior>(allocator: &impl BumpAllocatorExt, len: usize) -> Result<Self, B> {
62 let ptr = B::allocate_slice::<T>(allocator, len)?;
63
64 Ok(Self {
65 initialized: unsafe { RawBumpBox::from_ptr(NonNull::slice_from_raw_parts(ptr, 0)) },
66 capacity: len,
67 })
68 }
69
70 #[inline(always)]
71 pub(crate) unsafe fn prepare_allocation<B: ErrorBehavior>(
72 allocator: &mut impl MutBumpAllocatorExt,
73 len: usize,
74 ) -> Result<Self, B> {
75 unsafe {
76 let allocation = B::prepare_slice_allocation::<T>(allocator, len)?;
77
78 Ok(Self {
79 initialized: RawBumpBox::from_ptr(NonNull::slice_from_raw_parts(non_null::as_non_null_ptr(allocation), 0)),
80 capacity: allocation.len(),
81 })
82 }
83 }
84
85 pub(crate) unsafe fn grow_prepared_allocation<B: ErrorBehavior>(
87 &mut self,
88 allocator: &mut impl MutBumpAllocatorExt,
89 minimum_new_cap: usize,
90 ) -> Result<(), B> {
91 unsafe {
92 debug_assert!(minimum_new_cap > self.capacity);
93 let allocation = B::prepare_slice_allocation::<T>(allocator, minimum_new_cap)?;
94
95 let new_ptr = allocation.cast::<T>();
96 let new_cap = allocation.len();
97
98 ptr::copy_nonoverlapping(self.as_ptr(), new_ptr.as_ptr(), self.len());
99
100 self.initialized.set_ptr(new_ptr);
101 self.capacity = new_cap;
102
103 Ok(())
104 }
105 }
106
107 #[inline(always)]
108 pub(crate) const fn len(&self) -> usize {
109 self.initialized.len()
110 }
111
112 #[inline(always)]
113 pub(crate) const fn capacity(&self) -> usize {
114 self.capacity
115 }
116
117 #[inline(always)]
118 pub(crate) fn as_ptr(&self) -> *const T {
119 self.initialized.as_ptr().cast()
120 }
121
122 #[inline(always)]
123 pub(crate) fn as_mut_ptr(&mut self) -> *mut T {
124 self.initialized.as_mut_ptr().cast()
125 }
126
127 #[must_use]
128 #[inline(always)]
129 pub const fn as_non_null(&self) -> NonNull<T> {
130 self.initialized.as_non_null().cast()
131 }
132
133 #[doc(hidden)]
134 #[deprecated = "too niche; compute this yourself if needed"]
135 #[must_use]
136 #[inline(always)]
137 pub fn as_non_null_slice(&self) -> NonNull<[T]> {
138 self.initialized.as_non_null()
139 }
140
141 #[inline(always)]
142 pub(crate) unsafe fn set_ptr(&mut self, new_ptr: NonNull<T>) {
143 unsafe { self.initialized.set_ptr(new_ptr) };
144 }
145
146 #[inline(always)]
147 pub(crate) unsafe fn set_len(&mut self, new_len: usize) {
148 unsafe { self.initialized.set_len(new_len) };
149 }
150
151 #[inline(always)]
152 pub(crate) unsafe fn set_cap(&mut self, new_cap: usize) {
153 self.capacity = new_cap;
154 }
155
156 #[inline(always)]
157 pub(crate) unsafe fn set_len_on_drop(&mut self) -> SetLenOnDropByPtr<'_, T> {
158 SetLenOnDropByPtr::new(&mut self.initialized.ptr)
159 }
160
161 #[inline(always)]
162 pub(crate) fn into_raw_parts(self) -> (NonNull<[T]>, usize) {
163 let Self { initialized, capacity } = self;
164 (initialized.into_ptr(), capacity)
165 }
166
167 #[inline(always)]
168 pub(crate) unsafe fn from_raw_parts(slice: NonNull<[T]>, capacity: usize) -> Self {
169 Self {
170 initialized: unsafe { RawBumpBox::from_ptr(slice) },
171 capacity,
172 }
173 }
174}