1#[cfg(feature = "alloc")]
2extern crate alloc as _alloc;
3#[cfg(feature = "alloc")]
4use _alloc::alloc::{self,Layout};
5
6use core::mem;
7use core::ptr::NonNull;
8
9pub struct RawVec<T> {
10 pub ptr: NonNull<T>,
11 pub cap: usize,
12}
13
14#[inline(always)]
16#[cfg(feature = "alloc")]
17const fn next_cap(cap: usize) -> usize {
18 if cap == 0 { 1 } else { cap * 2 }
19}
20
21impl<T: Sized> RawVec<T> {
22 pub fn new() -> Self {
23 let cap = if mem::size_of::<T>() == 0 { isize::MAX } else { 0 };
24 Self {
25 ptr: NonNull::dangling(),
26 cap: cap as usize,
27 }
28 }
29}
30
31#[derive(Debug,Clone,Copy,PartialEq)]
33pub enum ResizeError {
34 #[cfg(feature = "alloc")]
35 AllocationError(Layout),
36 #[cfg(not(feature = "alloc"))]
37 AllocNotSupported,
38 CapacityOverflow,
39 AllocationExceedsMaximun,
40}
41
42impl ResizeError {
43 pub (crate) fn handle(&self) -> ! {
44 #[cfg(feature = "alloc")]
45 if let Self::AllocationError(layout) = self {
46 alloc::handle_alloc_error(*layout)
47 }
48 #[cfg(not(feature = "alloc"))]
49 if let Self::AllocNotSupported = self {
50 panic!("Alloc is not enabled. Can't switch the buffer to the heap")
51 }
52 panic!("Fatal error: {self:?}");
53 }
54}
55
56#[cfg(feature = "alloc")]
57impl<T: Sized> RawVec<T> {
58 pub fn try_with_capacity(cap: usize) -> Result<Self,ResizeError> {
59 let mut vec = Self::new();
60 if mem::size_of::<T>() != 0 {
61 vec.resize_buffer(cap)?;
62 }
63 Ok(vec)
64 }
65 fn resize_buffer(&mut self, new_cap: usize) -> Result<(), ResizeError> {
66 if mem::size_of::<T>() == 0 {
69 return Err(ResizeError::CapacityOverflow)
70 }
71
72 let Ok(new_layout) = Layout::array::<T>(new_cap) else {
73 return Err(ResizeError::AllocationExceedsMaximun);
74 };
75 if new_layout.size() > isize::MAX as usize {
76 return Err(ResizeError::AllocationExceedsMaximun);
77 }
78
79 let new_ptr = if self.cap == 0 {
80 unsafe { alloc::alloc(new_layout) }
81 } else {
82 let old_layout = Layout::array::<T>(self.cap).unwrap();
83 let ptr = self.ptr.as_ptr() as *mut u8;
84 unsafe { alloc::realloc(ptr, old_layout, new_layout.size()) }
85 };
86 if new_ptr.is_null() {
87 return Err(ResizeError::AllocationError(new_layout))
88 }
89
90 self.cap = new_cap;
91 self.ptr = unsafe { NonNull::new_unchecked(new_ptr as *mut T) };
92
93 Ok(())
94 }
95 pub fn try_expand_if_needed(&mut self, len: usize, n: usize) -> Result<(), ResizeError> {
96 if len == self.cap {
97 let mut new_cap = self.cap;
98 while new_cap - len < n {
99 new_cap = next_cap(new_cap);
100 }
101 self.resize_buffer(new_cap)?;
102 }
103 Ok(())
104 }
105 #[inline]
106 pub fn try_expand_if_needed_exact(&mut self, len: usize, n: usize) -> Result<(), ResizeError> {
107 if len == self.cap {
108 self.resize_buffer(n)?;
109 }
110 Ok(())
111 }
112
113 pub fn shrink_to_fit(&mut self, len: usize) {
114 self.resize_buffer(len).unwrap_or_else(|err| err.handle());
115 }
116 pub unsafe fn destroy(&mut self) {
117 if self.cap != 0 && mem::size_of::<T>() != 0 {
118 let layout = Layout::array::<T>(self.cap).unwrap();
119 unsafe {
120 let ptr = self.ptr.as_ptr() as *mut u8;
121 alloc::dealloc(ptr, layout);
122 }
123 }
124 }
125}
126
127#[cfg(not(feature = "alloc"))]
128#[allow(unused)]
129impl<T: Sized> RawVec<T> {
130 pub fn try_with_capacity(cap: usize) -> Result<Self,ResizeError> {
131 panic!("Alloc is not enabled. Can't switch the buffer to the heap")
132 }
133 fn resize_buffer(&mut self, new_cap: usize) {
134 panic!("Alloc is not enabled. Can't switch the buffer to the heap")
135 }
136
137 pub fn try_expand_if_needed(&mut self, len: usize, n: usize) -> Result<(), ResizeError> {
138 Err(ResizeError::AllocNotSupported)
139 }
140 #[inline]
141 pub fn try_expand_if_needed_exact(&mut self, len: usize, n: usize) -> Result<(), ResizeError> {
142 Err(ResizeError::AllocNotSupported)
143 }
144
145 pub fn shrink_to_fit(&mut self, len: usize) {
146 panic!("Alloc is not enabled. Can't switch the buffer to the heap")
147 }
148 pub unsafe fn destroy(&mut self) {
149 panic!("Alloc is not enabled. Can't switch the buffer to the heap")
150 }
151}
152
153impl<T: Sized> Clone for RawVec<T> {
154 fn clone(&self) -> Self {
155 *self
156 }
157}
158
159impl<T: Sized> Copy for RawVec<T> { }
160
161impl<T> Default for RawVec<T> {
162 fn default() -> Self {
163 Self::new()
164 }
165}