use crate::repr::HEAP_MASK;
const USIZE_SIZE: usize = core::mem::size_of::<usize>();
#[allow(non_snake_case)]
const fn CAP_ON_HEAP_FLAG() -> [u8; USIZE_SIZE] {
let mut flag = [255; USIZE_SIZE];
flag[USIZE_SIZE - 1] = HEAP_MASK;
flag
}
const CAPACITY_IS_ON_THE_HEAP: [u8; USIZE_SIZE] = CAP_ON_HEAP_FLAG();
const SPACE_FOR_CAPACITY: usize = USIZE_SIZE - 1;
pub const MAX_VALUE: usize = 2usize.pow(SPACE_FOR_CAPACITY as u32 * 8) - 2;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[cfg_attr(target_pointer_width = "64", repr(align(8)))]
#[cfg_attr(target_pointer_width = "32", repr(align(4)))]
pub struct Capacity([u8; USIZE_SIZE]);
static_assertions::assert_eq_size!(Capacity, usize);
static_assertions::assert_eq_align!(Capacity, usize);
impl Capacity {
#[inline]
pub const fn new(capacity: usize) -> Self {
cfg_if::cfg_if! {
if #[cfg(target_pointer_width = "64")] {
debug_assert!(capacity <= MAX_VALUE);
let mut bytes = capacity.to_le_bytes();
bytes[core::mem::size_of::<usize>() - 1] = HEAP_MASK;
Capacity(bytes)
} else if #[cfg(target_pointer_width = "32")] {
if capacity > MAX_VALUE {
Capacity(CAPACITY_IS_ON_THE_HEAP)
} else {
let mut bytes = capacity.to_le_bytes();
bytes[core::mem::size_of::<usize>() - 1] = HEAP_MASK;
Capacity(bytes)
}
} else {
compile_error!("Unsupported target_pointer_width");
}
}
}
#[inline(always)]
pub unsafe fn as_usize(&self) -> usize {
let mut usize_buf = [0u8; USIZE_SIZE];
core::ptr::copy_nonoverlapping(self.0.as_ptr(), usize_buf.as_mut_ptr(), SPACE_FOR_CAPACITY);
usize::from_le_bytes(usize_buf)
}
#[inline(always)]
pub fn is_heap(&self) -> bool {
self.0 == CAPACITY_IS_ON_THE_HEAP
}
}
#[cfg(test)]
mod tests {
use rayon::prelude::*;
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);
(0..=16_777_214).into_par_iter().for_each(|i| {
let cap = Capacity::new(i);
let val = unsafe { cap.as_usize() };
assert_eq!(val, i, "value roundtriped to wrong value?");
});
}
}