Index operator overloads for Mat

This commit is contained in:
tali 2022-12-19 17:20:25 -05:00
parent 4240c91a34
commit d30f413949
1 changed files with 37 additions and 18 deletions

View File

@ -36,11 +36,6 @@ impl Mat {
pub const EMPTY: &'static Self = Self::new(&[]);
#[inline]
const fn data(&self) -> &[u16] {
&self.0
}
/// Returns the number of columns in the matrix. This always returns `COLUMNS`.
#[inline]
pub const fn cols(&self) -> i16 {
@ -51,17 +46,13 @@ impl Mat {
#[inline]
pub const fn rows(&self) -> i16 {
// XXX(iitalics): this is guarunteed not to wrap, since we check len in `new`.
self.data().len() as i16
self.0.len() as i16
}
/// Returns true if the cells in row `y` selected by `mask` match the pattern `test`.
#[inline]
pub fn test_row(&self, y: i16, mask: u16, test: u16) -> bool {
let bits = match usize::try_from(y) {
Ok(i) => self.data().get(i).copied().unwrap_or(EMPTY_ROW),
Err(_) => FULL_ROW,
};
(bits & mask) == test
(self[y] & mask) == test
}
/// Returns true if the cell at `(x,y)` is occupied.
@ -75,6 +66,33 @@ impl Mat {
}
}
impl core::ops::Index<i16> for Mat {
type Output = u16;
fn index(&self, y: i16) -> &u16 {
if y < 0 {
&FULL_ROW
} else {
self.0.get(y as usize).unwrap_or(&EMPTY_ROW)
}
}
}
impl core::ops::Index<core::ops::RangeTo<i16>> for Mat {
type Output = [u16];
fn index(&self, r: core::ops::RangeTo<i16>) -> &[u16] {
let y = core::cmp::max(r.end, 0);
let y = core::cmp::min(y as usize, self.0.len());
&self.0[..y]
}
}
impl core::ops::Index<core::ops::RangeFull> for Mat {
type Output = [u16];
fn index(&self, _: core::ops::RangeFull) -> &[u16] {
&self.0
}
}
impl core::fmt::Debug for Mat {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "mat!{{")?;
@ -170,12 +188,13 @@ where
///
/// Panics if the buffer space cannot fit the rows of `mat`.
pub fn copy_from(&mut self, mat: &Mat) {
let data = self.buffer.as_mut();
if mat.data().len() > data.len() {
let mat_data = &mat[..];
let buf_data = self.buffer.as_mut();
if mat_data.len() > buf_data.len() {
panic!("matrix cannot fit in available buffer space");
}
self.rows = mat.rows() as usize;
data[..self.rows].copy_from_slice(mat.data());
self.rows = mat_data.len();
buf_data[..self.rows].copy_from_slice(mat_data);
}
pub fn fill_row(&mut self, y: i16, mask: u16) {
@ -184,14 +203,14 @@ where
return;
}
let y = y as usize;
let data = self.buffer.as_mut();
let buf_data = self.buffer.as_mut();
while y >= self.rows {
*data
*buf_data
.get_mut(self.rows)
.expect("y should be within available buffer space") = EMPTY_ROW;
self.rows += 1;
}
data[y] |= mask;
buf_data[y] |= mask;
}
/// Fills in the cell at the given (x,y) coordinate. Adds new rows to the top of the