flex_alloc/vec/
buffer.rs

1//! `Vec` buffer types and trait definitions.
2
3use core::alloc::Layout;
4use core::fmt::Debug;
5use core::mem::MaybeUninit;
6use core::ptr::NonNull;
7use core::slice;
8
9use crate::alloc::Allocator;
10use crate::capacity::Index;
11use crate::error::StorageError;
12use crate::storage::{BufferHeader, FatBuffer, InlineBuffer, RawBuffer, ThinBuffer};
13
14/// The header associated with each `Vec` instance.
15#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
16pub struct VecHeader<I: Index = usize> {
17    /// The capacity of the buffer.
18    pub capacity: I,
19    /// The number of items stored in the buffer.
20    pub length: I,
21}
22
23impl<T, I: Index> BufferHeader<T> for VecHeader<I> {
24    const EMPTY: Self = VecHeader {
25        capacity: I::ZERO,
26        length: I::ZERO,
27    };
28
29    #[inline]
30    fn is_empty(&self) -> bool {
31        self.capacity == I::ZERO
32    }
33
34    #[inline]
35    fn layout(&self) -> Result<Layout, core::alloc::LayoutError> {
36        Layout::array::<T>(self.capacity.to_usize())
37    }
38
39    #[inline]
40    fn update_for_alloc(&mut self, ptr: NonNull<[u8]>, exact: bool) -> NonNull<T> {
41        if !exact {
42            let t_size = size_of::<T>();
43            self.capacity = if t_size > 0 {
44                I::from_usize((ptr.len() / t_size).min(I::MAX_USIZE))
45            } else {
46                I::from_usize(I::MAX_USIZE)
47            };
48        }
49        ptr.cast()
50    }
51}
52
53/// An abstract type which captures the parameters of a `Vec` type's data representation.
54#[derive(Debug)]
55pub struct VecData<T, I: Index = usize>(T, I);
56
57/// A concrete `Vec` backing buffer.
58pub trait VecBuffer: RawBuffer<RawData = Self::Item> {
59    /// The type of the items stored in the `Vec`.
60    type Item;
61
62    /// The index type used to store the capacity and length.
63    type Index: Index;
64
65    /// Access the capacity of the buffer.
66    fn capacity(&self) -> Self::Index;
67
68    /// Access the number of items stored in the buffer.
69    fn length(&self) -> Self::Index;
70
71    /// Set the current length of the buffer.
72    ///
73    /// # Safety
74    /// A zero length buffer may not have an active allocation, and so it is
75    /// undefined behavior to set its length, even if setting it to zero. Doing so
76    /// may produce invalid memory access errors.
77    unsafe fn set_length(&mut self, len: Self::Index);
78
79    /// Access the contiguous memory contained in this buffer as a slice of
80    /// `MaybeUnint<Self::Item>`. The length of this slice must correspond to
81    /// `self.capacity()`.
82    #[inline]
83    fn as_uninit_slice(&mut self) -> &mut [MaybeUninit<Self::Item>] {
84        unsafe { slice::from_raw_parts_mut(self.data_ptr_mut().cast(), self.capacity().to_usize()) }
85    }
86
87    /// Access the items contained in this buffer as a slice of `Self::Item`. The length
88    /// of this slice must correspond to `self.length()`.
89    #[inline]
90    fn as_slice(&self) -> &[Self::Item] {
91        unsafe { slice::from_raw_parts(self.data_ptr(), self.length().to_usize()) }
92    }
93
94    /// Access the items contained in this buffer as a mutable slice of `Self::Item`. The
95    /// length of this slice must correspond to `self.length()`.
96    #[inline]
97    fn as_mut_slice(&mut self) -> &mut [Self::Item] {
98        unsafe { slice::from_raw_parts_mut(self.data_ptr_mut(), self.length().to_usize()) }
99    }
100
101    /// Access an index of the buffer as a mutable reference to a `MaybeUninit<Self::Item>`.
102    ///
103    /// # Safety
104    /// The index must be within the bounds of the buffer's capacity, otherwise a
105    /// memory access error may occur.
106    #[inline]
107    unsafe fn uninit_index(&mut self, index: usize) -> &mut MaybeUninit<Self::Item> {
108        &mut *self.data_ptr_mut().add(index).cast()
109    }
110
111    /// Attempt to resize this buffer to a new capacity. The `exact` flag determines
112    /// whether a larger capacity would be acceptable.
113    fn grow_buffer(&mut self, capacity: Self::Index, exact: bool) -> Result<(), StorageError>;
114
115    /// Attempt to resize this buffer to a new, smaller capacity.
116    fn shrink_buffer(&mut self, capacity: Self::Index) -> Result<(), StorageError>;
117}
118
119impl<T, I: Index, A: Allocator> VecBuffer for FatBuffer<T, VecHeader<I>, A> {
120    type Item = T;
121    type Index = I;
122
123    #[inline]
124    fn capacity(&self) -> I {
125        self.header.capacity
126    }
127
128    #[inline]
129    fn length(&self) -> I {
130        self.header.length
131    }
132
133    #[inline]
134    unsafe fn set_length(&mut self, len: I) {
135        self.header.length = len;
136    }
137
138    #[inline]
139    fn grow_buffer(&mut self, capacity: Self::Index, exact: bool) -> Result<(), StorageError> {
140        let length = self.length();
141        self.grow(VecHeader { capacity, length }, exact)?;
142        Ok(())
143    }
144
145    #[inline]
146    fn shrink_buffer(&mut self, capacity: Self::Index) -> Result<(), StorageError> {
147        let length = self.length();
148        self.shrink(VecHeader { capacity, length })?;
149        Ok(())
150    }
151}
152
153impl<T, I: Index, A: Allocator> VecBuffer for ThinBuffer<T, VecHeader<I>, A> {
154    type Item = T;
155    type Index = I;
156
157    #[inline]
158    fn capacity(&self) -> I {
159        self.header().capacity
160    }
161
162    #[inline]
163    fn length(&self) -> I {
164        self.header().length
165    }
166
167    #[inline]
168    unsafe fn set_length(&mut self, len: I) {
169        self.set_header(VecHeader {
170            capacity: self.capacity(),
171            length: len,
172        });
173    }
174
175    #[inline]
176    fn grow_buffer(&mut self, capacity: Self::Index, exact: bool) -> Result<(), StorageError> {
177        let length = self.length();
178        self.grow(VecHeader { capacity, length }, exact)?;
179        Ok(())
180    }
181
182    #[inline]
183    fn shrink_buffer(&mut self, capacity: Self::Index) -> Result<(), StorageError> {
184        let length = self.length();
185        self.shrink(VecHeader { capacity, length })?;
186        Ok(())
187    }
188}
189
190impl<'a, T: 'a, const N: usize> VecBuffer for InlineBuffer<T, N> {
191    type Item = T;
192    type Index = usize;
193
194    #[inline]
195    fn capacity(&self) -> usize {
196        N
197    }
198
199    #[inline]
200    fn length(&self) -> usize {
201        self.length
202    }
203
204    #[inline]
205    unsafe fn set_length(&mut self, len: usize) {
206        self.length = len;
207    }
208
209    #[inline]
210    fn grow_buffer(&mut self, capacity: Self::Index, exact: bool) -> Result<(), StorageError> {
211        if (!exact && capacity.to_usize() < N) || capacity.to_usize() == N {
212            Ok(())
213        } else {
214            Err(StorageError::CapacityLimit)
215        }
216    }
217
218    #[inline]
219    fn shrink_buffer(&mut self, _capacity: Self::Index) -> Result<(), StorageError> {
220        Ok(())
221    }
222}