Struct grid::Grid

source ·
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>

source

pub fn new(rows: usize, cols: usize) -> Self
where 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.

source

pub fn new_with_order(rows: usize, cols: usize, order: Order) -> Self
where T: Default,

Same as new but with a specific Order.

§Panics

Panics if rows * cols > usize::MAX.

source

pub fn init(rows: usize, cols: usize, data: T) -> Self
where 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.

source

pub fn init_with_order(rows: usize, cols: usize, order: Order, data: T) -> Self
where T: Clone,

Same as init but with a specific Order.

§Panics

Panics if rows * cols > usize::MAX.

source

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

source

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

source

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.

source

pub fn from_vec_with_order(vec: Vec<T>, cols: usize, order: Order) -> Self

Same as from_vec but with a specific Order.

§Panics

This panics if the vector length isn’t a multiple of the number of columns.

source

pub(crate) fn get_index(&self, row: usize, col: usize) -> usize

Returns the index of the coordinates in the internal vector.

source

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.

source

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.

source

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.

source

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.

source

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.

source

pub fn rows(&self) -> usize

Returns the number of rows of the grid.

source

pub fn cols(&self) -> usize

Returns the number of columns of the grid.

source

pub fn order(&self) -> Order

Returns the internal memory layout of the grid.

source

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());
source

pub fn clear(&mut self)

Clears the grid.

This doesn’t change the grid order.

source

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);
source

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;
source

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.

source

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.

source

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.

source

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.

source

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}");
}
source

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);
source

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
source

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
source

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.

source

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.

source

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.

source

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.

source

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
source

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
source

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]);
source

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.

source

pub fn transpose(&mut self)

Transpose the grid so that columns become rows in new grid.

This method changes the internal memory layout.

source

pub fn flip_cols(&mut self)

Flip (or mirrors) the columns.

§Examples
use grid::*;
let mut grid = grid![[1,2,3][4,5,6]];
grid.flip_cols();
assert_eq!(grid, grid![[3,2,1][6,5,4]])
§Performance

This method will be significantly slower if the grid uses a column-major memory layout.

source

pub fn flip_rows(&mut self)

Flip (or mirrors) the rows.

§Examples
use grid::*;
let mut grid = grid![[1,2,3][4,5,6]];
grid.flip_rows();
assert_eq!(grid, grid![[4,5,6][1,2,3]])
§Performance

This method will be significantly slower if the grid uses a row-major memory layout, which is the default.

source

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.

source

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.

source

pub fn rotate_half(&mut self)

Rotate the grid 180°.

This method doesn’t change the internal memory layout.

§Examples
use grid::*;
let mut grid = grid![[1,2,3][4,5,6]];
grid.rotate_half();
assert_eq!(grid, grid![[6,5,4][3,2,1]]);
§Performance

The performances of this method is not affected by the internal memory layout.

source

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]]);
source

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]]);
source

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])
source

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])
source

pub fn swap( &mut self, (row_a, col_a): (usize, usize), (row_b, col_b): (usize, usize), )

Swaps two elements in the Grid. Similar to Vec::swap().

§Panics

Panics if either index is out of bounds.

Trait Implementations§

source§

impl<T: Clone> Clone for Grid<T>

source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug> Debug for Grid<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T> Default for Grid<T>

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl<T: Clone> From<&Vec<&Vec<T>>> for Grid<T>

source§

fn from(vec: &Vec<&Vec<T>>) -> Self

Converts to this type from the input type.
source§

impl<T: Clone> From<&Vec<Vec<T>>> for Grid<T>

source§

fn from(vec: &Vec<Vec<T>>) -> Self

Converts to this type from the input type.
source§

impl<T: Clone> From<(&Vec<T>, &usize)> for Grid<T>

source§

fn from(value: (&Vec<T>, &usize)) -> Self

Converts to this type from the input type.
source§

impl<T: Clone> From<(&Vec<T>, usize)> for Grid<T>

source§

fn from(value: (&Vec<T>, usize)) -> Self

Converts to this type from the input type.
source§

impl<T> From<(Vec<T>, usize)> for Grid<T>

source§

fn from(value: (Vec<T>, usize)) -> Self

Converts to this type from the input type.
source§

impl<T> From<Vec<Vec<T>>> for Grid<T>

source§

fn from(vec: Vec<Vec<T>>) -> Self

Converts to this type from the input type.
source§

impl<T: Hash> Hash for Grid<T>

source§

fn hash<H: Hasher>(&self, state: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<T> Index<(usize, usize)> for Grid<T>

source§

type Output = T

The returned type after indexing.
source§

fn index(&self, (row, col): (usize, usize)) -> &T

Performs the indexing (container[index]) operation. Read more
source§

impl<T> IndexMut<(usize, usize)> for Grid<T>

source§

fn index_mut(&mut self, (row, col): (usize, usize)) -> &mut T

Performs the mutable indexing (container[index]) operation. Read more
source§

impl<T: PartialEq> PartialEq for Grid<T>

source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

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> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> CloneToUninit for T
where T: Clone,

source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

source§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.