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