flex_array/alloc/
std_alloc.rs1pub use alloc_def::Global;
2
3#[cfg(feature = "alloc_unstable")]
4mod alloc_def {
5 pub use std::alloc::Global;
7}
8
9#[cfg(not(feature = "alloc_unstable"))]
10mod alloc_def {
11 use core::ptr;
12 use core::ptr::NonNull;
13 use std::alloc;
14 use std::alloc::Layout;
15
16 use crate::alloc::AllocError;
17 use crate::alloc::AltAllocator;
18
19 #[derive(Debug, Copy, Clone)]
28 pub struct Global;
29
30 unsafe impl AltAllocator for Global {
31 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
32 if layout.size() == 0 {
35 return Err(AllocError);
36 };
37 let ptr = unsafe { alloc::alloc(layout) };
38 let Some(ptr) = NonNull::new(ptr) else {
39 return Err(AllocError);
40 };
41 return Ok(NonNull::slice_from_raw_parts(ptr, layout.size()));
42 }
43
44 fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
45 if layout.size() == 0 {
46 return Err(AllocError);
47 };
48 let ptr = unsafe { alloc::alloc_zeroed(layout) };
49 let Some(ptr) = NonNull::new(ptr) else {
50 return Err(AllocError);
51 };
52 return Ok(NonNull::slice_from_raw_parts(ptr, layout.size()));
53 }
54
55 unsafe fn deallocate(&self, ptr: ptr::NonNull<u8>, layout: Layout) {
56 unsafe { alloc::dealloc(ptr.as_ptr(), layout) };
57 }
58
59 unsafe fn grow(
60 &self,
61 old_ptr: NonNull<u8>,
62 old_layout: Layout,
63 new_layout: Layout,
64 ) -> Result<NonNull<[u8]>, AllocError> {
65 if new_layout.size() == 0 {
66 return Err(AllocError);
67 }
68
69 let new = unsafe { alloc::realloc(old_ptr.as_ptr(), old_layout, new_layout.size()) };
70 let Some(new) = NonNull::new(new) else {
71 return Err(AllocError);
72 };
73 return Ok(NonNull::slice_from_raw_parts(new, new_layout.size()));
74 }
75
76 unsafe fn grow_zeroed(
77 &self,
78 old_ptr: NonNull<u8>,
79 old_layout: Layout,
80 new_layout: Layout,
81 ) -> Result<NonNull<[u8]>, AllocError> {
82 let old_sz = old_layout.size();
83 let new_sz = new_layout.size();
84
85 if old_sz == 0 {
89 return self.allocate_zeroed(new_layout);
90 }
91
92 if new_sz <= old_sz {
96 return Ok(NonNull::slice_from_raw_parts(old_ptr, old_layout.size()));
97 }
98
99 let new = unsafe { alloc::realloc(old_ptr.as_ptr(), old_layout, new_layout.size()) };
100 let Some(new) = NonNull::new(new) else {
101 return Err(AllocError);
102 };
103
104 let start = unsafe { new.add(old_sz) };
106 unsafe {
107 start.write_bytes(0, new_sz - old_sz);
108 };
109
110 return Ok(NonNull::slice_from_raw_parts(new, new_layout.size()));
111 }
112
113 unsafe fn shrink(
114 &self,
115 old_ptr: NonNull<u8>,
116 old_layout: Layout,
117 new_layout: Layout,
118 ) -> Result<NonNull<[u8]>, AllocError> {
119 if new_layout.size() == 0 {
120 return Err(AllocError);
121 }
122 let new = unsafe { alloc::realloc(old_ptr.as_ptr(), old_layout, new_layout.size()) };
123 let Some(new) = NonNull::new(new) else {
124 return Err(AllocError);
125 };
126 return Ok(NonNull::slice_from_raw_parts(new, new_layout.size()));
127 }
128 }
129}