Skip to main content

bump_scope/fixed_bump_vec/
raw.rs

1use 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/// Like [`FixedBumpVec`] but without its lifetime.
16#[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    /// `new_cap` must be greater than `self.capacity`
78    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}