use crate::{VolAddress, VolBlock};
#[repr(transparent)]
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct VolGrid2d<T, R, W, const WIDTH: usize, const HEIGHT: usize> {
pub(crate) base: VolAddress<T, R, W>,
}
impl<T, R, W, const WIDTH: usize, const HEIGHT: usize> Clone
for VolGrid2d<T, R, W, WIDTH, HEIGHT>
{
#[inline]
#[must_use]
fn clone(&self) -> Self {
*self
}
}
impl<T, R, W, const WIDTH: usize, const HEIGHT: usize> Copy
for VolGrid2d<T, R, W, WIDTH, HEIGHT>
{
}
impl<T, R, W, const WIDTH: usize, const HEIGHT: usize>
VolGrid2d<T, R, W, WIDTH, HEIGHT>
{
#[inline]
#[must_use]
pub const unsafe fn new(address: usize) -> Self {
Self { base: VolAddress::new(address) }
}
#[inline]
#[must_use]
pub const fn width(self) -> usize {
WIDTH
}
#[inline]
#[must_use]
pub const fn height(self) -> usize {
HEIGHT
}
#[inline]
#[must_use]
pub const fn from_block<const B: usize>(block: VolBlock<T, R, W, B>) -> Self {
assert!(B == WIDTH * HEIGHT);
Self { base: block.base }
}
#[inline]
#[must_use]
pub const fn into_block<const B: usize>(self) -> VolBlock<T, R, W, B> {
assert!(B == WIDTH * HEIGHT);
VolBlock { base: self.base }
}
#[inline]
#[must_use]
pub const fn get(self, x: usize, y: usize) -> Option<VolAddress<T, R, W>> {
if x < WIDTH && y < HEIGHT {
Some(unsafe { self.base.add(x + y * WIDTH) })
} else {
None
}
}
#[inline]
#[must_use]
#[track_caller]
pub const fn index(self, x: usize, y: usize) -> VolAddress<T, R, W> {
assert!(x < WIDTH);
assert!(y < HEIGHT);
unsafe { self.base.add(x + y * WIDTH) }
}
#[inline]
#[must_use]
pub const fn get_row(self, y: usize) -> Option<VolBlock<T, R, W, WIDTH>> {
if y < HEIGHT {
Some(unsafe { VolBlock { base: self.base.add(y * WIDTH) } })
} else {
None
}
}
#[inline]
#[must_use]
pub const fn as_usize(self) -> usize {
self.base.address.get()
}
}