use core::fmt;
use crate::repr::LastByte;
const USIZE_SIZE: usize = core::mem::size_of::<usize>();
const VALID_MASK: usize = {
let mut bytes = [255; USIZE_SIZE];
bytes[USIZE_SIZE - 1] = 0;
usize::from_ne_bytes(bytes)
};
const HEAP_MARKER: usize = {
let mut bytes = [0; USIZE_SIZE];
bytes[USIZE_SIZE - 1] = LastByte::Heap as u8;
usize::from_ne_bytes(bytes)
};
#[cfg(not(target_pointer_width = "64"))]
const CAPACITY_IS_ON_THE_HEAP: Capacity = Capacity(VALID_MASK | HEAP_MARKER);
pub(crate) const MAX_VALUE: usize = {
let mut bytes = [255; USIZE_SIZE];
bytes[USIZE_SIZE - 1] = 0;
usize::from_le_bytes(bytes) - 1
};
#[derive(Copy, Clone, PartialEq, Eq)]
#[repr(transparent)]
pub(crate) struct Capacity(usize);
static_assertions::assert_eq_size!(Capacity, usize);
static_assertions::assert_eq_align!(Capacity, usize);
impl fmt::Debug for Capacity {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Capacity(0x{:x})", usize::from_le(self.0))
}
}
impl Capacity {
#[inline]
pub(crate) const fn new(capacity: usize) -> Self {
cfg_if::cfg_if! {
if #[cfg(target_pointer_width = "64")] {
debug_assert!(capacity <= MAX_VALUE);
Capacity(capacity.to_le() | HEAP_MARKER)
} else if #[cfg(target_pointer_width = "32")] {
if capacity > MAX_VALUE {
CAPACITY_IS_ON_THE_HEAP
} else {
Capacity(capacity.to_le() | HEAP_MARKER)
}
} else {
compile_error!("Unsupported target_pointer_width");
}
}
}
#[inline(always)]
pub(crate) unsafe fn as_usize(self) -> usize {
usize::from_le(self.0 & VALID_MASK)
}
#[inline(always)]
pub(crate) fn is_heap(self) -> bool {
cfg_if::cfg_if! {
if #[cfg(target_pointer_width = "64")] {
false
} else {
self == CAPACITY_IS_ON_THE_HEAP
}
}
}
}
#[cfg(test)]
mod tests {
use super::Capacity;
#[test]
fn test_zero_roundtrips() {
let og = 0;
let cap = Capacity::new(og);
let after = unsafe { cap.as_usize() };
assert_eq!(og, after);
}
#[test]
fn test_max_value() {
let available_bytes = (core::mem::size_of::<usize>() - 1) as u32;
let max_value = 2usize.pow(available_bytes * 8) - 2;
#[cfg(target_pointer_width = "64")]
assert_eq!(max_value, 72057594037927934);
#[cfg(target_pointer_width = "32")]
assert_eq!(max_value, 16777214);
let cap = Capacity::new(max_value);
let after = unsafe { cap.as_usize() };
assert_eq!(max_value, after);
}
#[cfg(target_pointer_width = "32")]
#[test]
fn test_invalid_value() {
let invalid_val = usize::MAX;
let cap = Capacity::new(invalid_val);
let after = unsafe { cap.as_usize() };
assert_eq!(16777215, after);
}
#[test]
#[cfg_attr(miri, ignore)]
fn test_all_valid_32bit_values() {
#[cfg(target_pointer_width = "32")]
assert_eq!(16_777_214, super::MAX_VALUE);
for i in 0..=16_777_214 {
let cap = Capacity::new(i);
let val = unsafe { cap.as_usize() };
assert_eq!(val, i, "value roundtriped to wrong value?");
}
}
}