#![cfg_attr(feature = "nightly", expect(clippy::incompatible_msrv))]
#[inline]
pub const unsafe fn maybe_uninit_slice_assume_init_ref<T>(
slice: &[core::mem::MaybeUninit<T>],
) -> &[T] {
#[cfg(feature = "nightly")]
{
unsafe { slice.assume_init_ref() }
}
#[cfg(not(feature = "nightly"))]
{
unsafe { &*(slice as *const [core::mem::MaybeUninit<T>] as *const [T]) }
}
}
#[inline]
pub fn hasher_write_length_prefix<H: core::hash::Hasher>(state: &mut H, num_entries: usize) {
#[cfg(feature = "nightly")]
{
<H as core::hash::Hasher>::write_length_prefix(state, num_entries);
}
#[cfg(not(feature = "nightly"))]
{
state.write_usize(num_entries);
}
}
#[cfg(feature = "nightly")]
macro_rules! likely {
($b:expr) => {
core::hint::likely($b)
};
}
#[cfg(not(feature = "nightly"))]
macro_rules! likely {
($b:expr) => {
$b
};
}
pub(crate) use likely;
#[cfg(feature = "nightly")]
macro_rules! unlikely {
($b:expr) => {
core::hint::unlikely($b)
};
}
#[cfg(not(feature = "nightly"))]
macro_rules! unlikely {
($b:expr) => {
$b
};
}
pub(crate) use unlikely;
pub(crate) mod ptr {
use core::{num::NonZeroUsize, ptr::NonNull};
#[inline]
#[cfg(not(feature = "nightly"))]
#[expect(clippy::transmutes_expressible_as_ptr_casts)]
pub fn mut_addr<T>(ptr: *mut T) -> usize {
unsafe { core::mem::transmute(ptr.cast::<()>()) }
}
#[inline]
#[cfg(feature = "nightly")]
pub fn mut_addr<T>(ptr: *mut T) -> usize {
ptr.addr()
}
#[cfg(all(test, any(feature = "allocator-api2", feature = "nightly")))]
#[inline]
#[cfg(not(feature = "nightly"))]
pub fn mut_with_addr<T>(ptr: *mut T, addr: usize) -> *mut T {
let self_addr = mut_addr(ptr) as isize;
let dest_addr = addr as isize;
let offset = dest_addr.wrapping_sub(self_addr);
ptr.wrapping_byte_offset(offset)
}
#[cfg(test)]
#[inline]
#[cfg(not(feature = "nightly"))]
pub fn const_addr<T>(ptr: *const T) -> usize {
ptr.cast::<()>() as usize
}
#[cfg(test)]
#[inline]
#[cfg(feature = "nightly")]
pub fn const_addr<T>(ptr: *const T) -> usize {
ptr.addr()
}
#[cfg(all(test, any(feature = "allocator-api2", feature = "nightly")))]
#[inline]
#[cfg(not(feature = "nightly"))]
pub fn nonnull_addr<T>(ptr: NonNull<T>) -> NonZeroUsize {
unsafe { NonZeroUsize::new_unchecked(mut_addr(ptr.as_ptr())) }
}
#[cfg(all(test, any(feature = "allocator-api2", feature = "nightly")))]
#[inline]
#[cfg(feature = "nightly")]
pub fn nonnull_addr<T>(ptr: NonNull<T>) -> NonZeroUsize {
ptr.addr()
}
#[cfg(all(test, any(feature = "allocator-api2", feature = "nightly")))]
#[inline]
#[cfg(not(feature = "nightly"))]
pub fn nonnull_with_addr<T>(ptr: NonNull<T>, addr: NonZeroUsize) -> NonNull<T> {
unsafe { NonNull::new_unchecked(mut_with_addr(ptr.as_ptr(), addr.get())) }
}
#[cfg(all(test, any(feature = "allocator-api2", feature = "nightly")))]
#[inline]
#[cfg(feature = "nightly")]
pub fn nonnull_with_addr<T>(ptr: NonNull<T>, addr: NonZeroUsize) -> NonNull<T> {
ptr.with_addr(addr)
}
#[inline]
#[cfg(not(feature = "nightly"))]
pub fn nonnull_map_addr<T>(
ptr: NonNull<T>,
f: impl FnOnce(NonZeroUsize) -> NonZeroUsize,
) -> NonNull<T> {
let ptr = ptr.as_ptr();
let old_addr = mut_addr(ptr);
let new_addr = f(unsafe {
NonZeroUsize::new_unchecked(old_addr)
});
let offset = new_addr.get().wrapping_sub(old_addr);
let new_ptr = ptr.wrapping_byte_offset(offset as isize);
unsafe { NonNull::new_unchecked(new_ptr) }
}
#[inline]
#[cfg(feature = "nightly")]
pub fn nonnull_map_addr<T>(
ptr: NonNull<T>,
f: impl FnOnce(NonZeroUsize) -> NonZeroUsize,
) -> NonNull<T> {
ptr.map_addr(f)
}
}