mod tests;
use std::fmt::Display;
use derive_more::{Add, Sub, Sum, AddAssign, SubAssign};
const BITS_IN_BYTE: u64 = 8;
#[derive(
PartialEq, PartialOrd, Ord, Eq,
Clone, Copy, Hash, Debug, Default,
Add, Sub, Sum, AddAssign, SubAssign
)]
pub struct MemorySize {
size_bits: u64
}
impl MemorySize {
pub const fn new() -> Self {
MemorySize { size_bits: 0 }
}
pub const fn from_bytes(size_bytes: u64) -> MemorySize{
MemorySize{
size_bits: size_bytes.checked_mul(BITS_IN_BYTE).unwrap()
}
}
pub const fn from_bits(size_bits: u64) -> MemorySize {
MemorySize {
size_bits
}
}
pub const fn from_bits_ceil(bits: u64) -> MemorySize {
MemorySize {
size_bits: bits.div_ceil(BITS_IN_BYTE) * BITS_IN_BYTE
}
}
pub const fn size_bytes(&self) -> u64 {
assert!(self.size_bits % BITS_IN_BYTE == 0);
self.size_bits / BITS_IN_BYTE
}
pub const fn size_bits(&self) -> u64 {
self.size_bits
}
pub const fn size_bits_bytes(&self) -> (u64, u64) {
(self.size_bits % BITS_IN_BYTE, self.size_bits / BITS_IN_BYTE)
}
pub const fn align_up(&self, alignment: MemorySize) -> MemorySize {
if self.size_bits == 0 {return *self;}
if alignment.size_bits == 0 {return *self;}
let too_much = self.size_bits + alignment.size_bits - 1; let size_bits = (too_much / alignment.size_bits) * alignment.size_bits;
Self { size_bits }
}
pub const fn round_up_byte(&self) -> MemorySize {
self.align_up(MemorySize::from_bytes(1))
}
}
impl Display for MemorySize {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}bit", self.size_bits())
}
}