use crate::{Discriminant, is};
use ::core::mem::{
align_of, align_of_val, discriminant, drop, forget, needs_drop, replace, size_of, size_of_val,
swap, take,
};
#[allow(unused_imports, reason = "±unsafe")]
use ::core::{
mem::{transmute_copy, zeroed},
slice::{from_raw_parts, from_raw_parts_mut},
};
#[doc = crate::_tags!(mem namespace)]
#[doc = crate::_doc_location!("sys/mem")]
#[doc = crate::doclink!(custom devela "[`MemExt`]" "sys/mem/trait.MemExt.html")]
#[derive(Debug)]
pub struct Mem;
impl Mem {
#[doc = crate::doclink!(custom devela "[`MemLayout`]" "sys/mem/struct.MemLayout.html")]
#[doc = crate::_doc!(vendor: "mini-alloc")]
#[must_use]
#[inline(always)]
pub const fn align_down(value: usize, align: usize) -> usize {
value & align.wrapping_neg()
}
#[must_use]
#[inline(always)]
pub const fn align_up(value: usize, align: usize) -> usize {
(value + align - 1) & !(align - 1)
}
#[must_use]
#[inline(always)]
pub const fn is_aligned(value: usize, align: usize) -> bool {
value & (align - 1) == 0
}
#[inline(always)]
pub fn is_aligned_to<T>(ptr: *const T, requirement: usize) -> bool {
let align = Mem::align_of::<T>();
requirement >= align && Mem::is_aligned(ptr as usize, align)
}
#[must_use]
pub const fn align_of<T>() -> usize {
align_of::<T>()
}
#[must_use]
pub const fn align_of_val<T: ?Sized>(val: &T) -> usize {
align_of_val(val)
}
#[must_use]
pub const fn copy<T: Copy>(x: &T) -> T {
*x
}
#[must_use]
pub const fn discriminant<T>(v: &T) -> Discriminant<T> {
discriminant(v)
}
pub fn drop<T>(_x: T) {
drop(_x);
}
pub fn forget<T>(t: T) {
forget(t);
}
#[must_use]
pub const fn needs_drop<T: ?Sized>() -> bool {
needs_drop::<T>()
}
#[must_use]
pub const fn replace<T>(dest: &mut T, src: T) -> T {
replace::<T>(dest, src)
}
#[must_use]
pub const fn size_of<T>() -> usize {
size_of::<T>()
}
#[must_use]
pub const fn size_of_val<T: ?Sized>(val: &T) -> usize {
size_of_val(val)
}
pub const fn swap<T>(x: &mut T, y: &mut T) {
swap::<T>(x, y);
}
#[must_use]
pub fn take<T: Default>(dest: &mut T) -> T {
take::<T>(dest)
}
}
#[rustfmt::skip]
impl Mem {
pub const fn bytes_from_bits(bit_size: usize) -> usize { (bit_size + 7) >> 3 }
#[must_use]
pub const fn bytes_from_bits_saturating(bit_size: usize) -> usize {
#[cold] const fn bytes_from_bits_cold() -> usize { usize::MAX >> 3 }
is![let Some(t) = bit_size.checked_add(7), t >> 3, bytes_from_bits_cold()]
}
}
#[cfg_attr(nightly_doc, doc(cfg(unsafe··)))]
#[cfg(all(not(feature = "safe_mem"), unsafe··))]
impl Mem {
#[must_use]
pub const unsafe fn transmute_copy<Src, Dst>(src: &Src) -> Dst {
unsafe { transmute_copy::<Src, Dst>(src) }
}
#[must_use]
pub const unsafe fn zeroed<T>() -> T {
unsafe { zeroed::<T>() }
}
}
#[cfg(all(not(feature = "safe_mem"), feature = "unsafe_slice"))]
#[cfg_attr(nightly_doc, doc(cfg(feature = "unsafe_slice")))]
impl Mem {
#[doc = crate::_doc!(vendor: "rawbytes")]
#[must_use]
pub fn as_bytes<'t, T: Sync + Unpin + ?Sized + 't>(v: &T) -> &'t [u8] {
unsafe { from_raw_parts(v as *const _ as *const u8, size_of_val(v)) }
}
#[doc = crate::_doc!(vendor: "rawbytes")]
#[must_use]
pub fn as_bytes_mut<'t, T: Sync + Unpin + ?Sized + 't>(v: &mut T) -> &'t mut [u8] {
unsafe { from_raw_parts_mut(v as *mut _ as *mut u8, size_of_val(v)) }
}
#[must_use]
pub const fn as_bytes_sized<T: Sync + Unpin>(v: &T) -> &[u8] {
unsafe { from_raw_parts(v as *const T as *const u8, size_of::<T>()) }
}
}