Fix #13 overflow size calculation and init zero grid
This commit is contained in:
parent
4aa88f4a65
commit
30caea7709
1 changed files with 71 additions and 4 deletions
75
src/lib.rs
75
src/lib.rs
|
@ -102,7 +102,7 @@ macro_rules! grid {
|
||||||
let rows = rows + 1usize;
|
let rows = rows + 1usize;
|
||||||
)*
|
)*
|
||||||
|
|
||||||
let mut vec = Vec::with_capacity(rows * cols);
|
let mut vec = Vec::with_capacity(rows.checked_mul(cols).unwrap());
|
||||||
|
|
||||||
$( vec.push($x0); )*
|
$( vec.push($x0); )*
|
||||||
$( $( vec.push($x); )* )*
|
$( $( vec.push($x); )* )*
|
||||||
|
@ -147,7 +147,7 @@ impl<T> Grid<T> {
|
||||||
return Grid { data: Vec::new(), rows:0, cols: 0 }
|
return Grid { data: Vec::new(), rows:0, cols: 0 }
|
||||||
}
|
}
|
||||||
let mut data = Vec::new();
|
let mut data = Vec::new();
|
||||||
data.resize_with(rows * cols, T::default);
|
data.resize_with(rows.checked_mul(cols).unwrap(), T::default);
|
||||||
Grid { data, cols, rows }
|
Grid { data, cols, rows }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,8 +162,11 @@ impl<T> Grid<T> {
|
||||||
where
|
where
|
||||||
T: Clone,
|
T: Clone,
|
||||||
{
|
{
|
||||||
|
if rows == 0 || cols == 0 {
|
||||||
|
return Grid { data: Vec::new(), rows:0, cols: 0 }
|
||||||
|
}
|
||||||
Grid {
|
Grid {
|
||||||
data: vec![data; rows * cols],
|
data: vec![data; rows.checked_mul(cols).unwrap()],
|
||||||
cols,
|
cols,
|
||||||
rows,
|
rows,
|
||||||
}
|
}
|
||||||
|
@ -283,7 +286,7 @@ impl<T> Grid<T> {
|
||||||
/// assert!(grid.is_empty());
|
/// assert!(grid.is_empty());
|
||||||
/// ```
|
/// ```
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
return self.data.is_empty()
|
self.data.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clears the grid.
|
/// Clears the grid.
|
||||||
|
@ -463,7 +466,10 @@ impl<T> Grid<T> {
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if the grid is not empty and `row.len() != grid.cols()`.
|
/// Panics if the grid is not empty and `row.len() != grid.cols()`.
|
||||||
|
///
|
||||||
|
/// Also panics if `row.len() == 0`
|
||||||
pub fn push_row(&mut self, row: Vec<T>) {
|
pub fn push_row(&mut self, row: Vec<T>) {
|
||||||
|
assert_ne!(row.len(), 0);
|
||||||
if self.rows > 0 && row.len() != self.cols {
|
if self.rows > 0 && row.len() != self.cols {
|
||||||
panic!(
|
panic!(
|
||||||
"pushed row does not match. Length must be {:?}, but was {:?}.",
|
"pushed row does not match. Length must be {:?}, but was {:?}.",
|
||||||
|
@ -508,7 +514,10 @@ impl<T> Grid<T> {
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if the grid is not empty and `col.len() != grid.rows()`.
|
/// Panics if the grid is not empty and `col.len() != grid.rows()`.
|
||||||
|
///
|
||||||
|
/// Also panics if `col.len() == 0`
|
||||||
pub fn push_col(&mut self, col: Vec<T>) {
|
pub fn push_col(&mut self, col: Vec<T>) {
|
||||||
|
assert_ne!(col.len(), 0);
|
||||||
if self.cols > 0 && col.len() != self.rows {
|
if self.cols > 0 && col.len() != self.rows {
|
||||||
panic!(
|
panic!(
|
||||||
"pushed column does not match. Length must be {:?}, but was {:?}.",
|
"pushed column does not match. Length must be {:?}, but was {:?}.",
|
||||||
|
@ -590,7 +599,14 @@ impl<T> Grid<T> {
|
||||||
/// assert_eq!(grid[2], [4,5,6]);
|
/// assert_eq!(grid[2], [4,5,6]);
|
||||||
/// assert_eq!(grid.size(), (3,3))
|
/// assert_eq!(grid.size(), (3,3))
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the grid is not empty and `row.len() != grid.cols()`.
|
||||||
|
///
|
||||||
|
/// Also panics if `row.len() == 0`
|
||||||
pub fn insert_row(&mut self, index: usize, row: Vec<T>) {
|
pub fn insert_row(&mut self, index: usize, row: Vec<T>) {
|
||||||
|
assert_ne!(row.len(), 0);
|
||||||
if row.len() != self.cols {
|
if row.len() != self.cols {
|
||||||
panic!("Inserted row must be of length {}, but was {}.", self.cols, row.len());
|
panic!("Inserted row must be of length {}, but was {}.", self.cols, row.len());
|
||||||
}
|
}
|
||||||
|
@ -616,7 +632,14 @@ impl<T> Grid<T> {
|
||||||
/// assert_eq!(grid[1], [4,9,5,6]);
|
/// assert_eq!(grid[1], [4,9,5,6]);
|
||||||
/// assert_eq!(grid.size(), (2,4))
|
/// assert_eq!(grid.size(), (2,4))
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the grid is not empty and `col.len() != grid.rows()`.
|
||||||
|
///
|
||||||
|
/// Also panics if `col.len() == 0`
|
||||||
pub fn insert_col(&mut self, index: usize, col: Vec<T>) {
|
pub fn insert_col(&mut self, index: usize, col: Vec<T>) {
|
||||||
|
assert_ne!(col.len(), 0);
|
||||||
if col.len() != self.rows {
|
if col.len() != self.rows {
|
||||||
panic!("Inserted col must be of length {}, but was {}.", self.rows, col.len());
|
panic!("Inserted col must be of length {}, but was {}.", self.rows, col.len());
|
||||||
}
|
}
|
||||||
|
@ -767,6 +790,20 @@ impl<T: Eq> Eq for Grid<T> {}
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn from_vec_zero_with_cols() {
|
||||||
|
let _: Grid<u8> = Grid::from_vec(vec![], 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn from_vec_zero() {
|
||||||
|
let grid: Grid<u8> = Grid::from_vec(vec![], 0);
|
||||||
|
grid.is_empty();
|
||||||
|
assert_eq!(grid.rows(), 0);
|
||||||
|
assert_eq!(grid.cols(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn insert_col_at_end() {
|
fn insert_col_at_end() {
|
||||||
let mut grid: Grid<u8> = Grid::from_vec(vec![1, 2, 3, 4], 2);
|
let mut grid: Grid<u8> = Grid::from_vec(vec![1, 2, 3, 4], 2);
|
||||||
|
@ -983,6 +1020,13 @@ mod test {
|
||||||
grid.push_col(vec!['b', 'b']);
|
grid.push_col(vec!['b', 'b']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn push_col_zero_len() {
|
||||||
|
let mut grid: Grid<char> = grid![];
|
||||||
|
grid.push_col(vec![]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn push_row_empty() {
|
fn push_row_empty() {
|
||||||
let mut grid: Grid<char> = grid![];
|
let mut grid: Grid<char> = grid![];
|
||||||
|
@ -991,6 +1035,13 @@ mod test {
|
||||||
assert_eq!(grid[0][0], 'b');
|
assert_eq!(grid[0][0], 'b');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn push_empty_row() {
|
||||||
|
let mut grid = Grid::init(0, 1, 0);
|
||||||
|
grid.push_row(vec![]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn push_row_wrong_size() {
|
fn push_row_wrong_size() {
|
||||||
|
@ -1170,6 +1221,14 @@ mod test {
|
||||||
Grid::init(1, 2, 'a');
|
Grid::init(1, 2, 'a');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn init_empty() {
|
||||||
|
let grid = Grid::init(0, 1, 0);
|
||||||
|
assert!(grid.is_empty());
|
||||||
|
assert_eq!(grid.cols(), 0);
|
||||||
|
assert_eq!(grid.rows(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn new() {
|
fn new() {
|
||||||
let grid: Grid<u8> = Grid::new(1, 2);
|
let grid: Grid<u8> = Grid::new(1, 2);
|
||||||
|
@ -1182,6 +1241,14 @@ mod test {
|
||||||
let _ : Grid<u8>= Grid::new(usize::MAX, 2);
|
let _ : Grid<u8>= Grid::new(usize::MAX, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn new_empty() {
|
||||||
|
let grid : Grid<u8> = Grid::new(0, 1);
|
||||||
|
assert!(grid.is_empty());
|
||||||
|
assert_eq!(grid.cols(), 0);
|
||||||
|
assert_eq!(grid.rows(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn init_panics() {
|
fn init_panics() {
|
||||||
|
|
Loading…
Reference in a new issue