#![cfg_attr(
not(any(all(feature = "alloc", not(portable_atomic_no_alloc)), feature = "std")),
allow(dead_code, unused_macros, unused_imports)
)]
macro_rules! cfg_sel {
({#[cfg(else)] { $($output:tt)* }}) => {
$($output)*
};
({
#[cfg($cfg:meta)]
{ $($output:tt)* }
$($( $rest:tt )+)?
}) => {
#[cfg($cfg)]
cfg_sel! {{#[cfg(else)] { $($output)* }}}
$(
#[cfg(not($cfg))]
cfg_sel! {{ $($rest)+ }}
)?
};
}
pub(crate) mod ptr {
cfg_sel!({
#[cfg(not(portable_atomic_no_strict_provenance))]
{
pub(crate) use core::ptr::without_provenance_mut;
}
#[cfg(else)]
{
#[inline(always)]
#[must_use]
pub(crate) const fn without_provenance_mut<T>(addr: usize) -> *mut T {
#[cfg(miri)]
unsafe {
core::mem::transmute(addr)
}
#[cfg(not(miri))]
{
addr as *mut T
}
}
pub(crate) trait PtrExt<T: ?Sized>: Copy {
#[must_use]
fn addr(self) -> usize;
}
impl<T: ?Sized> PtrExt<T> for *const T {
#[inline(always)]
#[must_use]
fn addr(self) -> usize {
#[cfg(miri)]
unsafe {
core::mem::transmute(self as *const ())
}
#[cfg(not(miri))]
{
self as *const () as usize
}
}
}
}
});
#[inline]
#[must_use]
pub(crate) fn with_metadata_of<T, U: ?Sized>(this: *mut T, mut other: *const U) -> *mut U {
let target = &mut other as *mut *const U as *mut *const u8;
unsafe { *target = this as *const u8 }
other as *mut U
}
#[inline]
#[must_use]
pub(crate) unsafe fn byte_add<T: ?Sized>(ptr: *mut T, count: usize) -> *mut T {
unsafe { with_metadata_of((ptr as *mut u8).add(count), ptr) }
}
#[inline]
#[must_use]
pub(crate) unsafe fn byte_sub<T: ?Sized>(ptr: *mut T, count: usize) -> *mut T {
unsafe { with_metadata_of((ptr as *mut u8).sub(count), ptr) }
}
}