1#![allow(unknown_lints)]
58#![deny(
59 clippy::all,
60 clippy::pedantic,
61 clippy::nursery,
62 clippy::multiple_unsafe_ops_per_block,
63 clippy::undocumented_unsafe_blocks,
64 missing_docs
65)]
66#![warn(clippy::missing_errors_doc)]
67#![allow(
68 clippy::inline_always,
69 clippy::borrow_as_ptr,
70 clippy::module_name_repetitions,
71 clippy::use_self,
72 clippy::question_mark,
73 unused_unsafe
74)]
75#![warn(unknown_lints)]
76#![no_implicit_prelude]
77#![cfg_attr(feature = "dev", warn(rustdoc::broken_intra_doc_links))]
78#![cfg_attr(not(feature = "std"), no_std)]
79#![cfg_attr(nightly, feature(allocator_api))]
81#![cfg_attr(feature = "metadata", feature(ptr_metadata))]
82#![cfg_attr(feature = "sized_hierarchy", feature(sized_hierarchy))]
83
84extern crate core;
89extern crate rustversion;
90
91#[cfg(not(feature = "no_alloc"))] extern crate alloc as stdalloc;
92#[cfg(all(feature = "std", feature = "no_alloc"))] extern crate std as stdalloc;
93
94#[allow(clippy::deprecated_cfg_attr)]
97#[cfg_attr(rustfmt, rustfmt::skip)]
98pub mod prelude {
99 pub use crate::{
100 DefaultAlloc,
102 error::Error,
103 layout::Layout,
104 traits::{
106 AllocError,
107 alloc::{Alloc, BasicAlloc, Dealloc, FullAlloc, Grow, Realloc, Shrink},
108 alloc_mut::{
109 AllocMut,
110 BasicAllocMut,
111 DeallocMut,
112 FullAllocMut,
113 GrowMut,
114 ReallocMut,
115 ShrinkMut
116 },
117 data::type_props::{PtrProps, SizedProps},
118 data::marker::{SizeMeta, Thin, UnsizedCopy}
119 }
120 };
121
122 #[cfg(feature = "alloc_temp_trait")] pub use crate::traits::alloc_temp::AllocTemp;
124
125 #[cfg(feature = "c_alloc")] pub use crate::allocs::c_alloc::CAlloc;
127 #[cfg(feature = "stack_alloc")] pub use crate::allocs::stack_alloc::StackAlloc;
128}
129
130macro_rules! tri {
132 (::$err:ident $($fallible:expr)+) => {
133 match $($fallible)+ {
134 ::core::result::Result::Ok(x) => x,
135 ::core::result::Result::Err(e) => return ::core::result::Result::Err(Error::$err(e)),
136 }
137 };
138 (opt $($fallible:expr)+) => {
139 match $($fallible)+ {
140 Some(x) => x,
141 None => return None,
142 }
143 };
144 (do $($fallible:expr)+) => {
145 match $($fallible)+ {
146 ::core::result::Result::Ok(s) => s,
147 ::core::result::Result::Err(e) => return ::core::result::Result::Err(e),
148 }
149 };
150 (cmap($err:expr) from $e:ty, $($fallible:expr)+) => {
151 match $($fallible)+ {
152 ::core::result::Result::Ok(s) => s,
153 ::core::result::Result::Err(_) => return ::core::result::Result::Err(<$e>::from($err)),
154 }
155 };
156}
157
158macro_rules! zalloc {
159 ($self:ident, $alloc:ident, $layout:ident) => {{
160 let res = $self.$alloc($layout);
161 if let ::core::result::Result::Ok(p) = res {
162 unsafe {
164 ptr::write_bytes(p.as_ptr(), 0, $layout.size());
165 }
166 }
167 res
168 }};
169}
170
171macro_rules! default_dealloc {
172 ($self:ident.$de:ident, $ptr:ident, $l:ident) => {
173 if $l.is_nonzero_sized() && $ptr != $l.dangling() {
174 if let ::core::result::Result::Err(e) = $self.$de($ptr, $l) {
175 default_dealloc_panic($ptr, $l, e)
176 }
177 }
178 };
179}
180
181macro_rules! default_shrink {
182 ($self:ident::$unchecked:ident, $ptr:ident, $old:ident, $new:ident) => {
183 match $new.size().cmp(&$old.size()) {
184 Ordering::Greater => ::core::result::Result::Err(<Self as AllocError>::Error::from(
185 Error::ShrinkLargerNewLayout($old.size(), $new.size())
186 )),
187 Ordering::Equal => {
188 if $new.align() > $old.align() {
189 $unchecked($self, $ptr, $old, $new)
190 } else {
191 ::core::result::Result::Ok($ptr)
192 }
193 }
194 Ordering::Less => $unchecked($self, $ptr, $old, $new)
195 }
196 };
197}
198
199pub mod traits;
201
202pub mod helpers;
204
205pub mod error;
207
208pub mod layout;
210
211#[cfg(any(feature = "c_alloc", feature = "stack_alloc"))]
212pub mod allocs;
214
215#[cfg(any(feature = "c_alloc", feature = "stack_alloc"))]
216pub mod ffi;
218
219#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
227pub struct DefaultAlloc;
228
229#[cfg(any(not(feature = "no_alloc"), feature = "std"))]
230macro_rules! default_alloc_impl {
231 ($ty:ty) => {
232 impl crate::traits::AllocError for $ty {
233 type Error = crate::error::Error;
234 }
235
236 impl crate::traits::alloc::Alloc for $ty {
237 #[cfg_attr(miri, track_caller)]
238 #[inline(always)]
239 fn alloc(
240 &self,
241 layout: crate::layout::Layout
242 ) -> ::core::result::Result<::core::ptr::NonNull<u8>, crate::error::Error> {
243 crate::helpers::null_q_dyn_zsl_check(
244 layout,
245 |layout| unsafe { ::stdalloc::alloc::alloc(layout.to_stdlib()) }
247 )
248 }
249
250 #[cfg_attr(miri, track_caller)]
251 #[inline(always)]
252 fn zalloc(
253 &self,
254 layout: crate::layout::Layout
255 ) -> ::core::result::Result<::core::ptr::NonNull<u8>, crate::error::Error> {
256 crate::helpers::null_q_dyn_zsl_check(
257 layout,
258 |layout| unsafe { ::stdalloc::alloc::alloc_zeroed(layout.to_stdlib()) }
260 )
261 }
262 }
263 impl crate::traits::alloc::Dealloc for $ty {
264 #[cfg_attr(miri, track_caller)]
265 #[inline(always)]
266 unsafe fn dealloc(&self, ptr: ::core::ptr::NonNull<u8>, layout: crate::layout::Layout) {
267 if layout.is_nonzero_sized() && ptr != layout.dangling() {
268 ::stdalloc::alloc::dealloc(ptr.as_ptr(), layout.to_stdlib());
269 }
270 }
271
272 #[cfg_attr(miri, track_caller)]
273 #[inline(always)]
274 unsafe fn try_dealloc(
275 &self,
276 ptr: ::core::ptr::NonNull<u8>,
277 layout: crate::layout::Layout
278 ) -> ::core::result::Result<(), crate::error::Error> {
279 if layout.is_zero_sized() {
280 ::core::result::Result::Err(crate::error::Error::ZeroSizedLayout)
281 } else if ptr == layout.dangling() {
282 ::core::result::Result::Err(crate::error::Error::DanglingDeallocation)
283 } else {
284 ::stdalloc::alloc::dealloc(ptr.as_ptr(), layout.to_stdlib());
285 ::core::result::Result::Ok(())
286 }
287 }
288 }
289 impl crate::traits::alloc::Grow for $ty {}
290 impl crate::traits::alloc::Shrink for $ty {}
291 impl crate::traits::alloc::Realloc for $ty {}
292 };
293}
294
295#[cfg(any(not(feature = "no_alloc"), feature = "std"))]
296unsafe impl ::stdalloc::alloc::GlobalAlloc for DefaultAlloc {
298 #[cfg_attr(miri, track_caller)]
299 #[inline]
300 unsafe fn alloc(&self, layout: crate::layout::StdLayout) -> *mut u8 {
301 ::stdalloc::alloc::alloc(layout)
302 }
303
304 #[cfg_attr(miri, track_caller)]
305 #[inline]
306 unsafe fn dealloc(&self, ptr: *mut u8, layout: crate::layout::StdLayout) {
307 ::stdalloc::alloc::dealloc(ptr, layout);
308 }
309
310 #[cfg_attr(miri, track_caller)]
311 #[inline]
312 unsafe fn alloc_zeroed(&self, layout: crate::layout::StdLayout) -> *mut u8 {
313 ::stdalloc::alloc::alloc_zeroed(layout)
314 }
315
316 #[cfg_attr(miri, track_caller)]
317 #[inline]
318 unsafe fn realloc(
319 &self,
320 ptr: *mut u8,
321 layout: crate::layout::StdLayout,
322 new_size: usize
323 ) -> *mut u8 {
324 ::stdalloc::alloc::realloc(ptr, layout, new_size)
325 }
326}
327
328#[cfg(any(not(feature = "no_alloc"), feature = "std"))]
329default_alloc_impl!(DefaultAlloc);
330
331#[cfg(all(nightly, not(feature = "no_alloc")))]
332pub(crate) mod nightly {
334 use {
335 ::core::ptr::NonNull,
336 ::stdalloc::alloc::{AllocError, Allocator, Global}
337 };
338
339 unsafe impl Allocator for crate::DefaultAlloc {
343 #[cfg_attr(miri, track_caller)]
344 #[inline]
345 fn allocate(
346 &self,
347 layout: crate::layout::StdLayout
348 ) -> ::core::result::Result<NonNull<[u8]>, AllocError> {
349 Allocator::allocate(&Global, layout)
350 }
351
352 #[cfg_attr(miri, track_caller)]
353 #[inline]
354 fn allocate_zeroed(
355 &self,
356 layout: crate::layout::StdLayout
357 ) -> ::core::result::Result<NonNull<[u8]>, AllocError> {
358 Allocator::allocate_zeroed(&Global, layout)
359 }
360
361 #[cfg_attr(miri, track_caller)]
362 #[inline]
363 unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: crate::layout::StdLayout) {
364 Allocator::deallocate(&Global, ptr.cast(), layout);
365 }
366
367 #[cfg_attr(miri, track_caller)]
368 #[inline]
369 unsafe fn grow(
370 &self,
371 ptr: NonNull<u8>,
372 old_layout: crate::layout::StdLayout,
373 new: crate::layout::StdLayout
374 ) -> ::core::result::Result<NonNull<[u8]>, AllocError> {
375 Allocator::grow(&Global, ptr.cast(), old_layout, new)
376 }
377
378 #[cfg_attr(miri, track_caller)]
379 #[inline]
380 unsafe fn grow_zeroed(
381 &self,
382 ptr: NonNull<u8>,
383 old_layout: crate::layout::StdLayout,
384 new: crate::layout::StdLayout
385 ) -> ::core::result::Result<NonNull<[u8]>, AllocError> {
386 Allocator::grow_zeroed(&Global, ptr.cast(), old_layout, new)
387 }
388
389 #[cfg_attr(miri, track_caller)]
390 #[inline]
391 unsafe fn shrink(
392 &self,
393 ptr: NonNull<u8>,
394 old_layout: crate::layout::StdLayout,
395 new: crate::layout::StdLayout
396 ) -> ::core::result::Result<NonNull<[u8]>, AllocError> {
397 Allocator::shrink(&Global, ptr.cast(), old_layout, new)
398 }
399 }
400
401 #[cfg(any(not(feature = "no_alloc"), feature = "std"))]
402 default_alloc_impl!(Global);
403
404 }