use crate::core::{Layout, Pos, RowMajor};
use core::marker::PhantomData;
pub mod bits;
mod inner_array;
pub use inner_array::ArrayGrid;
#[cfg(feature = "alloc")]
mod inner_vec;
#[cfg(feature = "alloc")]
pub use inner_vec::VecGrid;
mod inner_slice;
pub use inner_slice::{SliceGrid, SliceMutGrid};
mod impl_as_slice;
#[cfg(feature = "bytemuck")]
mod impl_bytemuck;
mod impl_grid;
mod impl_iter;
mod impl_mut;
mod impl_new;
#[derive(Debug, Clone)]
pub struct GridBuf<T, B, L = RowMajor>
where
L: Layout,
{
buffer: B,
width: usize,
height: usize,
_element: PhantomData<T>,
_layout: PhantomData<L>,
}
impl<T, B, L> GridBuf<T, B, L>
where
L: Layout,
{
#[must_use]
pub fn into_inner(self) -> (B, usize, usize) {
(self.buffer, self.width, self.height)
}
}
impl<T, B, L> GridBuf<T, B, L>
where
B: AsRef<[T]>,
L: Layout,
{
pub fn get(&self, pos: Pos) -> Option<&T> {
if pos.x < self.width && pos.y < self.height {
Some(&self.buffer.as_ref()[L::to_1d(pos, self.width).index])
} else {
None
}
}
}
#[cfg(test)]
mod tests {
extern crate alloc;
use super::*;
use crate::{
core::Rect,
grid::{BoundedGrid as _, GridReadUnchecked as _, GridWriteUnchecked as _},
};
use alloc::{vec, vec::Vec};
#[test]
fn impl_bounded_grid() {
let grid = VecGrid::new_filled_row_major(5, 4, 0);
assert_eq!(grid.width(), 5);
assert_eq!(grid.height(), 4);
}
#[test]
fn impl_get_unchecked() {
let grid = VecGrid::new_filled_row_major(5, 4, 42);
let pos = Pos::new(2, 3);
assert_eq!(unsafe { grid.get_unchecked(pos) }, &42);
}
#[test]
fn impl_set_unchecked() {
let mut grid = VecGrid::new_row_major(5, 4);
let pos = Pos::new(2, 3);
unsafe { grid.set_unchecked(pos, 99) };
assert_eq!(unsafe { grid.get_unchecked(pos) }, &99);
}
#[test]
fn with_buffer_col_major() {
let buffer = VecGrid::with_buffer_col_major(vec![1, 2, 3, 4, 5, 6, 7, 8, 9], 3, 3).unwrap();
assert_eq!(buffer.width(), 3);
assert_eq!(buffer.height(), 3);
assert_eq!(buffer.get(Pos::new(0, 0)), Some(&1));
assert_eq!(buffer.get(Pos::new(2, 2)), Some(&9));
}
#[test]
fn with_buffer_col_major_unchecked() {
let buffer = unsafe {
VecGrid::with_buffer_col_major_unchecked(vec![1, 2, 3, 4, 5, 6, 7, 8, 9], 3, 3)
};
assert_eq!(buffer.width(), 3);
assert_eq!(buffer.height(), 3);
assert_eq!(unsafe { buffer.get_unchecked(Pos::new(0, 0)) }, &1);
assert_eq!(unsafe { buffer.get_unchecked(Pos::new(2, 2)) }, &9);
}
#[test]
fn rect_iter_unchecked() {
#[rustfmt::skip]
let buffer = VecGrid::with_buffer_row_major(vec![
1, 2, 3,
4, 5, 6,
7, 8, 9,
], 3, 3).unwrap();
assert_eq!(
unsafe {
buffer
.rect_iter_unchecked(Rect::from_ltwh(1, 1, 2, 1))
.collect::<Vec<_>>()
},
vec![&5, &6]
);
assert_eq!(
unsafe {
buffer
.rect_iter_unchecked(Rect::from_ltwh(0, 0, 3, 3))
.collect::<Vec<_>>()
},
vec![&1, &2, &3, &4, &5, &6, &7, &8, &9]
);
}
#[test]
fn fill_rect_iter_unchecked() {
let mut grid = VecGrid::new_row_major(3, 3);
unsafe {
grid.fill_rect_iter_unchecked(Rect::from_ltwh(0, 0, 2, 2), vec![1, 2, 3, 4]);
}
#[rustfmt::skip]
assert_eq!(grid.buffer.as_ref() as &[i32], &[
1, 2, 0,
3, 4, 0,
0, 0, 0,
]);
}
#[test]
fn fill_rect_solid_unchecked() {
let mut grid = VecGrid::new_row_major(3, 3);
unsafe {
grid.fill_rect_solid_unchecked(Rect::from_ltwh(0, 0, 2, 2), 42);
}
#[rustfmt::skip]
assert_eq!(grid.buffer.as_ref() as &[i32], &[
42, 42, 0,
42, 42, 0,
0, 0, 0,
]);
}
}