realloc 0.1.1

A re-implementation of various ::alloc features
Documentation
use core::num::NonZero;

/// A type compactly storing a `usize` which is a power of two, and thus
/// represents a possible alignment in the Rust abstract machine.
///
/// To avoid confusion, values of this type shall be referred to as an
/// "alignment", while alignment represented as a `usize` shall be referred to
/// as an "absolute alignment".
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Align(u8);

impl Align {
    /// Creates a new alignment from an absolute alignment.
    ///
    /// Returns `None` if the `align` is not a power of two.
    pub const fn new(align: usize) -> Option<Self> {
        let n = align.trailing_zeros();

        if align >> n == 1 {
            Self::new_exp(n as u8)
        } else {
            None
        }
    }

    /// Creates a new alignment from an absolute alignment, bypassing the checks
    /// in [`new`](Self::new).
    ///
    /// This should usually not be necessary, as Rust can easily elide the
    /// checks if `new` is called with a compile-time-known value.
    ///
    /// # Safety
    ///
    /// Exactly one bit of `align` must be set. In other words, it must be a
    /// power of two (not zero).
    pub const unsafe fn new_unchecked(align: usize) -> Self {
        Self(align.trailing_zeros() as u8)
    }

    /// Creates a new alignment from the exponent in the equation `align =
    /// 2^exp`, where `align` is the absolute alignment.
    ///
    /// Returns `None` if `exp` is too large (if it's greater than
    /// [`usize::BITS`].
    pub const fn new_exp(exp: u8) -> Option<Self> {
        if exp < usize::BITS as u8 {
            Some(Self(exp))
        } else {
            None
        }
    }

    /// Creates a new alignment from the exponent in the equation `align =
    /// 2^exp`, where `align` is the absolute alignment, bypassing the checks in
    /// [`new_exp`](Self::new_exp).
    ///
    /// This should usually not be necessary, as Rust can easily elide the
    /// checks if `new_exp` is called with a compile-time-known value.
    ///
    /// # Safety
    ///
    /// This value must be < `usize::BITS`.
    pub const unsafe fn new_exp_unchecked(exp: u8) -> Self {
        Self(exp)
    }

    /// Returns the exponent in the equation `align = 2^exp`, where `align` is
    /// the absolute alignment.
    pub const fn exp(&self) -> u8 {
        self.0
    }

    /// Returns the absolute alignment.
    pub const fn align(&self) -> usize {
        1 << self.0 as usize
    }

    /// Returns the absolute alignment as a non-zero integer.
    pub const fn align_nonzero(&self) -> NonZero<usize> {
        // Rust elides this check in release mode
        NonZero::new(1 << self.0 as usize).unwrap()
    }

    /// Returns the alignment of a concrete type.
    ///
    /// Uses [`core::mem::align_of`].
    pub const fn of<T>() -> Self {
        // SAFETY: Rust won't give an invalid alignment
        unsafe { Self::new_unchecked(core::mem::align_of::<T>()) }
    }
}

/// Layout of a block of memory.
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct Layout {
    /// The minimum size in bytes for a memory block of this layout.
    pub size: usize,
    /// The minimum byte alignment for a memory block of this layout.
    pub align: Align,
}

impl Layout {
    /// Returns the layout of a concrete type.
    ///
    /// Uses [`core::mem::size_of`] and [`core::mem::align_of`].
    pub const fn of<T>() -> Self {
        Self {
            size: core::mem::size_of::<T>(),
            align: Align::of::<T>(),
        }
    }

    /// Creates a layout describing a list of `T` that is `len` elements long.
    pub const fn list<T>(len: usize) -> Self {
        let size = size_of::<T>();
        let align = Align::of::<T>();
        let gap = size % align.align();

        Self {
            size: (size + gap) * len - gap,
            align,
        }
    }
}