pub struct Grid<T> {
pub(crate) data: Vec<T>,
pub(crate) cols: usize,
pub(crate) rows: usize,
pub(crate) order: Order,
}
Expand description
Stores elements of a certain type in a 2D grid structure.
Uses a rust Vec<T>
type to reference the grid data on the heap.
Also the internal memory layout as well as the number of
rows and columns are stored in the grid data structure.
The size limit of a grid is rows * cols < usize
.
Fields§
§data: Vec<T>
§cols: usize
§rows: usize
§order: Order
Implementations§
source§impl<T> Grid<T>
impl<T> Grid<T>
sourcepub fn new(rows: usize, cols: usize) -> Selfwhere
T: Default,
pub fn new(rows: usize, cols: usize) -> Selfwhere
T: Default,
Init a grid of size rows x columns with default values of the given type. For example this will generate a 2x3 grid of zeros:
use grid::Grid;
let grid : Grid<u8> = Grid::new(2,3);
assert_eq!(grid[(0, 0)], 0);
If rows == 0
or cols == 0
the grid will be empty with no cols and rows.
This create a grid with a row-major memory layout.
If you need a column-major one, see new_with_order
.
§Panics
Panics if rows * cols > usize::MAX
.
sourcepub fn init(rows: usize, cols: usize, data: T) -> Selfwhere
T: Clone,
pub fn init(rows: usize, cols: usize, data: T) -> Selfwhere
T: Clone,
Init a grid of size rows x columns with the given data element.
If rows == 0
or cols == 0
the grid will be empty with no cols and rows.
This create a grid with a row-major memory layout.
If you need a column-major one, see init_with_order
.
§Panics
Panics if rows * cols > usize::MAX
.
sourcepub fn init_with_order(rows: usize, cols: usize, order: Order, data: T) -> Selfwhere
T: Clone,
pub fn init_with_order(rows: usize, cols: usize, order: Order, data: T) -> Selfwhere
T: Clone,
sourcepub fn with_capacity(rows: usize, cols: usize) -> Self
pub fn with_capacity(rows: usize, cols: usize) -> Self
Initialises an empty Grid with the capacity to store cols * rows
elements.
Similar to Vec::with_capacity
.
§Panics
Panics if rows * cols > usize::MAX
or if rows * cols * size_of::<T>() > isize::MAX
sourcepub fn with_capacity_and_order(rows: usize, cols: usize, order: Order) -> Self
pub fn with_capacity_and_order(rows: usize, cols: usize, order: Order) -> Self
Same as with_capacity
but with a specified Order
§Panics
Panics if rows * cols > usize::MAX
or if rows * cols * size_of::<T>() > isize::MAX
sourcepub fn from_vec(vec: Vec<T>, cols: usize) -> Self
pub fn from_vec(vec: Vec<T>, cols: usize) -> Self
Returns a grid from a vector with a given column length.
The length of vec
must be a multiple of cols
.
This create a grid with a row-major memory layout.
If you need a column-major one, see from_vec_with_order
.
For example:
use grid::Grid;
let grid = Grid::from_vec(vec![1,2,3,4,5,6], 3);
assert_eq!(grid.size(), (2, 3));
will create a grid with the following layout: [1,2,3] [4,5,6]
This example will fail, because vec.len()
is not a multiple of cols
:
use grid::Grid;
Grid::from_vec(vec![1,2,3,4,5], 3);
§Panics
This panics if the vector length isn’t a multiple of the number of columns.
sourcepub fn from_vec_with_order(vec: Vec<T>, cols: usize, order: Order) -> Self
pub fn from_vec_with_order(vec: Vec<T>, cols: usize, order: Order) -> Self
sourcepub(crate) fn get_index(&self, row: usize, col: usize) -> usize
pub(crate) fn get_index(&self, row: usize, col: usize) -> usize
Returns the index of the coordinates in the internal vector.
sourcepub unsafe fn get_unchecked(
&self,
row: impl Into<usize>,
col: impl Into<usize>,
) -> &T
pub unsafe fn get_unchecked( &self, row: impl Into<usize>, col: impl Into<usize>, ) -> &T
Returns a reference to an element, without performing bound checks. Generally not recommended, use with caution!
§Safety
Calling this method with an out-of-bounds index is undefined behavior even if the resulting reference is not used.
sourcepub unsafe fn get_unchecked_mut(
&mut self,
row: impl Into<usize>,
col: impl Into<usize>,
) -> &mut T
pub unsafe fn get_unchecked_mut( &mut self, row: impl Into<usize>, col: impl Into<usize>, ) -> &mut T
Returns a mutable reference to an element, without performing bound checks. Generally not recommended, use with caution!
§Safety
Calling this method with an out-of-bounds index is undefined behavior even if the resulting reference is not used.
sourcepub fn get(
&self,
row: impl TryInto<usize>,
col: impl TryInto<usize>,
) -> Option<&T>
pub fn get( &self, row: impl TryInto<usize>, col: impl TryInto<usize>, ) -> Option<&T>
Access a certain element in the grid.
Returns None
if an element beyond the grid bounds is tried to be accessed.
sourcepub fn get_mut(
&mut self,
row: impl TryInto<usize>,
col: impl TryInto<usize>,
) -> Option<&mut T>
pub fn get_mut( &mut self, row: impl TryInto<usize>, col: impl TryInto<usize>, ) -> Option<&mut T>
Mutable access to a certain element in the grid.
Returns None
if an element beyond the grid bounds is tried to be accessed.
sourcepub fn size(&self) -> (usize, usize)
pub fn size(&self) -> (usize, usize)
Returns the size of the grid as a two element tuple. First element are the number of rows and the second the columns.
sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true
if the grid contains no elements.
For example:
use grid::*;
let grid : Grid<u8> = grid![];
assert!(grid.is_empty());
sourcepub fn iter(&self) -> Iter<'_, T>
pub fn iter(&self) -> Iter<'_, T>
Returns an iterator over the whole grid, starting from the first row and column.
The iteration order is dependant on the internal memory layout.
If you need a specific order, see iter_rows
or
iter_cols
.
use grid::*;
let grid: Grid<u8> = grid![[1,2][3,4]];
let mut iter = grid.iter();
assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next(), Some(&4));
assert_eq!(iter.next(), None);
sourcepub fn iter_mut(&mut self) -> IterMut<'_, T>
pub fn iter_mut(&mut self) -> IterMut<'_, T>
Returns an mutable iterator over the whole grid that allows modifying each value.
The iteration order is dependant on the internal memory layout.
use grid::*;
let mut grid: Grid<u8> = grid![[1,2][3,4]];
let mut iter = grid.iter_mut();
let next = iter.next();
assert_eq!(next, Some(&mut 1));
*next.unwrap() = 10;
sourcepub fn iter_col(&self, col: usize) -> StepBy<Iter<'_, T>>
pub fn iter_col(&self, col: usize) -> StepBy<Iter<'_, T>>
Returns an iterator over a column.
§Examples
use grid::*;
let grid: Grid<u8> = grid![[1, 2, 3][3, 4, 5]];
let mut col_iter = grid.iter_col(1);
assert_eq!(col_iter.next(), Some(&2));
assert_eq!(col_iter.next(), Some(&4));
assert_eq!(col_iter.next(), None);
§Performance
This method will be significantly slower if the grid uses a row-major memory layout, which is the default.
§Panics
Panics if the col index is out of bounds.
sourcepub fn iter_col_mut(&mut self, col: usize) -> StepBy<IterMut<'_, T>>
pub fn iter_col_mut(&mut self, col: usize) -> StepBy<IterMut<'_, T>>
Returns a mutable iterator over a column.
§Examples
use grid::*;
let mut grid: Grid<u8> = grid![[1, 2, 3][3, 4, 5]];
let mut col_iter = grid.iter_col_mut(1);
let next = col_iter.next();
assert_eq!(next, Some(&mut 2));
*next.unwrap() = 10;
assert_eq!(grid[(0, 1)], 10);
§Performance
This method will be significantly slower if the grid uses a row-major memory layout, which is the default.
§Panics
Panics if the col index is out of bounds.
sourcepub fn iter_row(&self, row: usize) -> StepBy<Iter<'_, T>>
pub fn iter_row(&self, row: usize) -> StepBy<Iter<'_, T>>
Returns an iterator over a row.
§Examples
use grid::*;
let grid: Grid<u8> = grid![[1, 2, 3][3, 4, 5]];
let mut col_iter = grid.iter_row(1);
assert_eq!(col_iter.next(), Some(&3));
assert_eq!(col_iter.next(), Some(&4));
assert_eq!(col_iter.next(), Some(&5));
assert_eq!(col_iter.next(), None);
§Performance
This method will be significantly slower if the grid uses a column-major memory layout.
§Panics
Panics if the row index is out of bounds.
sourcepub fn iter_row_mut(&mut self, row: usize) -> StepBy<IterMut<'_, T>>
pub fn iter_row_mut(&mut self, row: usize) -> StepBy<IterMut<'_, T>>
Returns a mutable iterator over a row.
§Examples
use grid::*;
let mut grid: Grid<u8> = grid![[1, 2, 3][3, 4, 5]];
let mut col_iter = grid.iter_row_mut(1);
let next = col_iter.next();
*next.unwrap() = 10;
assert_eq!(grid[(1, 0)], 10);
§Performance
This method will be significantly slower if the grid uses a column-major memory layout.
§Panics
Panics if the row index is out of bounds.
sourcepub fn indexed_iter(&self) -> impl Iterator<Item = ((usize, usize), &T)>
pub fn indexed_iter(&self) -> impl Iterator<Item = ((usize, usize), &T)>
Traverse the grid with row and column indexes.
The iteration order is dependent on the internal memory layout, but the indexes will be accurate either way.
§Examples
use grid::*;
let grid: Grid<u8> = grid![[1,2][3,4]];
let mut iter = grid.indexed_iter();
assert_eq!(iter.next(), Some(((0, 0), &1)));
Or simply unpack in a for
loop:
use grid::*;
let grid: Grid<u8> = grid![[1,2][3,4]];
for ((row, col), i) in grid.indexed_iter() {
println!("value at row {row} and column {col} is: {i}");
}
sourcepub fn indexed_iter_mut(
&mut self,
) -> impl Iterator<Item = ((usize, usize), &mut T)>
pub fn indexed_iter_mut( &mut self, ) -> impl Iterator<Item = ((usize, usize), &mut T)>
Traverse the grid with row and column indexes, and mutable access to each element.
The iteration order is dependent on the internal memory layout, but the indexes will be accurate either way.
§Examples
use grid::*;
let mut grid: Grid<u8> = grid![[1,2][3,4]];
let mut iter = grid.indexed_iter_mut();
assert_eq!(iter.next(), Some(((0, 0), &mut 1)));
Or simply unpack in a for
loop:
use grid::*;
let mut grid: Grid<u8> = grid![[1,2][3,4]];
for ((row, col), i) in grid.indexed_iter_mut() {
*i += 1;
println!("value at row {row} and column {col} is: {i}");
}
assert_eq!(grid[(0, 0)], 2);
assert_eq!(grid[(0, 1)], 3);
assert_eq!(grid[(1, 0)], 4);
assert_eq!(grid[(1, 1)], 5);
sourcepub fn push_row(&mut self, row: Vec<T>)
pub fn push_row(&mut self, row: Vec<T>)
Add a new row to the grid.
§Examples
use grid::*;
let mut grid: Grid<u8> = grid![[1, 2, 3][3, 4, 5]];
let row = vec![6,7,8];
grid.push_row(row);
assert_eq!(grid.rows(), 3);
assert_eq!(grid[(2, 0)], 6);
assert_eq!(grid[(2, 1)], 7);
assert_eq!(grid[(2, 2)], 8);
Can also be used to init an empty grid:
use grid::*;
let mut grid: Grid<u8> = grid![];
let row = vec![1,2,3];
grid.push_row(row);
assert_eq!(grid.size(), (1, 3));
§Performance
This method will be significantly slower if the grid uses a column-major memory layout.
§Panics
Panics if:
- the grid is not empty and
row.len() != grid.cols()
row.len() == 0
sourcepub fn push_col(&mut self, col: Vec<T>)
pub fn push_col(&mut self, col: Vec<T>)
Add a new column to the grid.
§Examples
use grid::*;
let mut grid: Grid<u8> = grid![[1, 2, 3][3, 4, 5]];
let col = vec![4,6];
grid.push_col(col);
assert_eq!(grid.cols(), 4);
assert_eq!(grid[(0, 3)], 4);
assert_eq!(grid[(1, 3)], 6);
Can also be used to init an empty grid:
use grid::*;
let mut grid: Grid<u8> = grid![];
let col = vec![1,2,3];
grid.push_col(col);
assert_eq!(grid.size(), (3, 1));
§Performance
This method will be significantly slower if the grid uses a row-major memory layout, which is the default.
§Panics
Panics if:
- the grid is not empty and
col.len() != grid.rows()
col.len() == 0
sourcepub fn pop_row(&mut self) -> Option<Vec<T>>
pub fn pop_row(&mut self) -> Option<Vec<T>>
Removes the last row from a grid and returns it, or None if it is empty.
§Examples
use grid::*;
let mut grid = grid![[1,2,3][4,5,6]];
assert_eq![grid.pop_row(), Some(vec![4,5,6])];
assert_eq![grid.pop_row(), Some(vec![1,2,3])];
assert_eq![grid.pop_row(), None];
§Performance
This method will be significantly slower if the grid uses a column-major memory layout.
sourcepub fn remove_row(&mut self, row_index: usize) -> Option<Vec<T>>
pub fn remove_row(&mut self, row_index: usize) -> Option<Vec<T>>
Remove a Row at the index and return a vector of it.
§Examples
use grid::*;
let mut grid = grid![[1,2][3,4][5,6]];
assert_eq![grid.remove_row(1), Some(vec![3,4])];
assert_eq![grid.remove_row(0), Some(vec![1,2])];
assert_eq![grid.remove_row(0), Some(vec![5,6])];
assert_eq![grid.remove_row(0), None];
§Performance
This method will be significantly slower if the grid uses a column-major memory layout.
sourcepub fn pop_col(&mut self) -> Option<Vec<T>>
pub fn pop_col(&mut self) -> Option<Vec<T>>
Removes the last column from a grid and returns it, or None if it is empty.
Note that this operation is much slower than the pop_row()
because the memory layout
of Grid
is row-major and removing a column requires a lot of move operations.
§Examples
use grid::*;
let mut grid = grid![[1,2,3][4,5,6]];
assert_eq![grid.pop_col(), Some(vec![3,6])];
assert_eq![grid.pop_col(), Some(vec![2,5])];
assert_eq![grid.pop_col(), Some(vec![1,4])];
assert_eq![grid.pop_col(), None];
§Performance
This method will be significantly slower if the grid uses a row-major memory layout, which is the default.
sourcepub fn remove_col(&mut self, col_index: usize) -> Option<Vec<T>>
pub fn remove_col(&mut self, col_index: usize) -> Option<Vec<T>>
Remove a column at the index and return a vector of it.
§Examples
use grid::*;
let mut grid = grid![[1,2,3,4][5,6,7,8][9,10,11,12][13,14,15,16]];
assert_eq![grid.remove_col(3), Some(vec![4,8,12,16])];
assert_eq![grid.remove_col(0), Some(vec![1,5,9,13])];
assert_eq![grid.remove_col(1), Some(vec![3,7,11,15])];
assert_eq![grid.remove_col(0), Some(vec![2,6,10,14])];
assert_eq![grid.remove_col(0), None];
§Performance
This method will be significantly slower if the grid uses a row-major memory layout, which is the default.
sourcepub fn insert_row(&mut self, index: usize, row: Vec<T>)
pub fn insert_row(&mut self, index: usize, row: Vec<T>)
Insert a new row at the index and shifts all rows after down.
§Examples
use grid::*;
let mut grid = grid![[1,2,3][4,5,6]];
grid.insert_row(1, vec![7,8,9]);
assert_eq!(grid, grid![[1,2,3][7,8,9][4,5,6]]);
§Performance
This method will be significantly slower if the grid uses a column-major memory layout.
§Panics
Panics if:
- the grid is not empty and
row.len() != grid.cols()
. - the index is greater than the number of rows
sourcepub fn insert_col(&mut self, index: usize, col: Vec<T>)
pub fn insert_col(&mut self, index: usize, col: Vec<T>)
Insert a new column at the index.
Important! Insertion of columns is a lot slower than the lines insertion. This is because of the memory layout of the grid data structure.
§Examples
use grid::*;
let mut grid = grid![[1,2,3][4,5,6]];
grid.insert_col(1, vec![9,9]);
assert_eq!(grid, grid![[1,9,2,3][4,9,5,6]])
§Performance
This method will be significantly slower if the grid uses a row-major memory layout, which is the default.
§Panics
Panics if:
- the grid is not empty and
col.len() != grid.rows()
. - the index is greater than the number of columns
sourcepub fn flatten(&self) -> &Vec<T>
pub fn flatten(&self) -> &Vec<T>
Returns a reference to the internal data structure of the grid.
The order of the elements depends on the internal memory layout, which is row-major by default.
§Examples
use grid::*;
let grid = grid![[1,2,3][4,5,6]];
let flat = grid.flatten();
assert_eq!(flat, &vec![1,2,3,4,5,6]);
sourcepub fn into_vec(self) -> Vec<T>
pub fn into_vec(self) -> Vec<T>
Converts self into a vector without clones or allocation.
The order of the elements depends on the internal memory layout, which is row-major by default.
sourcepub fn transpose(&mut self)
pub fn transpose(&mut self)
Transpose the grid so that columns become rows in new grid.
This method changes the internal memory layout.
sourcepub fn rotate_left(&mut self)
pub fn rotate_left(&mut self)
Rotate the grid 90° counter-clockwise.
This method changes the internal memory layout.
§Examples
use grid::*;
let mut grid = grid![[1,2][3,4]];
grid.rotate_left();
assert_eq!(grid, grid![[2,4][1,3]]);
§Performance
This method will be significantly slower if the grid initialy uses a column-major memory layout, which is the default.
sourcepub fn rotate_right(&mut self)
pub fn rotate_right(&mut self)
Rotate the grid 90° clockwise.
This method changes the internal memory layout.
§Examples
use grid::*;
let mut grid = grid![[1,2][3,4]];
grid.rotate_right();
assert_eq!(grid, grid![[3,1][4,2]]);
§Performance
This method will be significantly slower if the grid initialy uses a row-major memory layout, which is the default.
sourcepub fn rotate_half(&mut self)
pub fn rotate_half(&mut self)
sourcepub fn fill(&mut self, value: T)where
T: Clone,
pub fn fill(&mut self, value: T)where
T: Clone,
Fills the grid with elements by cloning value
.
§Examples
use grid::*;
let mut grid = grid![[1,2,3][4,5,6]];
grid.fill(7);
assert_eq!(grid, grid![[7,7,7][7,7,7]]);
sourcepub fn fill_with<F>(&mut self, f: F)where
F: FnMut() -> T,
pub fn fill_with<F>(&mut self, f: F)where
F: FnMut() -> T,
Fills the grid with elements returned by calling a closure repeatedly.
This method uses a closure to create new values. If you’d rather
Clone
a given value, use fill
. If you want to use the Default
trait to generate values, you can pass Default::default
as the
argument.
§Examples
use grid::*;
let mut grid = grid![[1,2,3][4,5,6]];
grid.fill_with(Default::default);
assert_eq!(grid, grid![[0,0,0][0,0,0]]);
sourcepub fn iter_rows(&self) -> GridRowIter<'_, T> ⓘ
pub fn iter_rows(&self) -> GridRowIter<'_, T> ⓘ
Iterate over the rows of the grid. Each time an iterator over a single row is returned.
An item in this iterator is equal to a call to Grid.iter_row(row_index)
of the corresponding row.
§Examples
use grid::*;
let mut grid = grid![[1,2,3][4,5,6]];
let sum_by_row: Vec<u8> = grid.iter_rows().map(|row| row.sum()).collect();
assert_eq!(sum_by_row, vec![1+2+3, 4+5+6])
sourcepub fn iter_cols(&self) -> GridColIter<'_, T> ⓘ
pub fn iter_cols(&self) -> GridColIter<'_, T> ⓘ
Iterate over the columns of the grid. Each time an iterator over a single column is returned.
An item in this iterator is equal to a call to Grid.iter_col(col_index)
of the corresponding column.
§Examples
use grid::*;
let mut grid = grid![[1,2,3][4,5,6]];
let sum_by_col: Vec<u8> = grid.iter_cols().map(|col| col.sum()).collect();
assert_eq!(sum_by_col, vec![1+4, 2+5, 3+6])
Trait Implementations§
impl<T: Eq> Eq for Grid<T>
Auto Trait Implementations§
impl<T> Freeze for Grid<T>
impl<T> RefUnwindSafe for Grid<T>where
T: RefUnwindSafe,
impl<T> Send for Grid<T>where
T: Send,
impl<T> Sync for Grid<T>where
T: Sync,
impl<T> Unpin for Grid<T>where
T: Unpin,
impl<T> UnwindSafe for Grid<T>where
T: UnwindSafe,
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)