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}