#![allow(unknown_lints)]
#![deny(
clippy::all,
clippy::pedantic,
clippy::nursery,
clippy::multiple_unsafe_ops_per_block,
clippy::undocumented_unsafe_blocks,
clippy::unsafe_op_in_unsafe_fn,
missing_docs
)]
#![warn(clippy::missing_errors_doc)]
#![allow(
clippy::inline_always,
clippy::borrow_as_ptr,
clippy::module_name_repetitions,
clippy::use_self,
clippy::question_mark,
unused_unsafe
)]
#![warn(unknown_lints)]
#![no_implicit_prelude]
#![cfg_attr(feature = "dev", warn(rustdoc::broken_intra_doc_links))]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(nightly, feature(allocator_api))]
#![cfg_attr(feature = "metadata", feature(ptr_metadata))]
#![cfg_attr(feature = "sized_hierarchy", feature(sized_hierarchy))]
extern crate core;
extern crate rustversion;
#[cfg(feature = "c_alloc")] extern crate cty;
#[cfg(not(feature = "no_alloc"))] extern crate alloc as stdalloc;
#[cfg(all(feature = "std", feature = "no_alloc"))] extern crate std as stdalloc;
#[allow(clippy::deprecated_cfg_attr)]
#[cfg_attr(rustfmt, rustfmt::skip)]
pub mod prelude {
pub use crate::{
DefaultAlloc,
error::Error,
layout::Layout,
traits::{
AllocError,
alloc::{Alloc, BasicAlloc, Dealloc, FullAlloc, Grow, Realloc, Shrink},
alloc_mut::{
AllocMut,
BasicAllocMut,
DeallocMut,
FullAllocMut,
GrowMut,
ReallocMut,
ShrinkMut
},
data::type_props::{PtrProps, SizedProps},
data::marker::{SizeMeta, Thin, UnsizedCopy}
}
};
#[cfg(feature = "alloc_temp_trait")] pub use crate::traits::alloc_temp::AllocTemp;
#[cfg(feature = "c_alloc")] pub use crate::allocs::c_alloc::CAlloc;
#[cfg(feature = "stack_alloc")] pub use crate::allocs::stack_alloc::StackAlloc;
}
macro_rules! tri {
(::$err:ident $($fallible:expr)+) => {
match $($fallible)+ {
::core::result::Result::Ok(x) => x,
::core::result::Result::Err(e) => return ::core::result::Result::Err(Error::$err(e)),
}
};
(opt $($fallible:expr)+) => {
match $($fallible)+ {
Some(x) => x,
None => return None,
}
};
(do $($fallible:expr)+) => {
match $($fallible)+ {
::core::result::Result::Ok(s) => s,
::core::result::Result::Err(e) => return ::core::result::Result::Err(e),
}
};
(cmap($err:expr) from $e:ty, $($fallible:expr)+) => {
match $($fallible)+ {
::core::result::Result::Ok(s) => s,
::core::result::Result::Err(_) => return ::core::result::Result::Err(<$e>::from($err)),
}
};
}
macro_rules! zalloc {
($self:ident, $alloc:ident, $layout:ident) => {{
let res = $self.$alloc($layout);
if let ::core::result::Result::Ok(p) = res {
unsafe {
ptr::write_bytes(p.as_ptr(), 0, $layout.size());
}
}
res
}};
}
macro_rules! default_dealloc {
($self:ident.$de:ident, $ptr:ident, $l:ident) => {
if $l.is_nonzero_sized() && $ptr != $l.dangling() {
if let ::core::result::Result::Err(e) = $self.$de($ptr, $l) {
default_dealloc_panic($ptr, $l, e)
}
}
};
}
macro_rules! default_shrink {
($self:ident::$unchecked:ident, $ptr:ident, $old:ident, $new:ident) => {
match $new.size().cmp(&$old.size()) {
Ordering::Greater => ::core::result::Result::Err(<Self as AllocError>::Error::from(
Error::ShrinkLargerNewLayout($old.size(), $new.size())
)),
Ordering::Equal => {
if $new.align() > $old.align() {
$unchecked($self, $ptr, $old, $new)
} else {
::core::result::Result::Ok($ptr)
}
}
Ordering::Less => $unchecked($self, $ptr, $old, $new)
}
};
}
pub mod traits;
pub mod helpers;
pub mod error;
pub mod layout;
#[cfg(any(feature = "c_alloc", feature = "stack_alloc"))]
pub mod allocs;
#[cfg(any(feature = "c_alloc", feature = "stack_alloc"))]
pub mod ffi;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct DefaultAlloc;
#[cfg(any(not(feature = "no_alloc"), feature = "std"))]
macro_rules! default_alloc_impl {
($ty:ty) => {
impl crate::traits::AllocError for $ty {
type Error = crate::error::Error;
}
impl crate::traits::alloc::Alloc for $ty {
#[cfg_attr(miri, track_caller)]
#[inline(always)]
fn alloc(
&self,
layout: crate::layout::Layout
) -> ::core::result::Result<::core::ptr::NonNull<u8>, crate::error::Error> {
crate::helpers::null_q_dyn_zsl_check(
layout,
|layout| unsafe { ::stdalloc::alloc::alloc(layout.to_stdlib()) }
)
}
#[cfg_attr(miri, track_caller)]
#[inline(always)]
fn zalloc(
&self,
layout: crate::layout::Layout
) -> ::core::result::Result<::core::ptr::NonNull<u8>, crate::error::Error> {
crate::helpers::null_q_dyn_zsl_check(
layout,
|layout| unsafe { ::stdalloc::alloc::alloc_zeroed(layout.to_stdlib()) }
)
}
}
impl crate::traits::alloc::Dealloc for $ty {
#[cfg_attr(miri, track_caller)]
#[inline(always)]
unsafe fn dealloc(&self, ptr: ::core::ptr::NonNull<u8>, layout: crate::layout::Layout) {
if layout.is_nonzero_sized() && ptr != layout.dangling() {
::stdalloc::alloc::dealloc(ptr.as_ptr(), layout.to_stdlib());
}
}
#[cfg_attr(miri, track_caller)]
#[inline(always)]
unsafe fn try_dealloc(
&self,
ptr: ::core::ptr::NonNull<u8>,
layout: crate::layout::Layout
) -> ::core::result::Result<(), crate::error::Error> {
if layout.is_zero_sized() {
::core::result::Result::Err(crate::error::Error::ZeroSizedLayout)
} else if ptr == layout.dangling() {
::core::result::Result::Err(crate::error::Error::DanglingDeallocation)
} else {
::stdalloc::alloc::dealloc(ptr.as_ptr(), layout.to_stdlib());
::core::result::Result::Ok(())
}
}
}
impl crate::traits::alloc::Grow for $ty {}
impl crate::traits::alloc::Shrink for $ty {}
impl crate::traits::alloc::Realloc for $ty {}
};
}
#[cfg(any(not(feature = "no_alloc"), feature = "std"))]
unsafe impl ::stdalloc::alloc::GlobalAlloc for DefaultAlloc {
#[cfg_attr(miri, track_caller)]
#[inline]
unsafe fn alloc(&self, layout: crate::layout::StdLayout) -> *mut u8 {
::stdalloc::alloc::alloc(layout)
}
#[cfg_attr(miri, track_caller)]
#[inline]
unsafe fn dealloc(&self, ptr: *mut u8, layout: crate::layout::StdLayout) {
::stdalloc::alloc::dealloc(ptr, layout);
}
#[cfg_attr(miri, track_caller)]
#[inline]
unsafe fn alloc_zeroed(&self, layout: crate::layout::StdLayout) -> *mut u8 {
::stdalloc::alloc::alloc_zeroed(layout)
}
#[cfg_attr(miri, track_caller)]
#[inline]
unsafe fn realloc(
&self,
ptr: *mut u8,
layout: crate::layout::StdLayout,
new_size: usize
) -> *mut u8 {
::stdalloc::alloc::realloc(ptr, layout, new_size)
}
}
#[cfg(any(not(feature = "no_alloc"), feature = "std"))]
default_alloc_impl!(DefaultAlloc);
#[cfg(all(nightly, not(feature = "no_alloc")))]
pub(crate) mod nightly {
use {
::core::ptr::NonNull,
::stdalloc::alloc::{AllocError, Allocator, Global}
};
unsafe impl Allocator for crate::DefaultAlloc {
#[cfg_attr(miri, track_caller)]
#[inline]
fn allocate(
&self,
layout: crate::layout::StdLayout
) -> ::core::result::Result<NonNull<[u8]>, AllocError> {
Allocator::allocate(&Global, layout)
}
#[cfg_attr(miri, track_caller)]
#[inline]
fn allocate_zeroed(
&self,
layout: crate::layout::StdLayout
) -> ::core::result::Result<NonNull<[u8]>, AllocError> {
Allocator::allocate_zeroed(&Global, layout)
}
#[cfg_attr(miri, track_caller)]
#[inline]
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: crate::layout::StdLayout) {
Allocator::deallocate(&Global, ptr.cast(), layout);
}
#[cfg_attr(miri, track_caller)]
#[inline]
unsafe fn grow(
&self,
ptr: NonNull<u8>,
old_layout: crate::layout::StdLayout,
new: crate::layout::StdLayout
) -> ::core::result::Result<NonNull<[u8]>, AllocError> {
Allocator::grow(&Global, ptr.cast(), old_layout, new)
}
#[cfg_attr(miri, track_caller)]
#[inline]
unsafe fn grow_zeroed(
&self,
ptr: NonNull<u8>,
old_layout: crate::layout::StdLayout,
new: crate::layout::StdLayout
) -> ::core::result::Result<NonNull<[u8]>, AllocError> {
Allocator::grow_zeroed(&Global, ptr.cast(), old_layout, new)
}
#[cfg_attr(miri, track_caller)]
#[inline]
unsafe fn shrink(
&self,
ptr: NonNull<u8>,
old_layout: crate::layout::StdLayout,
new: crate::layout::StdLayout
) -> ::core::result::Result<NonNull<[u8]>, AllocError> {
Allocator::shrink(&Global, ptr.cast(), old_layout, new)
}
}
#[cfg(any(not(feature = "no_alloc"), feature = "std"))]
default_alloc_impl!(Global);
}