use oct::IntoOctets;
use std::mem::take;
#[derive(Debug, Default)]
pub struct Mem {
base: Box<[u32]>,
}
impl Mem {
pub const DEFAULT_SIZE: usize = 256;
pub const MAX_SIZE: usize = 2_usize.checked_pow(32).unwrap_or(usize::MAX);
#[inline]
#[must_use]
pub fn new() -> Self {
Default::default()
}
#[must_use]
pub fn with_capacity(size: usize) -> Self {
let base = vec![0; size].into();
Self { base }
}
pub fn allocate(&mut self, mut size: usize) {
size = size.min(Self::MAX_SIZE);
let mut base = take(&mut self.base).into_vec();
base.clear();
base.resize(size, 0);
self.base = base.into();
}
#[inline]
pub fn store_byte(&mut self, addr: u32, value: u8) {
let slot = usize::try_from(addr).ok()
.and_then(|addr| self.data_mut().get_mut(addr));
if let Some(slot) = slot {
*slot = value;
}
}
#[inline]
#[must_use]
pub fn data(&self) -> &[u8] {
self.base.as_octets()
}
#[inline]
#[must_use]
pub fn data_mut(&mut self) -> &mut [u8] {
self.base.as_octets_mut()
}
}
impl Drop for Mem {
#[inline(always)]
fn drop(&mut self) {}
}