use core::{ops::Range, ptr::NonNull};
#[cfg(feature = "alloc")]
use core::{num::NonZeroUsize, ptr};
use crate::polyfill::pointer;
#[must_use]
#[inline(always)]
pub(crate) unsafe fn offset_from_unsigned<T>(this: NonNull<T>, origin: NonNull<T>) -> usize {
unsafe { pointer::offset_from_unsigned(this.as_ptr(), origin.as_ptr()) }
}
#[must_use]
#[inline(always)]
pub(crate) unsafe fn byte_offset_from_unsigned<T>(this: NonNull<T>, origin: NonNull<T>) -> usize {
unsafe { offset_from_unsigned::<u8>(this.cast(), origin.cast()) }
}
#[inline(always)]
pub(crate) fn is_aligned_to(ptr: NonNull<u8>, align: usize) -> bool {
debug_assert!(align.is_power_of_two());
ptr.addr().get() & (align - 1) == 0
}
#[inline(always)]
pub(crate) const fn as_non_null_ptr<T>(ptr: NonNull<[T]>) -> NonNull<T> {
ptr.cast()
}
pub(crate) const fn from_ref<T>(r: &T) -> NonNull<T> {
unsafe { NonNull::new_unchecked(r as *const T as *mut T) }
}
#[inline]
#[must_use]
#[cfg(feature = "alloc")]
pub(crate) const fn without_provenance<T>(addr: NonZeroUsize) -> NonNull<T> {
let pointer = ptr::without_provenance_mut(addr.get());
unsafe { NonNull::new_unchecked(pointer) }
}
pub(crate) unsafe fn truncate<T>(slice: &mut NonNull<[T]>, len: usize) {
unsafe {
if len >= slice.len() {
return;
}
let remaining_len = slice.len() - len;
let to_drop_start = as_non_null_ptr(*slice).add(len);
let to_drop = NonNull::slice_from_raw_parts(to_drop_start, remaining_len);
set_len::<T>(slice, len);
to_drop.drop_in_place();
}
}
#[inline(always)]
pub(crate) unsafe fn wrapping_byte_add<T>(ptr: NonNull<T>, count: usize) -> NonNull<T> {
unsafe { NonNull::new_unchecked(ptr.as_ptr().cast::<u8>().wrapping_add(count).cast()) }
}
#[inline(always)]
pub(crate) unsafe fn wrapping_byte_sub<T>(ptr: NonNull<T>, count: usize) -> NonNull<T> {
unsafe { NonNull::new_unchecked(ptr.as_ptr().cast::<u8>().wrapping_sub(count).cast()) }
}
#[inline(always)]
pub(crate) fn set_ptr<T>(ptr: &mut NonNull<[T]>, new_ptr: NonNull<T>) {
let len = ptr.len();
*ptr = NonNull::slice_from_raw_parts(new_ptr, len);
}
#[inline(always)]
pub(crate) fn set_len<T>(ptr: &mut NonNull<[T]>, new_len: usize) {
let elem_ptr = as_non_null_ptr(*ptr);
*ptr = NonNull::slice_from_raw_parts(elem_ptr, new_len);
}
#[inline(always)]
pub(crate) unsafe fn result<T, E>(mut ptr: NonNull<Result<T, E>>) -> Result<NonNull<T>, NonNull<E>> {
unsafe {
match ptr.as_mut() {
Ok(ok) => Ok(ok.into()),
Err(err) => Err(err.into()),
}
}
}
#[inline(always)]
pub(crate) unsafe fn cast_range<T, U>(ptr: Range<NonNull<T>>) -> Range<NonNull<U>> {
ptr.start.cast()..ptr.end.cast()
}
#[must_use]
#[inline(always)]
pub(crate) const fn str_from_utf8(bytes: NonNull<[u8]>) -> NonNull<str> {
unsafe { NonNull::new_unchecked(bytes.as_ptr() as *mut str) }
}
#[must_use]
#[inline(always)]
pub(crate) const fn str_bytes(str: NonNull<str>) -> NonNull<[u8]> {
unsafe { NonNull::new_unchecked(str.as_ptr() as *mut [u8]) }
}
#[must_use]
#[inline(always)]
pub(crate) const fn str_len(str: NonNull<str>) -> usize {
str_bytes(str).len()
}
#[inline(always)]
pub(crate) unsafe fn write_with<T>(ptr: NonNull<T>, f: impl FnOnce() -> T) {
unsafe { ptr.write(f()) };
}