any_vec/mem/
mod.rs

1#[cfg(feature="alloc")]
2mod heap;
3mod stack;
4mod stack_n;
5mod empty;
6
7#[cfg(feature="alloc")]
8#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
9pub use heap::Heap;
10pub use stack::Stack;
11pub use stack_n::StackN;
12pub use empty::Empty;
13
14#[cfg(feature="alloc")]
15pub(crate) type Default = Heap;
16#[cfg(not(feature="alloc"))]
17pub(crate) type Default = Empty;
18
19use core::alloc::Layout;
20use core::ptr::NonNull;
21
22/// This is [`Mem`] builder.
23///
24/// It can be stateful. You can use it like Allocator.
25/// Making `MemBuilder` default constructible, allow to use [`AnyVec::new`], without that you
26/// limited to [`AnyVec::new_in`].
27///
28/// [`AnyVec::new`]: crate::AnyVec::new
29/// [`AnyVec::new_in`]: crate::AnyVec::new_in
30pub trait MemBuilder: Clone {
31    type Mem: Mem;
32    fn build(&mut self, element_layout: Layout) -> Self::Mem;
33}
34
35/// This allows to use [`AnyVec::with_capacity`] with it.
36///
37/// [`AnyVec::with_capacity`]: crate::AnyVec::with_capacity
38pub trait MemBuilderSizeable: MemBuilder{
39    fn build_with_size(&mut self, element_layout: Layout, capacity: usize) -> Self::Mem;
40}
41
42/// Interface for [`AnyVec`] memory chunk.
43///
44/// Responsible for allocation, dealocation, reallocation of the memory chunk.
45/// Constructed through [`MemBuilder`].
46///
47/// _`Mem` is fixed capacity memory. Implement [`MemResizable`] if you want it
48/// to be resizable._
49///
50/// [`AnyVec`]: crate::AnyVec
51pub trait Mem{
52    fn as_ptr(&self) -> *const u8;
53
54    fn as_mut_ptr(&mut self) -> *mut u8;
55
56    /// Aligned.
57    fn element_layout(&self) -> Layout;
58
59    /// In elements.
60    fn size(&self) -> usize;
61
62    /// Expand `Mem` size for **at least** `additional` more elements.
63    /// Implementation encouraged to avoid frequent reallocations.
64    ///
65    /// # Notes
66    ///
67    /// Consider, that `expand` is in [`MemResizable`].
68    /// Implement this only if your type [`MemResizable`].
69    ///
70    /// It's here, only due to technical reasons (see `AnyVecRaw::reserve`).
71    /// _Rust does not support specialization_
72    ///
73    /// # Panics
74    ///
75    /// Implementation may panic, if fail to allocate/reallocate memory.
76    fn expand(&mut self, additional: usize){
77        let _ = additional;
78        panic!("Can't change capacity!");
79
80        /*let requested_size = self.size() + additional;
81        let new_size = cmp::max(self.size() * 2, requested_size);
82        self.resize(new_size);*/
83    }
84}
85
86/// Resizable [`Mem`].
87///
88/// Implemented by [`Heap::Mem`].
89pub trait MemResizable: Mem{
90    /// Expand `Mem` size for **exactly** `additional` more elements.
91    /// Implementation encouraged to be as precise as possible with new memory size.
92    ///
93    /// # Panics
94    ///
95    /// Implementation may panic, if fail to allocate/reallocate memory.
96    fn expand_exact(&mut self, additional: usize){
97        self.resize(self.size() + additional);
98    }
99
100    /// Resize memory chunk to specified size.
101    ///
102    /// # Panics
103    ///
104    /// Implementation may panic, if fail to allocate/reallocate/deallocate memory.
105    fn resize(&mut self, new_size: usize);
106}
107
108/// [`Mem`] destructurable into raw parts.
109///
110/// Implemented by [`Heap::Mem`], [`Empty::Mem`].
111pub trait MemRawParts: Mem{
112    type Handle;
113
114    fn into_raw_parts(self) -> (Self::Handle, Layout, usize);
115    unsafe fn from_raw_parts(handle: Self::Handle, element_layout: Layout, size: usize) -> Self;
116}
117
118#[inline]
119const fn dangling(layout: &Layout) -> NonNull<u8>{
120    #[cfg(miri)]
121    {
122        layout.dangling()
123    }
124    #[cfg(not(miri))]
125    {
126        unsafe { NonNull::new_unchecked(layout.align() as *mut u8) }
127    }
128}