Import 'grid' crate

Request Document: go/android-rust-importing-crates
For CL Reviewers: go/android3p#cl-review
Bug: 395134064
Test: m libgrid -j

Change-Id: Ia0b4dc83c7f4d88991065ad45a1b491b85beb503
diff --git a/crates/grid/.android-checksum.json b/crates/grid/.android-checksum.json
new file mode 100644
index 0000000..6a36c50
--- /dev/null
+++ b/crates/grid/.android-checksum.json
@@ -0,0 +1 @@
+{"package":null,"files":{".cargo-checksum.json":"8b0d4f770e4717dfadc316449d56be8f25455b240c705988ebf48c4f248e4fc3","Android.bp":"bb317acfae50c8113d8c01c7b42cf1996fbf79e893a6a849bdd4e3134c912dff","Cargo.toml":"dd5e534a80da98507c3e49ac93ea203787a77d75b546be06dce55ccafa6e2c88","LICENSE":"d59b3f573f9e3f7318d9c24f042f710e1184bc5522cef96be7954dc6ba77c927","METADATA":"956d838673e3619c2126e1eb50588b65839984b2fa822aa952fa2906ace3317b","MODULE_LICENSE_MIT":"0d6f8afa3940b7f06bebee651376d43bc8b0d5b437337be2696d30377451e93a","README.md":"349942b55ac9eaf352b1ccaf8a67b15fa9d953fffc9ab08348af57c7f7654476","benches/benches.rs":"acb1661440bbfec83b267be4fa8d1a8de22dd2c2467ff01b587891a9fc3674d2","cargo_embargo.json":"0be745f01ba4955b20f2cb5011168c4d8cd396af75c007035ec693c67b17bce7","src/lib.rs":"99633cf7f4fb283046c49513c7ba451cf08374d506dc1df5d1ebc38d117ca454"}}
\ No newline at end of file
diff --git a/crates/grid/.cargo-checksum.json b/crates/grid/.cargo-checksum.json
new file mode 100644
index 0000000..381356b
--- /dev/null
+++ b/crates/grid/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"69fec42da5d88c7c01abb0e2482d0dbb7dfaf16495fb4e83da3df64b91566b77","LICENSE":"965116a3d1e412221d5ff2e58edfab30a62fe112f0f6bf13136a946907869da9","README.md":"7291a0c7fce70323458500e07eb8822213a851600d8b00aef45b05c1209929fb","benches/benches.rs":"d492daebc19d65853c8a1baee99e9f1a09d182413121f23f465357706c9d9698","src/lib.rs":"9d86db518aa0585f064e2c283099e1e4f76c57e857f19193b32dd2bd7764927b"},"package":"fb6ae361963ea5fe52038156ea1729f3b4e4ccc0711c362ab2b2d2c0a259e7c3"}
\ No newline at end of file
diff --git a/crates/grid/Android.bp b/crates/grid/Android.bp
new file mode 100644
index 0000000..bb1aa23
--- /dev/null
+++ b/crates/grid/Android.bp
@@ -0,0 +1,34 @@
+// This file is generated by cargo_embargo.
+// Do not modify this file because the changes will be overridden on upgrade.
+
+package {
+    default_applicable_licenses: ["external_rust_crates_grid_license"],
+    default_team: "trendy_team_android_rust",
+}
+
+license {
+    name: "external_rust_crates_grid_license",
+    visibility: [":__subpackages__"],
+    license_kinds: ["SPDX-license-identifier-MIT"],
+    license_text: ["LICENSE"],
+}
+
+rust_library {
+    name: "libgrid",
+    host_supported: true,
+    crate_name: "grid",
+    cargo_env_compat: true,
+    cargo_pkg_version: "0.16.1",
+    crate_root: "src/lib.rs",
+    edition: "2018",
+    features: [
+        "default",
+        "std",
+    ],
+    apex_available: [
+        "//apex_available:platform",
+        "//apex_available:anyapex",
+    ],
+    product_available: true,
+    vendor_available: true,
+}
diff --git a/crates/grid/Cargo.toml b/crates/grid/Cargo.toml
new file mode 100644
index 0000000..f074895
--- /dev/null
+++ b/crates/grid/Cargo.toml
@@ -0,0 +1,77 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+rust-version = "1.51"
+name = "grid"
+version = "0.16.1"
+authors = ["Armin Becher <armin.becher@gmai.com>"]
+build = false
+autolib = false
+autobins = false
+autoexamples = false
+autotests = false
+autobenches = false
+description = "Dynamic generic 2D data structure."
+documentation = "https://docs.rs/grid"
+readme = "README.md"
+keywords = [
+    "2D",
+    "array",
+    "matrix",
+    "data-structure",
+    "2D-vector",
+]
+categories = [
+    "science",
+    "data-structures",
+]
+license = "MIT"
+repository = "https://github.com/becheran/grid"
+
+[lib]
+name = "grid"
+path = "src/lib.rs"
+
+[[bench]]
+name = "benches"
+path = "benches/benches.rs"
+harness = false
+
+[dependencies.serde]
+version = "1.0.217"
+features = ["derive"]
+optional = true
+
+[dev-dependencies.criterion]
+version = "0.5.1"
+
+[dev-dependencies.rand]
+version = "0.9.0"
+
+[dev-dependencies.serde_json]
+version = "1.0.138"
+
+[features]
+default = ["std"]
+serde = [
+    "std",
+    "dep:serde",
+]
+std = []
+
+[badges.gitlab]
+branch = "master"
+repository = "becheran/grid_ci"
+
+[badges.maintenance]
+status = "actively-developed"
diff --git a/crates/grid/LICENSE b/crates/grid/LICENSE
new file mode 100644
index 0000000..9ffd7ce
--- /dev/null
+++ b/crates/grid/LICENSE
@@ -0,0 +1,21 @@
+MIT License

+

+Copyright (c) 2020 Armin Becher

+

+Permission is hereby granted, free of charge, to any person obtaining a copy

+of this software and associated documentation files (the "Software"), to deal

+in the Software without restriction, including without limitation the rights

+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell

+copies of the Software, and to permit persons to whom the Software is

+furnished to do so, subject to the following conditions:

+

+The above copyright notice and this permission notice shall be included in all

+copies or substantial portions of the Software.

+

+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE

+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE

+SOFTWARE.

diff --git a/crates/grid/METADATA b/crates/grid/METADATA
new file mode 100644
index 0000000..0c1c6bb
--- /dev/null
+++ b/crates/grid/METADATA
@@ -0,0 +1,17 @@
+name: "grid"
+description: "Dynamic generic 2D data structure."
+third_party {
+  version: "0.16.1"
+  license_type: NOTICE
+  last_upgrade_date {
+    year: 2025
+    month: 2
+    day: 11
+  }
+  homepage: "https://crates.io/crates/grid"
+  identifier {
+    type: "Archive"
+    value: "https://static.crates.io/crates/grid/grid-0.16.1.crate"
+    version: "0.16.1"
+  }
+}
diff --git a/crates/grid/MODULE_LICENSE_MIT b/crates/grid/MODULE_LICENSE_MIT
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/crates/grid/MODULE_LICENSE_MIT
diff --git a/crates/grid/README.md b/crates/grid/README.md
new file mode 100644
index 0000000..6e9304f
--- /dev/null
+++ b/crates/grid/README.md
@@ -0,0 +1,19 @@
+# Grid

+

+[![docs](https://docs.rs/grid/badge.svg)](https://docs.rs/grid)

+[![crates.io](https://badgen.net/crates/d/grid)](https://crates.io/crates/grid)

+[![build status](https://github.com/becheran/grid/actions/workflows/rust.yml/badge.svg)](https://github.com/becheran/grid/actions)

+[![license](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

+

+Data structure grid for rust. Provide a two dimensional data structure for rust that is easy to use and fast.

+Most of the functionality provided by the [std::vec::Vec](https://doc.rust-lang.org/std/vec/struct.Vec.html) type for one dimensional vectors

+is implemented for two dimensions in this crate.

+

+To use *grid* with *no_std* import the library such as:

+

+``` toml

+grid = { version = "*", default-features = false }

+```

+

+- [documentation](https://docs.rs/grid/)

+- [library on crates.io](https://crates.io/crates/grid)

diff --git a/crates/grid/benches/benches.rs b/crates/grid/benches/benches.rs
new file mode 100644
index 0000000..a912b6a
--- /dev/null
+++ b/crates/grid/benches/benches.rs
@@ -0,0 +1,207 @@
+use criterion::{criterion_group, criterion_main, Criterion};

+use grid::grid;

+use grid::Grid;

+use rand::Rng;

+

+const SIZE: usize = 1_000;

+

+fn init_vec_vec() -> Vec<Vec<u8>> {

+    vec![vec![0; SIZE]; SIZE]

+}

+

+fn init_grid() -> Grid<u8> {

+    Grid::init(SIZE, SIZE, 0)

+}

+

+fn criterion_benchmark(c: &mut Criterion) {

+    let mut rng = rand::rng();

+    let mut rand = || rng.random_range(0..SIZE);

+

+    // Init macro

+    c.bench_function("vecvec_init_macro", |b| {

+        b.iter(|| {

+            vec![

+                vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9],

+                vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9],

+                vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9],

+                vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9],

+                vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9],

+                vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9],

+                vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9],

+                vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9],

+                vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9],

+                vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9],

+            ]

+        })

+    });

+    c.bench_function("grid_init_macro", |b| {

+        b.iter(|| {

+            grid![[0,1,2,3,4,5,6,7,8,9]

+            [0,1,2,3,4,5,6,7,8,9]

+            [0,1,2,3,4,5,6,7,8,9]

+            [0,1,2,3,4,5,6,7,8,9]

+            [0,1,2,3,4,5,6,7,8,9]

+            [0,1,2,3,4,5,6,7,8,9]

+            [0,1,2,3,4,5,6,7,8,9]

+            [0,1,2,3,4,5,6,7,8,9]

+            [0,1,2,3,4,5,6,7,8,9]

+            [0,1,2,3,4,5,6,7,8,9]]

+        })

+    });

+    c.bench_function("grid_from_vec", |b| {

+        b.iter(|| {

+            let vec = vec![

+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7,

+                8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5,

+                6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3,

+                4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,

+            ];

+            Grid::from_vec(vec, 10)

+        })

+    });

+

+    // Constructor

+    c.bench_function("vecvec_init", |b| b.iter(|| vec![vec![0; SIZE]; SIZE]));

+    c.bench_function("grid_init", |b| b.iter(|| Grid::init(SIZE, SIZE, 0)));

+

+    // Index

+    c.bench_function("vecvec_idx", |b| {

+        let vec_vec = init_vec_vec();

+        b.iter_batched(

+            || (rand(), rand()),

+            |(x, y)| {

+                let _v = vec_vec[x][y];

+            },

+            criterion::BatchSize::SmallInput,

+        )

+    });

+    c.bench_function("grid_idx", |b| {

+        let grid = init_grid();

+        b.iter_batched(

+            || (rand(), rand()),

+            |(x, y)| grid[(x, y)],

+            criterion::BatchSize::SmallInput,

+        )

+    });

+    c.bench_function("vecvec_get", |b| {

+        let vec_vec = init_vec_vec();

+        b.iter_batched(

+            || (rand(), rand()),

+            |(x, y)| {

+                let _v = vec_vec.get(x).unwrap().get(y).unwrap();

+            },

+            criterion::BatchSize::SmallInput,

+        )

+    });

+    c.bench_function("grid_get", |b| {

+        let grid = init_grid();

+        b.iter_batched(

+            || (rand(), rand()),

+            |(x, y)| {

+                let _v = grid.get(x, y).unwrap();

+            },

+            criterion::BatchSize::SmallInput,

+        )

+    });

+

+    //Set

+    c.bench_function("vecvec_set", |b| {

+        let mut vec_vec = init_vec_vec();

+        b.iter_batched(

+            || (rand(), rand()),

+            |(x, y)| vec_vec[x][y] = 42,

+            criterion::BatchSize::SmallInput,

+        )

+    });

+    c.bench_function("grid_set", |b| {

+        let mut g = init_grid();

+        b.iter_batched(

+            || (rand(), rand()),

+            |(x, y)| g[(x, y)] = 42,

+            criterion::BatchSize::SmallInput,

+        )

+    });

+

+    // Push

+    c.bench_function("grid_push_row", |b| {

+        let grid = init_grid();

+        b.iter_batched(

+            || grid.clone(),

+            |mut g| g.push_row(vec![0; SIZE]),

+            criterion::BatchSize::SmallInput,

+        )

+    });

+    c.bench_function("grid_push_col", |b| {

+        let grid = init_grid();

+        b.iter_batched(

+            || grid.clone(),

+            |mut g| g.push_col(vec![0; SIZE]),

+            criterion::BatchSize::SmallInput,

+        )

+    });

+

+    // Pop

+    c.bench_function("grid_pop_row", |b| {

+        let grid = init_grid();

+        b.iter_batched(

+            || grid.clone(),

+            |mut g| g.pop_row(),

+            criterion::BatchSize::SmallInput,

+        )

+    });

+    c.bench_function("grid_pop_col", |b| {

+        let grid = init_grid();

+        b.iter_batched(

+            || grid.clone(),

+            |mut g| g.pop_col(),

+            criterion::BatchSize::SmallInput,

+        )

+    });

+

+    // Remove

+    c.bench_function("grid_remove_row", |b| {

+        let grid = init_grid();

+        b.iter_batched(

+            || grid.clone(),

+            |mut g| g.remove_row(2),

+            criterion::BatchSize::SmallInput,

+        )

+    });

+    c.bench_function("grid_remove_col", |b| {

+        let grid = init_grid();

+        b.iter_batched(

+            || grid.clone(),

+            |mut g| g.remove_col(2),

+            criterion::BatchSize::SmallInput,

+        )

+    });

+

+    // Rotation

+    c.bench_function("grid_rotate_left", |b| {

+        let grid = init_grid();

+        b.iter_batched(

+            || grid.clone(),

+            |mut g| g.rotate_left(),

+            criterion::BatchSize::SmallInput,

+        )

+    });

+    c.bench_function("grid_rotate_right", |b| {

+        let grid = init_grid();

+        b.iter_batched(

+            || grid.clone(),

+            |mut g| g.rotate_right(),

+            criterion::BatchSize::SmallInput,

+        )

+    });

+    c.bench_function("grid_rotate_half", |b| {

+        let grid = init_grid();

+        b.iter_batched(

+            || grid.clone(),

+            |mut g| g.rotate_half(),

+            criterion::BatchSize::SmallInput,

+        )

+    });

+}

+

+criterion_group!(benches, criterion_benchmark);

+criterion_main!(benches);

diff --git a/crates/grid/cargo_embargo.json b/crates/grid/cargo_embargo.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/crates/grid/cargo_embargo.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/crates/grid/src/lib.rs b/crates/grid/src/lib.rs
new file mode 100644
index 0000000..5cb6db7
--- /dev/null
+++ b/crates/grid/src/lib.rs
@@ -0,0 +1,3637 @@
+#![warn(clippy::all, clippy::pedantic, clippy::nursery)]

+/*!

+# Two Dimensional Grid

+Continuous growable 2D data structure.

+The purpose of this crate is to provide an universal data structure that is faster,

+uses less memory, and is easier to use than a naive `Vec<Vec<T>>` solution.

+

+This crate will always provide a 2D data structure. If you need three or more dimensions take a look at the

+[ndarray](https://docs.rs/ndarray/0.13.0/ndarray/) library. The `grid` crate is a container for all kind of data.

+If you need to perform matrix operations, you are better off with a linear algebra lib, such as

+[cgmath](https://docs.rs/cgmath/0.17.0/cgmath/) or [nalgebra](https://docs.rs/nalgebra/0.21.0/nalgebra/).

+No other dependencies except for the std lib are used.

+Most of the functions `std::Vec<T>` offer are also implemented in `grid` and slightly modified for a 2D data object.

+

+# Memory layout

+

+Similar to *C-like* arrays, `grid` uses a flat 1D `Vec<T>` data structure to have a continuous

+memory data layout. See also [this](https://stackoverflow.com/questions/17259877/1d-or-2d-array-whats-faster)

+explanation of why you should probably use a one-dimensional array approach.

+

+Note that this crate uses a [*row-major*](https://eli.thegreenplace.net/2015/memory-layout-of-multi-dimensional-arrays) memory layout by default.

+

+If you need a specific memory layout, please seek the `*_with_order` constructors. You should also take note that some transformation methods

+change the internal memory layout, like [`transpose`](Grid::transpose).

+

+This choice is important, because operations on rows are faster with a row-major memory layout.

+Likewise, operations on columns are faster with column-major memory layout.

+

+# Examples

+```

+use grid::*;

+let mut grid = grid![[1,2,3]

+                     [4,5,6]];

+assert_eq!(grid, Grid::from_vec(vec![1,2,3,4,5,6],3));

+assert_eq!(grid.get(0, 2), Some(&3));

+assert_eq!(grid[(1, 1)], 5);

+assert_eq!(grid.size(), (2, 3));

+grid.push_row(vec![7,8,9]);

+assert_eq!(grid, grid![[1,2,3][4,5,6][7,8,9]])

+ ```

+*/

+

+#![cfg_attr(not(feature = "std"), no_std)]

+

+#[cfg(not(feature = "std"))]

+extern crate alloc;

+#[cfg(not(feature = "std"))]

+use alloc::{format, vec, vec::Vec};

+#[cfg(feature = "serde")]

+use serde::{

+    de::{self, Deserialize, Deserializer, MapAccess, SeqAccess, Visitor},

+    ser::{Serialize, SerializeStruct, Serializer},

+};

+

+use core::cmp::Eq;

+use core::fmt;

+use core::hash;

+use core::iter::StepBy;

+use core::ops::Index;

+use core::ops::IndexMut;

+use core::slice::Iter;

+use core::slice::IterMut;

+use core::{cmp, convert::TryInto};

+

+#[doc(hidden)]

+#[macro_export]

+macro_rules! count {

+    () => (0usize);

+    ( $x:tt $($xs:tt)* ) => (1usize + $crate::count!($($xs)*));

+}

+

+/// Init a grid with values.

+///

+/// Each array within `[]` represents a row starting from top to button.

+///

+/// # Examples

+///

+/// In this example a grid of numbers from 1 to 9 is created:

+///

+///  

+/// ```

+/// use grid::grid;

+/// let grid = grid![[1, 2, 3]

+/// [4, 5, 6]

+/// [7, 8, 9]];

+/// assert_eq!(grid.size(), (3, 3))

+/// ```

+///

+/// Note that each row must be of the same length. The following example will not compile:

+///  

+/// ``` ignore

+/// use grid::grid;

+/// let grid = grid![[1, 2, 3]

+/// [4, 5] // This does not work!

+/// [7, 8, 9]];

+/// ```

+#[macro_export]

+macro_rules! grid {

+    () => {

+        $crate::Grid::from_vec(vec![], 0)

+    };

+    ( [$( $x:expr ),* ]) => { {

+        let vec = vec![$($x),*];

+        let len  = vec.len();

+        $crate::Grid::from_vec(vec, len)

+    } };

+    ( [$( $x0:expr ),*] $([$( $x:expr ),*])* ) => {

+        {

+            let mut _assert_width0 = [(); $crate::count!($($x0)*)];

+            let cols = $crate::count!($($x0)*);

+            let rows = 1usize;

+

+            $(

+                let _assert_width = [(); $crate::count!($($x)*)];

+                _assert_width0 = _assert_width;

+                let rows = rows + 1usize;

+            )*

+

+            let mut vec = Vec::with_capacity(rows.checked_mul(cols).unwrap());

+

+            $( vec.push($x0); )*

+            $( $( vec.push($x); )* )*

+

+            $crate::Grid::from_vec(vec, cols)

+        }

+    };

+}

+

+/// Init a column-major grid with values.

+///

+/// Each array within `[]` represents a row starting from top to button.

+///

+/// # Examples

+///

+/// In this example a grid of numbers from 1 to 9 is created:

+///

+/// ```

+/// use grid::grid_cm;

+/// let grid = grid_cm![[1, 2, 3]

+/// [4, 5, 6]

+/// [7, 8, 9]];

+/// assert_eq!(grid.size(), (3, 3));

+/// assert_eq!(grid[(1, 1)], 5);

+/// ```

+///

+/// Note that each row must be of the same length. The following example will not compile:

+///

+/// ``` ignore

+/// use grid::grid_cm;

+/// let grid = grid_cm![[1, 2, 3]

+/// [4, 5] // This does not work!

+/// [7, 8, 9]];

+/// ```

+#[macro_export]

+macro_rules! grid_cm {

+    () => {

+        $crate::Grid::from_vec_with_order(vec![], 0, $crate::Order::ColumnMajor)

+    };

+    ( [$( $x:expr ),* ]) => { {

+        let vec = vec![$($x),*];

+        let len  = vec.len();

+        $crate::Grid::from_vec_with_order(vec, len, $crate::Order::ColumnMajor)

+    } };

+    ( [$( $x0:expr ),*] $([$( $x:expr ),*])* ) => {

+        {

+            let mut _assert_width0 = [(); $crate::count!($($x0)*)];

+            let cols = $crate::count!($($x0)*);

+            let rows = 1usize;

+

+            $(

+                let _assert_width = [(); $crate::count!($($x)*)];

+                _assert_width0 = _assert_width;

+                let rows = rows + 1usize;

+            )*

+

+            let vec = Vec::with_capacity(rows.checked_mul(cols).unwrap());

+            let mut grid = $crate::Grid::from_vec_with_order(vec, cols, $crate::Order::ColumnMajor);

+

+            grid.push_row(vec![$($x0),*]);

+            $( grid.push_row(vec![$($x),*]); )*

+

+            grid

+        }

+    };

+}

+

+/// Define the internal memory layout of the grid.

+#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]

+#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]

+pub enum Order {

+    /// The data is ordered row by row.

+    #[default]

+    RowMajor,

+

+    /// The data is ordered column by column.

+    ColumnMajor,

+}

+

+impl Order {

+    const fn counterpart(self) -> Self {

+        match self {

+            Self::RowMajor => Self::ColumnMajor,

+            Self::ColumnMajor => Self::RowMajor,

+        }

+    }

+}

+

+/// 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`.

+pub struct Grid<T> {

+    data: Vec<T>,

+    cols: usize,

+    rows: usize,

+    order: Order,

+}

+

+#[cfg(feature = "serde")]

+impl<'de, T: Deserialize<'de>> Deserialize<'de> for Grid<T> {

+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>

+    where

+        D: Deserializer<'de>,

+    {

+        use std::marker::PhantomData;

+        #[derive(serde::Deserialize)]

+        #[serde(field_identifier, rename_all = "lowercase")]

+        enum Field {

+            Data,

+            Cols,

+            Order,

+        }

+

+        struct GridVisitor<T> {

+            _p: PhantomData<T>,

+        }

+

+        impl<'de, T: Deserialize<'de>> Visitor<'de> for GridVisitor<T> {

+            type Value = Grid<T>;

+

+            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {

+                formatter.write_str("struct Grid")

+            }

+

+            fn visit_seq<V>(self, mut seq: V) -> Result<Grid<T>, V::Error>

+            where

+                V: SeqAccess<'de>,

+            {

+                let cols = seq

+                    .next_element()?

+                    .ok_or_else(|| de::Error::invalid_length(0, &self))?;

+                let data = seq

+                    .next_element()?

+                    .ok_or_else(|| de::Error::invalid_length(1, &self))?;

+                let order = seq.next_element()?.unwrap_or_default();

+                Ok(Grid::from_vec_with_order(data, cols, order))

+            }

+

+            fn visit_map<V>(self, mut map: V) -> Result<Grid<T>, V::Error>

+            where

+                V: MapAccess<'de>,

+            {

+                let mut cols = None;

+                let mut data = None;

+                let mut order = None;

+                while let Some(key) = map.next_key()? {

+                    match key {

+                        Field::Data => {

+                            if data.is_some() {

+                                return Err(de::Error::duplicate_field("data"));

+                            }

+                            data = Some(map.next_value()?);

+                        }

+                        Field::Cols => {

+                            if cols.is_some() {

+                                return Err(de::Error::duplicate_field("cols"));

+                            }

+                            cols = Some(map.next_value()?);

+                        }

+                        Field::Order => {

+                            if order.is_some() {

+                                return Err(de::Error::duplicate_field("order"));

+                            }

+                            order = Some(map.next_value()?);

+                        }

+                    }

+                }

+                let cols = cols.ok_or_else(|| de::Error::missing_field("cols"))?;

+                let data = data.ok_or_else(|| de::Error::missing_field("data"))?;

+                let order = order.unwrap_or_default();

+                Ok(Grid::from_vec_with_order(data, cols, order))

+            }

+        }

+

+        const FIELDS: &[&str] = &["cols", "data", "order"];

+        deserializer.deserialize_struct("Grid", FIELDS, GridVisitor { _p: PhantomData })

+    }

+}

+

+#[cfg(feature = "serde")]

+impl<T: Serialize> Serialize for Grid<T> {

+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>

+    where

+        S: Serializer,

+    {

+        // 3 is the number of fields in the struct.

+        let mut state = serializer.serialize_struct("Grid", 3)?;

+        state.serialize_field("cols", &self.cols)?;

+        state.serialize_field("data", &self.data)?;

+        state.serialize_field("order", &self.order)?;

+        state.end()

+    }

+}

+

+impl<T> Grid<T> {

+    /// 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`](Grid::new_with_order).

+    ///

+    /// # Panics

+    ///

+    /// Panics if `rows * cols > usize::MAX`.

+    #[must_use]

+    #[inline]

+    pub fn new(rows: usize, cols: usize) -> Self

+    where

+        T: Default,

+    {

+        Self::new_with_order(rows, cols, Order::default())

+    }

+

+    /// Same as [`new`](Self::new) but with a specific [`Order`].

+    ///

+    /// # Panics

+    ///

+    /// Panics if `rows * cols > usize::MAX`.

+    pub fn new_with_order(rows: usize, cols: usize, order: Order) -> Self

+    where

+        T: Default,

+    {

+        if rows == 0 || cols == 0 {

+            return Self {

+                data: Vec::new(),

+                rows: 0,

+                cols: 0,

+                order,

+            };

+        }

+        let mut data = Vec::new();

+        data.resize_with(rows.checked_mul(cols).unwrap(), T::default);

+        Self {

+            data,

+            cols,

+            rows,

+            order,

+        }

+    }

+

+    /// 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`](Grid::init_with_order).

+    ///

+    /// # Panics

+    ///

+    /// Panics if `rows * cols > usize::MAX`.

+    #[inline]

+    pub fn init(rows: usize, cols: usize, data: T) -> Self

+    where

+        T: Clone,

+    {

+        Self::init_with_order(rows, cols, Order::default(), data)

+    }

+

+    /// Same as [`init`](Self::init) but with a specific [`Order`].

+    ///

+    /// # Panics

+    ///

+    /// Panics if `rows * cols > usize::MAX`.

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

+    where

+        T: Clone,

+    {

+        if rows == 0 || cols == 0 {

+            return Self {

+                data: Vec::new(),

+                rows: 0,

+                cols: 0,

+                order,

+            };

+        }

+        Self {

+            data: vec![data; rows.checked_mul(cols).unwrap()],

+            cols,

+            rows,

+            order,

+        }

+    }

+

+    /// 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`

+    #[must_use]

+    pub fn with_capacity(rows: usize, cols: usize) -> Self {

+        Self::with_capacity_and_order(rows, cols, Order::default())

+    }

+

+    /// Same as [`with_capacity`](Self::with_capacity) but with a specified [`Order`]

+    ///

+    /// # Panics

+    ///

+    /// Panics if `rows * cols > usize::MAX` or if `rows * cols * size_of::<T>() > isize::MAX`

+    #[must_use]

+    pub fn with_capacity_and_order(rows: usize, cols: usize, order: Order) -> Self {

+        Self {

+            data: Vec::with_capacity(rows.checked_mul(cols).unwrap()),

+            cols: 0,

+            rows: 0,

+            order,

+        }

+    }

+

+    /// 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`](Grid::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`:

+    ///

+    /// ``` should_panic

+    /// 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.

+    #[must_use]

+    #[inline]

+    pub fn from_vec(vec: Vec<T>, cols: usize) -> Self {

+        Self::from_vec_with_order(vec, cols, Order::default())

+    }

+

+    /// Same as [`from_vec`](Self::from_vec) but with a specific [`Order`].

+    ///

+    /// # Panics

+    ///

+    /// This panics if the vector length isn't a multiple of the number of columns.

+    #[must_use]

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

+        let rows = vec.len().checked_div(cols).unwrap_or(0);

+        assert_eq!(

+            rows * cols,

+            vec.len(),

+            "Vector length {:?} should be a multiple of cols = {:?}",

+            vec.len(),

+            cols

+        );

+        if rows == 0 || cols == 0 {

+            Self {

+                data: vec,

+                rows: 0,

+                cols: 0,

+                order,

+            }

+        } else {

+            Self {

+                data: vec,

+                rows,

+                cols,

+                order,

+            }

+        }

+    }

+

+    /// Returns the index of the coordinates in the internal vector.

+    #[inline]

+    #[must_use]

+    const fn get_index(&self, row: usize, col: usize) -> usize {

+        match self.order {

+            Order::RowMajor => row * self.cols + col,

+            Order::ColumnMajor => col * self.rows + row,

+        }

+    }

+

+    /// 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.

+    #[inline]

+    #[must_use]

+    pub unsafe fn get_unchecked(&self, row: impl Into<usize>, col: impl Into<usize>) -> &T {

+        let index = self.get_index(row.into(), col.into());

+        self.data.get_unchecked(index)

+    }

+

+    /// 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.

+    #[inline]

+    #[must_use]

+    pub unsafe fn get_unchecked_mut(

+        &mut self,

+        row: impl Into<usize>,

+        col: impl Into<usize>,

+    ) -> &mut T {

+        let index = self.get_index(row.into(), col.into());

+        self.data.get_unchecked_mut(index)

+    }

+

+    /// Access a certain element in the grid.

+    /// Returns `None` if an element beyond the grid bounds is tried to be accessed.

+    #[must_use]

+    pub fn get(&self, row: impl TryInto<usize>, col: impl TryInto<usize>) -> Option<&T> {

+        let row_usize = row.try_into().ok()?;

+        let col_usize = col.try_into().ok()?;

+        if row_usize < self.rows && col_usize < self.cols {

+            unsafe { Some(self.get_unchecked(row_usize, col_usize)) }

+        } else {

+            None

+        }

+    }

+

+    /// Mutable access to a certain element in the grid.

+    /// Returns `None` if an element beyond the grid bounds is tried to be accessed.

+    #[must_use]

+    pub fn get_mut(

+        &mut self,

+        row: impl TryInto<usize>,

+        col: impl TryInto<usize>,

+    ) -> Option<&mut T> {

+        let row_usize = row.try_into().ok()?;

+        let col_usize = col.try_into().ok()?;

+        if row_usize < self.rows && col_usize < self.cols {

+            unsafe { Some(self.get_unchecked_mut(row_usize, col_usize)) }

+        } else {

+            None

+        }

+    }

+

+    /// Returns the size of the grid as a two element tuple.

+    /// First element are the number of rows and the second the columns.

+    #[must_use]

+    pub const fn size(&self) -> (usize, usize) {

+        (self.rows, self.cols)

+    }

+

+    /// Returns the number of rows of the grid.

+    #[must_use]

+    pub const fn rows(&self) -> usize {

+        self.rows

+    }

+

+    /// Returns the number of columns of the grid.

+    #[must_use]

+    pub const fn cols(&self) -> usize {

+        self.cols

+    }

+

+    /// Returns the internal memory layout of the grid.

+    #[must_use]

+    pub const fn order(&self) -> Order {

+        self.order

+    }

+

+    /// Returns `true` if the grid contains no elements.

+    /// For example:

+    /// ```

+    /// use grid::*;

+    /// let grid : Grid<u8> = grid![];

+    /// assert!(grid.is_empty());

+    /// ```

+    #[must_use]

+    pub fn is_empty(&self) -> bool {

+        self.data.is_empty()

+    }

+

+    /// Clears the grid.

+    ///

+    /// This doesn't change the grid order.

+    pub fn clear(&mut self) {

+        self.rows = 0;

+        self.cols = 0;

+        self.data.clear();

+    }

+

+    /// 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`](Grid::iter_rows) or

+    /// [`iter_cols`](Grid::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);

+    /// ```

+    pub fn iter(&self) -> Iter<T> {

+        self.data.iter()

+    }

+

+    /// 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;

+    /// ```

+    pub fn iter_mut(&mut self) -> IterMut<T> {

+        self.data.iter_mut()

+    }

+

+    /// 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.

+    pub fn iter_col(&self, col: usize) -> StepBy<Iter<T>> {

+        assert!(

+            col < self.cols,

+            "out of bounds. Column must be less than {:?}, but is {:?}",

+            self.cols,

+            col

+        );

+        match self.order {

+            Order::RowMajor => self.data[col..].iter().step_by(self.cols),

+            Order::ColumnMajor => {

+                let start = col * self.rows;

+                self.data[start..(start + self.rows)].iter().step_by(1)

+            }

+        }

+    }

+

+    /// 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.

+    pub fn iter_col_mut(&mut self, col: usize) -> StepBy<IterMut<T>> {

+        assert!(

+            col < self.cols,

+            "out of bounds. Column must be less than {:?}, but is {:?}",

+            self.cols,

+            col

+        );

+        match self.order {

+            Order::RowMajor => self.data[col..].iter_mut().step_by(self.cols),

+            Order::ColumnMajor => {

+                let start = col * self.rows;

+                self.data[start..(start + self.rows)].iter_mut().step_by(1)

+            }

+        }

+    }

+

+    /// 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.

+    pub fn iter_row(&self, row: usize) -> StepBy<Iter<T>> {

+        assert!(

+            row < self.rows,

+            "out of bounds. Row must be less than {:?}, but is {:?}",

+            self.rows,

+            row

+        );

+        match self.order {

+            Order::RowMajor => {

+                let start = row * self.cols;

+                self.data[start..(start + self.cols)].iter().step_by(1)

+            }

+            Order::ColumnMajor => self.data[row..].iter().step_by(self.rows),

+        }

+    }

+

+    /// 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.

+    pub fn iter_row_mut(&mut self, row: usize) -> StepBy<IterMut<T>> {

+        assert!(

+            row < self.rows,

+            "out of bounds. Row must be less than {:?}, but is {:?}",

+            self.rows,

+            row

+        );

+        match self.order {

+            Order::RowMajor => {

+                let start = row * self.cols;

+                self.data[start..(start + self.cols)].iter_mut().step_by(1)

+            }

+            Order::ColumnMajor => self.data[row..].iter_mut().step_by(self.rows),

+        }

+    }

+

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

+    /// }

+    /// ```

+    pub fn indexed_iter(&self) -> impl Iterator<Item = ((usize, usize), &T)> {

+        self.data.iter().enumerate().map(move |(idx, i)| {

+            let position = match self.order {

+                Order::RowMajor => (idx / self.cols, idx % self.cols),

+                Order::ColumnMajor => (idx % self.rows, idx / self.rows),

+            };

+            (position, i)

+        })

+    }

+

+    /// 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);

+    /// ```

+    pub fn indexed_iter_mut(&mut self) -> impl Iterator<Item = ((usize, usize), &mut T)> {

+        let order = self.order;

+        let cols = self.cols;

+        let rows = self.rows;

+

+        self.data.iter_mut().enumerate().map(move |(idx, i)| {

+            let position = match order {

+                Order::RowMajor => (idx / cols, idx % cols),

+                Order::ColumnMajor => (idx % rows, idx / rows),

+            };

+            (position, i)

+        })

+    }

+

+    /// 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`

+    pub fn push_row(&mut self, row: Vec<T>) {

+        assert_ne!(row.len(), 0);

+        assert!(

+            !(self.rows > 0 && row.len() != self.cols),

+            "pushed row does not match. Length must be {:?}, but was {:?}.",

+            self.cols,

+            row.len()

+        );

+        self.data.extend(row);

+        if self.order == Order::ColumnMajor {

+            for i in (1..self.cols).rev() {

+                let col_idx = i * self.rows;

+                self.data[col_idx..col_idx + self.rows + i].rotate_right(i);

+            }

+        }

+        self.rows += 1;

+        if self.cols == 0 {

+            self.cols = self.data.len();

+        }

+    }

+

+    /// 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`

+    pub fn push_col(&mut self, col: Vec<T>) {

+        assert_ne!(col.len(), 0);

+        assert!(

+            !(self.cols > 0 && col.len() != self.rows),

+            "pushed column does not match. Length must be {:?}, but was {:?}.",

+            self.rows,

+            col.len()

+        );

+        self.data.extend(col);

+        if self.order == Order::RowMajor {

+            for i in (1..self.rows).rev() {

+                let row_idx = i * self.cols;

+                self.data[row_idx..row_idx + self.cols + i].rotate_right(i);

+            }

+        }

+        self.cols += 1;

+        if self.rows == 0 {

+            self.rows = self.data.len();

+        }

+    }

+

+    /// 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.

+    pub fn pop_row(&mut self) -> Option<Vec<T>> {

+        if self.rows == 0 {

+            return None;

+        }

+        if self.order == Order::ColumnMajor {

+            for i in 1..self.cols {

+                let col_idx = i * (self.rows - 1);

+                self.data[col_idx..col_idx + self.rows + i - 1].rotate_left(i);

+            }

+        }

+        let row = self.data.split_off(self.data.len() - self.cols);

+        self.rows -= 1;

+        if self.rows == 0 {

+            self.cols = 0;

+        }

+        Some(row)

+    }

+

+    /// 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.

+    pub fn remove_row(&mut self, row_index: usize) -> Option<Vec<T>> {

+        if self.cols == 0 || self.rows == 0 || row_index >= self.rows {

+            return None;

+        }

+        let row = match self.order {

+            Order::RowMajor => self

+                .data

+                .drain((row_index * self.cols)..((row_index + 1) * self.cols))

+                .collect(),

+            Order::ColumnMajor => {

+                for i in 0..self.cols {

+                    let col_idx = row_index + i * (self.rows - 1);

+                    let end = cmp::min(col_idx + self.rows + i, self.data.len());

+                    self.data[col_idx..end].rotate_left(i + 1);

+                }

+                self.data.split_off(self.data.len() - self.cols)

+            }

+        };

+        self.rows -= 1;

+        if self.rows == 0 {

+            self.cols = 0;

+        }

+        Some(row)

+    }

+

+    /// 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.

+    pub fn pop_col(&mut self) -> Option<Vec<T>> {

+        if self.cols == 0 {

+            return None;

+        }

+        if self.order == Order::RowMajor {

+            for i in 1..self.rows {

+                let row_idx = i * (self.cols - 1);

+                self.data[row_idx..row_idx + self.cols + i - 1].rotate_left(i);

+            }

+        }

+        let col = self.data.split_off(self.data.len() - self.rows);

+        self.cols -= 1;

+        if self.cols == 0 {

+            self.rows = 0;

+        }

+        Some(col)

+    }

+

+    /// 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.

+    pub fn remove_col(&mut self, col_index: usize) -> Option<Vec<T>> {

+        if self.cols == 0 || self.rows == 0 || col_index >= self.cols {

+            return None;

+        }

+        let col = match self.order {

+            Order::RowMajor => {

+                for i in 0..self.rows {

+                    let row_idx = col_index + i * (self.cols - 1);

+                    let end = cmp::min(row_idx + self.cols + i, self.data.len());

+                    self.data[row_idx..end].rotate_left(i + 1);

+                }

+                self.data.split_off(self.data.len() - self.rows)

+            }

+            Order::ColumnMajor => self

+                .data

+                .drain((col_index * self.rows)..((col_index + 1) * self.rows))

+                .collect(),

+        };

+        self.cols -= 1;

+        if self.cols == 0 {

+            self.rows = 0;

+        }

+        Some(col)

+    }

+

+    /// 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

+    pub fn insert_row(&mut self, index: usize, row: Vec<T>) {

+        let input_len = row.len();

+        assert!(

+            !(self.cols > 0 && input_len != self.cols),

+            "Inserted row must be of length {}, but was {}.",

+            self.cols,

+            row.len()

+        );

+        assert!(

+            index <= self.rows,

+            "Out of range. Index was {}, but must be less or equal to {}.",

+            index,

+            self.rows

+        );

+        match self.order {

+            Order::RowMajor => {

+                let data_idx = index * input_len;

+                self.data.splice(data_idx..data_idx, row);

+            }

+            Order::ColumnMajor => {

+                for (col_iter, row_val) in row.into_iter().enumerate() {

+                    let data_idx = col_iter * self.rows + index + col_iter;

+                    self.data.insert(data_idx, row_val);

+                }

+            }

+        }

+        self.cols = input_len;

+        self.rows += 1;

+    }

+

+    /// 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

+    pub fn insert_col(&mut self, index: usize, col: Vec<T>) {

+        let input_len = col.len();

+        assert!(

+            !(self.rows > 0 && input_len != self.rows),

+            "Inserted col must be of length {}, but was {}.",

+            self.rows,

+            col.len()

+        );

+        assert!(

+            index <= self.cols,

+            "Out of range. Index was {}, but must be less or equal to {}.",

+            index,

+            self.cols

+        );

+        match self.order {

+            Order::RowMajor => {

+                for (row_iter, col_val) in col.into_iter().enumerate() {

+                    let data_idx = row_iter * self.cols + index + row_iter;

+                    self.data.insert(data_idx, col_val);

+                }

+            }

+            Order::ColumnMajor => {

+                let data_idx = index * input_len;

+                self.data.splice(data_idx..data_idx, col);

+            }

+        }

+        self.rows = input_len;

+        self.cols += 1;

+    }

+

+    /// 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]);

+    /// ```

+    #[must_use]

+    pub const fn flatten(&self) -> &Vec<T> {

+        &self.data

+    }

+

+    /// 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.

+    #[must_use]

+    pub fn into_vec(self) -> Vec<T> {

+        self.data

+    }

+

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

+    ///

+    /// This method changes the internal memory layout.

+    pub fn transpose(&mut self) {

+        self.order = self.order.counterpart();

+        core::mem::swap(&mut self.rows, &mut self.cols);

+    }

+

+    /// 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.

+    pub fn flip_cols(&mut self) {

+        match self.order {

+            Order::RowMajor => {

+                for row in 0..self.rows {

+                    let idx = row * self.cols;

+                    self.data[idx..idx + self.cols].reverse();

+                }

+            }

+            Order::ColumnMajor => {

+                for col in 0..self.cols / 2 {

+                    for row in 0..self.rows {

+                        let cell1 = self.get_index(row, col);

+                        let cell2 = self.get_index(row, self.cols - col - 1);

+                        self.data.swap(cell1, cell2);

+                    }

+                }

+            }

+        }

+    }

+

+    /// 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.

+    pub fn flip_rows(&mut self) {

+        match self.order {

+            Order::RowMajor => {

+                for row in 0..self.rows / 2 {

+                    for col in 0..self.cols {

+                        let cell1 = self.get_index(row, col);

+                        let cell2 = self.get_index(self.rows - row - 1, col);

+                        self.data.swap(cell1, cell2);

+                    }

+                }

+            }

+            Order::ColumnMajor => {

+                for col in 0..self.cols {

+                    let idx = col * self.rows;

+                    self.data[idx..idx + self.rows].reverse();

+                }

+            }

+        }

+    }

+

+    /// 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.

+    pub fn rotate_left(&mut self) {

+        self.transpose();

+        self.flip_rows();

+    }

+

+    /// 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.

+    pub fn rotate_right(&mut self) {

+        self.transpose();

+        self.flip_cols();

+    }

+

+    /// 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.

+    pub fn rotate_half(&mut self) {

+        self.data.reverse();

+    }

+

+    /// 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]]);

+    /// ```

+    pub fn fill(&mut self, value: T)

+    where

+        T: Clone,

+    {

+        self.data.fill(value);

+    }

+

+    /// 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.

+    ///

+    /// [`fill`]: Grid::fill

+    ///

+    /// # 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]]);

+    /// ```

+    pub fn fill_with<F>(&mut self, f: F)

+    where

+        F: FnMut() -> T,

+    {

+        self.data.fill_with(f);

+    }

+

+    /// Returns a new grid with the same dimensions, but with each element transformed by the closure.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// use grid::*;

+    /// let grid = grid![[1,2][3,4]];

+    /// let new_grid = grid.map(|x| x * 2);

+    /// assert_eq!(new_grid, grid![[2,4][6,8]]);

+    ///

+    /// let grid = grid![[1,2][3,4]];

+    /// let new_grid = grid.map(|x| x > 2);

+    /// assert_eq!(new_grid, grid![[false,false][true,true]]);

+    /// ```

+    pub fn map<U, F>(self, f: F) -> Grid<U>

+    where

+        F: FnMut(T) -> U,

+    {

+        Grid {

+            data: self.data.into_iter().map(f).collect(),

+            cols: self.cols,

+            rows: self.rows,

+            order: self.order,

+        }

+    }

+

+    /// Returns a new grid with the same dimensions, but with each element

+    /// transformed by the closure. Does not consume the grid.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// use grid::*;

+    /// let grid = grid![[1,2][3,4]];

+    /// let new_grid = grid.map(|x| x * 2);

+    /// assert_eq!(new_grid, grid![[2,4][6,8]]);

+    ///

+    /// let grid = grid![[1,2][3,4]];

+    /// let new_grid = grid.map(|x| x > 2);

+    /// assert_eq!(new_grid, grid![[false,false][true,true]]);

+    /// ```

+    #[must_use]

+    pub fn map_ref<U, F>(&self, f: F) -> Grid<U>

+    where

+        F: Fn(&T) -> U,

+    {

+        Grid {

+            data: self.data.iter().map(f).collect(),

+            cols: self.cols,

+            rows: self.rows,

+            order: self.order,

+        }

+    }

+

+    /// 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])

+    /// ```

+    #[must_use]

+    pub const fn iter_rows(&self) -> GridRowIter<'_, T> {

+        GridRowIter {

+            grid: self,

+            row_start_index: 0,

+            row_end_index: self.rows,

+        }

+    }

+

+    /// 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])

+    /// ```

+    #[must_use]

+    pub const fn iter_cols(&self) -> GridColIter<'_, T> {

+        GridColIter {

+            grid: self,

+            col_start_index: 0,

+            col_end_index: self.cols,

+        }

+    }

+

+    /// Swaps two elements in the Grid.

+    /// Similar to `Vec::swap()`.

+    ///

+    /// # Panics

+    ///

+    /// Panics if either index is out of bounds.

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

+        assert!(

+            !(row_a >= self.rows || col_a >= self.cols),

+            "grid index out of bounds: ({row_a},{col_a}) out of ({},{})",

+            self.rows,

+            self.cols

+        );

+        assert!(

+            !(row_b >= self.rows || col_b >= self.cols),

+            "grid index out of bounds: ({row_b},{col_b}) out of ({},{})",

+            self.rows,

+            self.cols

+        );

+

+        let a_idx = self.get_index(row_a, col_a);

+        let b_idx = self.get_index(row_b, col_b);

+

+        self.data.swap(a_idx, b_idx);

+    }

+}

+

+impl<T> Default for Grid<T> {

+    fn default() -> Self {

+        Self {

+            data: Vec::default(),

+            cols: 0,

+            rows: 0,

+            order: Order::default(),

+        }

+    }

+}

+

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

+    fn clone(&self) -> Self {

+        Self {

+            rows: self.rows,

+            cols: self.cols,

+            data: self.data.clone(),

+            order: self.order,

+        }

+    }

+}

+

+impl<T: hash::Hash> hash::Hash for Grid<T> {

+    #[inline]

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

+        self.rows.hash(state);

+        self.cols.hash(state);

+        self.order.hash(state);

+        self.data.hash(state);

+    }

+}

+

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

+    type Output = T;

+

+    #[inline]

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

+        assert!(

+            !(row >= self.rows || col >= self.cols),

+            "grid index out of bounds: ({row},{col}) out of ({},{})",

+            self.rows,

+            self.cols

+        );

+        let index = self.get_index(row, col);

+        &self.data[index]

+    }

+}

+

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

+    #[inline]

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

+        assert!(

+            !(row >= self.rows || col >= self.cols),

+            "grid index out of bounds: ({row},{col}) out of ({},{})",

+            self.rows,

+            self.cols

+        );

+        let index = self.get_index(row, col);

+        &mut self.data[index]

+    }

+}

+

+impl<'a, T> IntoIterator for &'a Grid<T> {

+    type IntoIter = core::slice::Iter<'a, T>;

+    type Item = &'a T;

+

+    fn into_iter(self) -> Self::IntoIter {

+        self.iter()

+    }

+}

+

+impl<'a, T> IntoIterator for &'a mut Grid<T> {

+    type IntoIter = core::slice::IterMut<'a, T>;

+    type Item = &'a mut T;

+

+    fn into_iter(self) -> Self::IntoIter {

+        self.iter_mut()

+    }

+}

+

+impl<T: fmt::Debug> fmt::Debug for Grid<T> {

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

+        write!(f, "[")?;

+        if self.cols > 0 {

+            if f.alternate() {

+                writeln!(f)?;

+                /*

+                    WARNING

+

+                    Compound types becoming enormous as the entire `fmt::Debug` width is applied to each item individually.

+                    For tuples and structs define padding and precision arguments manually to improve readability.

+                */

+                let width = f.width().unwrap_or_else(|| {

+                    // Conditionally calculate the longest item by default.

+                    self.data

+                        .iter()

+                        .map(|i| format!("{i:?}").len())

+                        .max()

+                        .unwrap()

+                });

+                let precision = f.precision().unwrap_or(2);

+                for mut row in self.iter_rows().map(Iterator::peekable) {

+                    write!(f, "    [")?;

+                    while let Some(item) = row.next() {

+                        write!(f, " {item:width$.precision$?}")?;

+                        if row.peek().is_some() {

+                            write!(f, ",")?;

+                        }

+                    }

+                    writeln!(f, "]")?;

+                }

+            } else {

+                for row in self.iter_rows() {

+                    f.debug_list().entries(row).finish()?;

+                }

+            }

+        }

+        write!(f, "]")

+    }

+}

+

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

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

+        if self.rows != other.rows || self.cols != other.cols {

+            return false;

+        }

+        if self.order == other.order {

+            return self.data == other.data;

+        }

+        for (self_row, other_row) in core::iter::zip(self.iter_rows(), other.iter_rows()) {

+            if self_row.ne(other_row) {

+                return false;

+            }

+        }

+        true

+    }

+}

+

+impl<T: Eq> Eq for Grid<T> {}

+

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

+    #[allow(clippy::redundant_closure_for_method_calls)]

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

+        let cols = vec.first().map_or(0, |row| row.len());

+        Self::from_vec_with_order(vec.into_iter().flatten().collect(), cols, Order::default())

+    }

+}

+

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

+    #[allow(clippy::redundant_closure_for_method_calls)]

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

+        let cols = vec.first().map_or(0, |row| row.len());

+        Self::from_vec_with_order(

+            vec.clone().into_iter().flatten().collect(),

+            cols,

+            Order::default(),

+        )

+    }

+}

+

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

+    #[allow(clippy::redundant_closure_for_method_calls)]

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

+        let cols = vec.first().map_or(0, |row| row.len());

+        Self::from_vec_with_order(

+            vec.clone()

+                .into_iter()

+                .flat_map(|inner| inner.clone())

+                .collect(),

+            cols,

+            Order::default(),

+        )

+    }

+}

+

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

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

+        Self::from_vec_with_order(value.0, value.1, Order::default())

+    }

+}

+

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

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

+        Self::from_vec_with_order(value.0.clone(), value.1, Order::default())

+    }

+}

+

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

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

+        Self::from_vec_with_order(value.0.clone(), *value.1, Order::default())

+    }

+}

+

+#[derive(Clone)]

+pub struct GridRowIter<'a, T> {

+    grid: &'a Grid<T>,

+    row_start_index: usize,

+    row_end_index: usize,

+}

+

+#[derive(Clone)]

+pub struct GridColIter<'a, T> {

+    grid: &'a Grid<T>,

+    col_start_index: usize,

+    col_end_index: usize,

+}

+

+impl<'a, T> Iterator for GridRowIter<'a, T> {

+    type Item = StepBy<Iter<'a, T>>;

+

+    fn next(&mut self) -> Option<Self::Item> {

+        if self.row_start_index >= self.row_end_index {

+            return None;

+        }

+

+        let row_iter = self.grid.iter_row(self.row_start_index);

+        self.row_start_index += 1;

+        Some(row_iter)

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        let size = self.row_end_index - self.row_start_index;

+        (size, Some(size))

+    }

+}

+

+impl<T> ExactSizeIterator for GridRowIter<'_, T> {}

+

+impl<T> DoubleEndedIterator for GridRowIter<'_, T> {

+    fn next_back(&mut self) -> Option<Self::Item> {

+        if self.row_start_index >= self.row_end_index {

+            return None;

+        }

+

+        let row_iter = self.grid.iter_row(self.row_end_index - 1);

+        self.row_end_index -= 1;

+        Some(row_iter)

+    }

+}

+

+impl<'a, T> Iterator for GridColIter<'a, T> {

+    type Item = StepBy<Iter<'a, T>>;

+

+    fn next(&mut self) -> Option<Self::Item> {

+        if self.col_start_index >= self.col_end_index {

+            return None;

+        }

+

+        let col_iter = self.grid.iter_col(self.col_start_index);

+        self.col_start_index += 1;

+        Some(col_iter)

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        let size = self.col_end_index - self.col_start_index;

+        (size, Some(size))

+    }

+}

+

+impl<T> ExactSizeIterator for GridColIter<'_, T> {}

+

+impl<T> DoubleEndedIterator for GridColIter<'_, T> {

+    fn next_back(&mut self) -> Option<Self::Item> {

+        if self.col_start_index >= self.col_end_index {

+            return None;

+        }

+

+        let col_iter = self.grid.iter_col(self.col_end_index - 1);

+        self.col_end_index -= 1;

+        Some(col_iter)

+    }

+}

+

+#[cfg(test)]

+mod test {

+    use super::*;

+    #[cfg(not(feature = "std"))]

+    use alloc::string::String;

+

+    fn test_grid<T>(grid: &Grid<T>, rows: usize, cols: usize, order: Order, data: &[T])

+    where

+        T: fmt::Debug + PartialEq,

+    {

+        assert_eq!(grid.rows, rows, "number of rows is unexpected");

+        assert_eq!(grid.cols, cols, "number of cols is unexpected");

+        assert_eq!(grid.order, order, "grid order is unexpected");

+        assert_eq!(grid.data, data, "internal data is unexpected");

+    }

+

+    #[test]

+    fn from_1d_vec() {

+        let grid: Grid<u8> = Grid::from((vec![1, 2, 3], 1));

+        test_grid(&grid, 3, 1, Order::RowMajor, &[1, 2, 3]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn from_1d_vec_panic() {

+        let _: Grid<u8> = Grid::from((vec![1, 2, 3], 2));

+    }

+

+    #[test]

+    fn from_1d_vec_reference() {

+        let vec = vec![1, 2, 3];

+        let grid: Grid<u8> = Grid::from((&vec, 1));

+        test_grid(&grid, 3, 1, Order::RowMajor, &[1, 2, 3]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn from_1d_vec_reference_panic() {

+        let vec = vec![1, 2, 3];

+        let _: Grid<u8> = Grid::from((&vec, 2));

+    }

+

+    #[test]

+    fn from_1d_vec_reference_and_reference() {

+        let vec = vec![1, 2, 3];

+        let cols = 1;

+        let grid: Grid<u8> = Grid::from((&vec, &cols));

+        test_grid(&grid, 3, 1, Order::RowMajor, &[1, 2, 3]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn from_1d_vec_reference_and_reference_panic() {

+        let vec = vec![1, 2, 3];

+        let cols = 2;

+        let _: Grid<u8> = Grid::from((&vec, &cols));

+    }

+

+    #[test]

+    fn from_2d_vec() {

+        let grid: Grid<u8> = Grid::from(vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]]);

+        test_grid(&grid, 3, 3, Order::RowMajor, &[1, 2, 3, 4, 5, 6, 7, 8, 9]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn from_2d_vec_panic() {

+        let _: Grid<u8> = Grid::from(vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8]]);

+    }

+

+    #[test]

+    fn from_2d_vec_reference() {

+        let vec = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]];

+        let grid: Grid<u8> = Grid::from(&vec);

+        test_grid(&grid, 3, 3, Order::RowMajor, &[1, 2, 3, 4, 5, 6, 7, 8, 9]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn from_2d_vec_reference_panic() {

+        let vec = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8]];

+        let _: Grid<u8> = Grid::from(&vec);

+    }

+

+    #[test]

+    fn from_2d_vec_reference_of_references() {

+        let inner_vec1 = vec![1, 2, 3];

+        let inner_vec2 = vec![4, 5, 6];

+        let inner_vec3 = vec![7, 8, 9];

+        let vec = vec![&inner_vec1, &inner_vec2, &inner_vec3];

+        let grid: Grid<u8> = Grid::from(&vec);

+        test_grid(&grid, 3, 3, Order::RowMajor, &[1, 2, 3, 4, 5, 6, 7, 8, 9]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn from_2d_vec_reference_of_references_panic() {

+        let inner_vec1 = vec![1, 2, 3];

+        let inner_vec2 = vec![4, 5, 6];

+        let inner_vec3 = vec![7, 8];

+        let vec = vec![&inner_vec1, &inner_vec2, &inner_vec3];

+        let _: Grid<u8> = Grid::from(&vec);

+    }

+

+    #[test]

+    fn from_vec_zero_with_cols() {

+        let grid: Grid<u8> = Grid::from_vec(vec![], 1);

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+    }

+

+    #[test]

+    fn from_vec_zero() {

+        let grid: Grid<u8> = Grid::from_vec(vec![], 0);

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn from_vec_panics_1() {

+        let _: Grid<u8> = Grid::from_vec(vec![1, 2, 3], 0);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn from_vec_panics_2() {

+        let _: Grid<u8> = Grid::from_vec(vec![1, 2, 3], 2);

+    }

+

+    #[test]

+    fn from_vec_uses_original_vec() {

+        let capacity = 10_000_000;

+        let vec = Vec::with_capacity(capacity);

+        let grid: Grid<u8> = Grid::from_vec(vec, 0);

+        assert!(grid.into_vec().capacity() >= capacity);

+    }

+

+    #[test]

+    fn from_vec_with_order_zero_with_cols() {

+        let grid: Grid<u8> = Grid::from_vec_with_order(vec![], 1, Order::ColumnMajor);

+        test_grid(&grid, 0, 0, Order::ColumnMajor, &[]);

+    }

+

+    #[test]

+    fn from_vec_with_order_zero() {

+        let grid: Grid<u8> = Grid::from_vec_with_order(vec![], 0, Order::ColumnMajor);

+        test_grid(&grid, 0, 0, Order::ColumnMajor, &[]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn from_vec_with_order_panics_1() {

+        let _: Grid<u8> = Grid::from_vec_with_order(vec![1, 2, 3], 0, Order::ColumnMajor);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn from_vec_with_order_panics_2() {

+        let _: Grid<u8> = Grid::from_vec_with_order(vec![1, 2, 3], 2, Order::ColumnMajor);

+    }

+

+    #[test]

+    fn from_vec_with_order_uses_original_vec() {

+        let capacity = 10_000_000;

+        let vec = Vec::with_capacity(capacity);

+        let grid: Grid<u8> = Grid::from_vec_with_order(vec, 0, Order::ColumnMajor);

+        assert!(grid.into_vec().capacity() >= capacity);

+    }

+

+    #[test]

+    fn insert_col_at_end() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![1, 2, 3, 4], 2, Order::RowMajor);

+        grid.insert_col(2, vec![5, 6]);

+        test_grid(&grid, 2, 3, Order::RowMajor, &[1, 2, 5, 3, 4, 6]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn insert_col_out_of_idx() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![1, 2, 3, 4], 2, Order::RowMajor);

+        grid.insert_col(3, vec![4, 5]);

+    }

+

+    #[test]

+    fn insert_col_empty() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![], 0, Order::RowMajor);

+        grid.insert_col(0, vec![1, 2, 3]);

+        test_grid(&grid, 3, 1, Order::RowMajor, &[1, 2, 3]);

+    }

+

+    #[test]

+    fn insert_col_at_end_column_major() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![1, 3, 2, 4], 2, Order::ColumnMajor);

+        grid.insert_col(2, vec![5, 6]);

+        test_grid(&grid, 2, 3, Order::ColumnMajor, &[1, 3, 2, 4, 5, 6]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn insert_col_out_of_idx_column_major() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![1, 3, 2, 4], 2, Order::ColumnMajor);

+        grid.insert_col(3, vec![4, 5]);

+    }

+

+    #[test]

+    fn insert_col_empty_column_major() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![], 0, Order::ColumnMajor);

+        grid.insert_col(0, vec![1, 2, 3]);

+        test_grid(&grid, 3, 1, Order::ColumnMajor, &[1, 2, 3]);

+    }

+

+    #[test]

+    fn insert_row_at_end() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![1, 2, 3, 4], 2, Order::RowMajor);

+        grid.insert_row(2, vec![5, 6]);

+        test_grid(&grid, 3, 2, Order::RowMajor, &[1, 2, 3, 4, 5, 6]);

+    }

+

+    #[test]

+    fn insert_row_empty() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![], 0, Order::RowMajor);

+        grid.insert_row(0, vec![1, 2, 3]);

+        test_grid(&grid, 1, 3, Order::RowMajor, &[1, 2, 3]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn insert_row_out_of_idx() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![1, 2, 3, 4], 2, Order::RowMajor);

+        grid.insert_row(3, vec![4, 5]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn insert_row_wrong_size_of_idx() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![1, 2, 3, 4], 2, Order::RowMajor);

+        grid.insert_row(1, vec![4, 5, 4]);

+    }

+

+    #[test]

+    fn insert_row_start() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![1, 2, 3, 4], 2, Order::RowMajor);

+        grid.insert_row(1, vec![5, 6]);

+        test_grid(&grid, 3, 2, Order::RowMajor, &[1, 2, 5, 6, 3, 4]);

+    }

+

+    #[test]

+    fn insert_row_at_end_column_major() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![1, 3, 2, 4], 2, Order::ColumnMajor);

+        grid.insert_row(2, vec![5, 6]);

+        test_grid(&grid, 3, 2, Order::ColumnMajor, &[1, 3, 5, 2, 4, 6]);

+    }

+

+    #[test]

+    fn insert_row_empty_column_major() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![], 0, Order::ColumnMajor);

+        grid.insert_row(0, vec![1, 2, 3]);

+        test_grid(&grid, 1, 3, Order::ColumnMajor, &[1, 2, 3]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn insert_row_out_of_idx_column_major() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![1, 2, 3, 4], 2, Order::ColumnMajor);

+        grid.insert_row(3, vec![4, 5]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn insert_row_wrong_size_of_idx_column_major() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![1, 2, 3, 4], 2, Order::ColumnMajor);

+        grid.insert_row(1, vec![4, 5, 4]);

+    }

+

+    #[test]

+    fn insert_row_start_column_major() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![1, 3, 2, 4], 2, Order::ColumnMajor);

+        grid.insert_row(1, vec![5, 6]);

+        test_grid(&grid, 3, 2, Order::ColumnMajor, &[1, 5, 3, 2, 6, 4]);

+    }

+

+    #[test]

+    fn pop_col_1x3() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![1, 2, 3], 3, Order::RowMajor);

+        assert_eq!(grid.pop_col(), Some(vec![3]));

+        test_grid(&grid, 1, 2, Order::RowMajor, &[1, 2]);

+        assert_eq!(grid.pop_col(), Some(vec![2]));

+        test_grid(&grid, 1, 1, Order::RowMajor, &[1]);

+        assert_eq!(grid.pop_col(), Some(vec![1]));

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+        assert_eq!(grid.pop_col(), None);

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+    }

+

+    #[test]

+    fn pop_col_3x1() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![1, 2, 3], 1, Order::RowMajor);

+        assert_eq!(grid.pop_col(), Some(vec![1, 2, 3]));

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+        assert_eq!(grid.pop_col(), None);

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+    }

+

+    #[test]

+    fn pop_col_2x2() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![1, 2, 3, 4], 2, Order::RowMajor);

+        assert_eq!(grid.pop_col(), Some(vec![2, 4]));

+        assert_eq!(grid.size(), (2, 1));

+        test_grid(&grid, 2, 1, Order::RowMajor, &[1, 3]);

+        assert_eq!(grid.pop_col(), Some(vec![1, 3]));

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+        assert_eq!(grid.pop_col(), None);

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+    }

+

+    #[test]

+    fn pop_col_3x4() {

+        let internal = vec![1, 2, 3, 4, 11, 22, 33, 44, 111, 222, 333, 444];

+        let mut grid: Grid<u16> = Grid::from_vec_with_order(internal, 4, Order::RowMajor);

+        assert_eq!(grid.pop_col(), Some(vec![4, 44, 444]));

+        let expected = [1, 2, 3, 11, 22, 33, 111, 222, 333];

+        test_grid(&grid, 3, 3, Order::RowMajor, &expected);

+        assert_eq!(grid.pop_col(), Some(vec![3, 33, 333]));

+        test_grid(&grid, 3, 2, Order::RowMajor, &[1, 2, 11, 22, 111, 222]);

+        assert_eq!(grid.pop_col(), Some(vec![2, 22, 222]));

+        test_grid(&grid, 3, 1, Order::RowMajor, &[1, 11, 111]);

+        assert_eq!(grid.pop_col(), Some(vec![1, 11, 111]));

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+        assert_eq!(grid.pop_col(), None);

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+    }

+

+    #[test]

+    fn pop_col_empty() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![], 0, Order::RowMajor);

+        assert_eq!(grid.pop_col(), None);

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+    }

+

+    #[test]

+    fn pop_col_1x3_column_major() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![1, 2, 3], 3, Order::ColumnMajor);

+        assert_eq!(grid.pop_col(), Some(vec![3]));

+        test_grid(&grid, 1, 2, Order::ColumnMajor, &[1, 2]);

+        assert_eq!(grid.pop_col(), Some(vec![2]));

+        test_grid(&grid, 1, 1, Order::ColumnMajor, &[1]);

+        assert_eq!(grid.pop_col(), Some(vec![1]));

+        test_grid(&grid, 0, 0, Order::ColumnMajor, &[]);

+        assert_eq!(grid.pop_col(), None);

+        test_grid(&grid, 0, 0, Order::ColumnMajor, &[]);

+    }

+

+    #[test]

+    fn pop_col_3x1_column_major() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![1, 2, 3], 1, Order::ColumnMajor);

+        assert_eq!(grid.pop_col(), Some(vec![1, 2, 3]));

+        test_grid(&grid, 0, 0, Order::ColumnMajor, &[]);

+        assert_eq!(grid.pop_col(), None);

+        test_grid(&grid, 0, 0, Order::ColumnMajor, &[]);

+    }

+

+    #[test]

+    fn pop_col_2x2_column_major() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![1, 3, 2, 4], 2, Order::ColumnMajor);

+        assert_eq!(grid.pop_col(), Some(vec![2, 4]));

+        assert_eq!(grid.size(), (2, 1));

+        test_grid(&grid, 2, 1, Order::ColumnMajor, &[1, 3]);

+        assert_eq!(grid.pop_col(), Some(vec![1, 3]));

+        test_grid(&grid, 0, 0, Order::ColumnMajor, &[]);

+        assert_eq!(grid.pop_col(), None);

+        test_grid(&grid, 0, 0, Order::ColumnMajor, &[]);

+    }

+

+    #[test]

+    fn pop_col_3x4_column_major() {

+        let internal = vec![1, 11, 111, 2, 22, 222, 3, 33, 333, 4, 44, 444];

+        let mut grid: Grid<u16> = Grid::from_vec_with_order(internal, 4, Order::ColumnMajor);

+        assert_eq!(grid.pop_col(), Some(vec![4, 44, 444]));

+        let expected = [1, 11, 111, 2, 22, 222, 3, 33, 333];

+        test_grid(&grid, 3, 3, Order::ColumnMajor, &expected);

+        assert_eq!(grid.pop_col(), Some(vec![3, 33, 333]));

+        test_grid(&grid, 3, 2, Order::ColumnMajor, &[1, 11, 111, 2, 22, 222]);

+        assert_eq!(grid.pop_col(), Some(vec![2, 22, 222]));

+        test_grid(&grid, 3, 1, Order::ColumnMajor, &[1, 11, 111]);

+        assert_eq!(grid.pop_col(), Some(vec![1, 11, 111]));

+        test_grid(&grid, 0, 0, Order::ColumnMajor, &[]);

+        assert_eq!(grid.pop_col(), None);

+        test_grid(&grid, 0, 0, Order::ColumnMajor, &[]);

+    }

+

+    #[test]

+    fn pop_col_empty_column_major() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![], 0, Order::ColumnMajor);

+        assert_eq!(grid.pop_col(), None);

+        test_grid(&grid, 0, 0, Order::ColumnMajor, &[]);

+    }

+

+    #[test]

+    fn pop_row_2x2() {

+        let mut grid: Grid<u8> = Grid::from_vec(vec![1, 2, 3, 4], 2);

+        assert_eq!(grid.pop_row(), Some(vec![3, 4]));

+        test_grid(&grid, 1, 2, Order::RowMajor, &[1, 2]);

+        assert_eq!(grid.pop_row(), Some(vec![1, 2]));

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+        assert_eq!(grid.pop_row(), None);

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+    }

+

+    #[test]

+    fn pop_row_empty() {

+        let mut grid: Grid<u8> = Grid::from_vec(vec![], 0);

+        assert_eq!(grid.pop_row(), None);

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+    }

+

+    #[test]

+    fn pop_row_2x2_column_major() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![1, 3, 2, 4], 2, Order::ColumnMajor);

+        assert_eq!(grid.pop_row(), Some(vec![3, 4]));

+        test_grid(&grid, 1, 2, Order::ColumnMajor, &[1, 2]);

+        assert_eq!(grid.pop_row(), Some(vec![1, 2]));

+        test_grid(&grid, 0, 0, Order::ColumnMajor, &[]);

+        assert_eq!(grid.pop_row(), None);

+        test_grid(&grid, 0, 0, Order::ColumnMajor, &[]);

+    }

+

+    #[test]

+    fn pop_row_empty_column_major() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![], 0, Order::ColumnMajor);

+        assert_eq!(grid.pop_row(), None);

+        test_grid(&grid, 0, 0, Order::ColumnMajor, &[]);

+    }

+

+    #[test]

+    fn ne_full_empty() {

+        let g1 = Grid::from_vec(vec![1, 2, 3, 4], 2);

+        let g2: Grid<u8> = grid![];

+        assert_ne!(g1, g2);

+    }

+

+    #[test]

+    fn ne() {

+        let g1 = Grid::from_vec(vec![1, 2, 3, 5], 2);

+        let g2 = Grid::from_vec(vec![1, 2, 3, 4], 2);

+        assert_ne!(g1, g2);

+    }

+

+    #[test]

+    fn ne_dif_rows() {

+        let g1 = Grid::from_vec(vec![1, 2, 3, 4], 2);

+        let g2 = Grid::from_vec(vec![1, 2, 3, 4], 1);

+        assert_ne!(g1, g2);

+    }

+

+    #[test]

+    fn equal_empty() {

+        let grid: Grid<char> = grid![];

+        let grid2: Grid<char> = grid![];

+        assert_eq!(grid, grid2);

+    }

+

+    #[test]

+    fn equal() {

+        let grid: Grid<char> = grid![['a', 'b', 'c', 'd']['a', 'b', 'c', 'd']['a', 'b', 'c', 'd']];

+        let grid2: Grid<char> = grid![['a', 'b', 'c', 'd']['a', 'b', 'c', 'd']['a', 'b', 'c', 'd']];

+        assert_eq!(grid, grid2);

+    }

+

+    #[test]

+    fn equal_different_order() {

+        let grid = Grid::from_vec_with_order(vec![1, 2, 3, 4], 2, Order::RowMajor);

+        let grid2 = Grid::from_vec_with_order(vec![1, 3, 2, 4], 2, Order::ColumnMajor);

+        assert_eq!(grid, grid2);

+    }

+

+    #[test]

+    fn equal_partial_eq() {

+        let grid = grid![[1.0]];

+        let grid2 = Grid::from_vec(vec![1.0], 1);

+        assert_eq!(grid, grid2);

+    }

+

+    #[test]

+    fn ne_partial_eq() {

+        let grid = grid![[f64::NAN]];

+        assert_ne!(grid, grid);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn idx_tup_out_of_col_bounds() {

+        let grid: Grid<char> = grid![['a', 'b', 'c', 'd']['a', 'b', 'c', 'd']['a', 'b', 'c', 'd']];

+        let _ = grid[(0, 5)];

+    }

+

+    #[test]

+    fn push_col_2x3() {

+        let mut grid: Grid<u8> = grid![

+                    [0, 1, 2]

+                    [10, 11, 12]];

+        grid.push_col(vec![3, 13]);

+        test_grid(&grid, 2, 4, Order::RowMajor, &[0, 1, 2, 3, 10, 11, 12, 13]);

+    }

+

+    #[test]

+    fn push_col_3x4() {

+        let mut grid: Grid<char> = grid![

+                    ['a', 'b', 'c', 'd']

+                    ['a', 'b', 'c', 'd']

+                    ['a', 'b', 'c', 'd']];

+        grid.push_col(vec!['x', 'y', 'z']);

+        let expected = [

+            'a', 'b', 'c', 'd', 'x', 'a', 'b', 'c', 'd', 'y', 'a', 'b', 'c', 'd', 'z',

+        ];

+        test_grid(&grid, 3, 5, Order::RowMajor, &expected);

+    }

+

+    #[test]

+    fn push_col_1x3() {

+        let mut grid: Grid<char> = grid![['a', 'b', 'c']];

+        grid.push_col(vec!['d']);

+        test_grid(&grid, 1, 4, Order::RowMajor, &['a', 'b', 'c', 'd']);

+    }

+

+    #[test]

+    fn push_col_empty() {

+        let mut grid: Grid<char> = grid![];

+        grid.push_col(vec!['b', 'b', 'b', 'b']);

+        test_grid(&grid, 4, 1, Order::RowMajor, &['b', 'b', 'b', 'b']);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn push_col_wrong_size() {

+        let mut grid: Grid<char> = grid![['a','a','a']['a','a','a']];

+        grid.push_col(vec!['b']);

+        grid.push_col(vec!['b', 'b']);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn push_col_zero_len() {

+        let mut grid: Grid<char> = grid![];

+        grid.push_col(vec![]);

+    }

+

+    #[test]

+    fn push_col_2x3_column_major() {

+        let internal = vec![0, 10, 1, 11, 2, 12];

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(internal, 3, Order::ColumnMajor);

+        grid.push_col(vec![3, 13]);

+        let expected = [0, 10, 1, 11, 2, 12, 3, 13];

+        test_grid(&grid, 2, 4, Order::ColumnMajor, &expected);

+    }

+

+    #[test]

+    fn push_col_3x4_column_major() {

+        let internal = vec!['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'd'];

+        let mut grid: Grid<char> = Grid::from_vec_with_order(internal, 4, Order::ColumnMajor);

+        grid.push_col(vec!['x', 'y', 'z']);

+        let expected = [

+            'a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'd', 'x', 'y', 'z',

+        ];

+        test_grid(&grid, 3, 5, Order::ColumnMajor, &expected);

+    }

+

+    #[test]

+    fn push_col_1x3_column_major() {

+        let mut grid: Grid<char> =

+            Grid::from_vec_with_order(vec!['a', 'b', 'c'], 3, Order::ColumnMajor);

+        grid.push_col(vec!['d']);

+        test_grid(&grid, 1, 4, Order::ColumnMajor, &['a', 'b', 'c', 'd']);

+    }

+

+    #[test]

+    fn push_col_empty_column_major() {

+        let mut grid: Grid<char> = Grid::new_with_order(0, 0, Order::ColumnMajor);

+        grid.push_col(vec!['b', 'b', 'b', 'b']);

+        test_grid(&grid, 4, 1, Order::ColumnMajor, &['b', 'b', 'b', 'b']);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn push_col_wrong_size_column_major() {

+        let mut grid: Grid<char> = Grid::init_with_order(2, 3, Order::ColumnMajor, 'a');

+        grid.push_col(vec!['b']);

+        grid.push_col(vec!['b', 'b']);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn push_col_zero_len_column_major() {

+        let mut grid: Grid<char> = Grid::new_with_order(0, 0, Order::ColumnMajor);

+        grid.push_col(vec![]);

+    }

+

+    #[test]

+    fn push_row() {

+        let mut grid: Grid<u8> = grid![[1, 2][3, 4]];

+        grid.push_row(vec![5, 6]);

+        test_grid(&grid, 3, 2, Order::RowMajor, &[1, 2, 3, 4, 5, 6]);

+    }

+

+    #[test]

+    fn push_row_empty() {

+        let mut grid: Grid<char> = grid![];

+        grid.push_row(vec!['b', 'b', 'b', 'b']);

+        test_grid(&grid, 1, 4, Order::RowMajor, &['b', 'b', 'b', 'b']);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn push_empty_row() {

+        let mut grid = Grid::init(0, 1, 0);

+        grid.push_row(vec![]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn push_row_wrong_size() {

+        let mut grid: Grid<char> = grid![['a','a','a']['a','a','a']];

+        grid.push_row(vec!['b']);

+        grid.push_row(vec!['b', 'b', 'b', 'b']);

+    }

+

+    #[test]

+    fn push_row_column_major() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![1, 3, 2, 4], 2, Order::ColumnMajor);

+        grid.push_row(vec![5, 6]);

+        test_grid(&grid, 3, 2, Order::ColumnMajor, &[1, 3, 5, 2, 4, 6]);

+    }

+

+    #[test]

+    fn push_row_empty_column_major() {

+        let mut grid: Grid<char> = Grid::new_with_order(0, 0, Order::ColumnMajor);

+        grid.push_row(vec!['b', 'b', 'b', 'b']);

+        test_grid(&grid, 1, 4, Order::ColumnMajor, &['b', 'b', 'b', 'b']);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn push_empty_row_column_major() {

+        let mut grid = Grid::init_with_order(0, 1, Order::ColumnMajor, 0);

+        grid.push_row(vec![]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn push_row_wrong_size_column_major() {

+        let mut grid: Grid<char> =

+            Grid::from_vec_with_order(vec!['a', 'a', 'a', 'a', 'a', 'a'], 3, Order::ColumnMajor);

+        grid.push_row(vec!['b']);

+        grid.push_row(vec!['b', 'b', 'b', 'b']);

+    }

+

+    #[test]

+    fn iter_row() {

+        let grid = Grid::from_vec_with_order(vec![1, 2, 3, 4, 5, 6], 3, Order::RowMajor);

+        let row: Vec<_> = grid.iter_row(1).collect();

+        assert_eq!(row, [&4, &5, &6]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn iter_row_out_of_bound() {

+        let grid = Grid::from_vec_with_order(vec![1, 2, 3, 4, 5, 6], 3, Order::RowMajor);

+        let _ = grid.iter_row(3);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn iter_row_zero() {

+        let grid: Grid<u8> = Grid::from_vec_with_order(vec![], 0, Order::RowMajor);

+        let _ = grid.iter_row(0);

+    }

+

+    #[test]

+    fn iter_row_rowumn_major() {

+        let grid = Grid::from_vec_with_order(vec![1, 4, 2, 5, 3, 6], 3, Order::ColumnMajor);

+        let row: Vec<_> = grid.iter_row(1).collect();

+        assert_eq!(row, [&4, &5, &6]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn iter_row_rowumn_major_out_of_bound() {

+        let grid = Grid::from_vec_with_order(vec![1, 4, 2, 5, 3, 6], 3, Order::ColumnMajor);

+        let _ = grid.iter_row(3);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn iter_row_rowumn_major_zero() {

+        let grid: Grid<u8> = Grid::from_vec_with_order(vec![], 0, Order::ColumnMajor);

+        let _ = grid.iter_row(0);

+    }

+

+    #[test]

+    fn iter_row_mut() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 2, 3, 4, 5, 6], 3, Order::RowMajor);

+        let row: Vec<_> = grid.iter_row_mut(1).collect();

+        assert_eq!(row, [&mut 4, &mut 5, &mut 6]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn iter_row_mut_out_of_bound() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 2, 3, 4, 5, 6], 3, Order::RowMajor);

+        let _ = grid.iter_row_mut(3);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn iter_row_mut_zero() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![], 0, Order::RowMajor);

+        let _ = grid.iter_row_mut(0);

+    }

+

+    #[test]

+    fn iter_row_mut_rowumn_major() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 4, 2, 5, 3, 6], 3, Order::ColumnMajor);

+        let row: Vec<_> = grid.iter_row_mut(1).collect();

+        assert_eq!(row, [&mut 4, &mut 5, &mut 6]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn iter_row_mut_rowumn_major_out_of_bound() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 4, 2, 5, 3, 6], 3, Order::ColumnMajor);

+        let _ = grid.iter_row_mut(3);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn iter_row_mut_rowumn_major_zero() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![], 0, Order::ColumnMajor);

+        let _ = grid.iter_row_mut(0);

+    }

+

+    #[test]

+    fn iter_col() {

+        let grid = Grid::from_vec_with_order(vec![1, 2, 3, 4, 5, 6], 3, Order::RowMajor);

+        let col: Vec<_> = grid.iter_col(1).collect();

+        assert_eq!(col, [&2, &5]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn iter_col_out_of_bound() {

+        let grid = Grid::from_vec_with_order(vec![1, 2, 3, 4, 5, 6], 3, Order::RowMajor);

+        let _ = grid.iter_col(3);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn iter_col_zero() {

+        let grid: Grid<u8> = Grid::from_vec_with_order(vec![], 0, Order::RowMajor);

+        let _ = grid.iter_col(0);

+    }

+

+    #[test]

+    fn iter_col_column_major() {

+        let grid = Grid::from_vec_with_order(vec![1, 4, 2, 5, 3, 6], 3, Order::ColumnMajor);

+        let col: Vec<_> = grid.iter_col(1).collect();

+        assert_eq!(col, [&2, &5]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn iter_col_column_major_out_of_bound() {

+        let grid = Grid::from_vec_with_order(vec![1, 4, 2, 5, 3, 6], 3, Order::ColumnMajor);

+        let _ = grid.iter_col(3);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn iter_col_column_major_zero() {

+        let grid: Grid<u8> = Grid::from_vec_with_order(vec![], 0, Order::ColumnMajor);

+        let _ = grid.iter_col(0);

+    }

+

+    #[test]

+    fn iter_col_mut() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 2, 3, 4, 5, 6], 3, Order::RowMajor);

+        let col: Vec<_> = grid.iter_col_mut(1).collect();

+        assert_eq!(col, [&mut 2, &mut 5]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn iter_col_mut_out_of_bound() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 2, 3, 4, 5, 6], 3, Order::RowMajor);

+        let _ = grid.iter_col_mut(3);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn iter_col_mut_zero() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![], 0, Order::RowMajor);

+        let _ = grid.iter_col_mut(0);

+    }

+

+    #[test]

+    fn iter_col_mut_column_major() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 4, 2, 5, 3, 6], 3, Order::ColumnMajor);

+        let col: Vec<_> = grid.iter_col_mut(1).collect();

+        assert_eq!(col, [&mut 2, &mut 5]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn iter_col_mut_column_major_out_of_bound() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 4, 2, 5, 3, 6], 3, Order::ColumnMajor);

+        let _ = grid.iter_col_mut(3);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn iter_col_mut_column_major_zero() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![], 0, Order::ColumnMajor);

+        let _ = grid.iter_col_mut(0);

+    }

+

+    #[test]

+    fn iter() {

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

+    }

+

+    #[test]

+    fn into_iter() {

+        let grid: Grid<u8> = grid![[1,1][1,1]];

+        for val in &grid {

+            assert_eq!(val, &1);

+        }

+    }

+

+    #[test]

+    fn into_iter_mut() {

+        let mut grid: Grid<u8> = grid![[1,1][1,1]];

+        for val in &mut grid {

+            *val = 2;

+        }

+        assert_eq!(grid, grid![[2, 2][2, 2]]);

+    }

+

+    #[test]

+    fn indexed_iter() {

+        let grid: Grid<u8> = grid![[1,2][3,4]];

+        let mut iter = grid.indexed_iter();

+        assert_eq!(iter.next(), Some(((0, 0), &1)));

+        assert_eq!(iter.next(), Some(((0, 1), &2)));

+        assert_eq!(iter.next(), Some(((1, 0), &3)));

+        assert_eq!(iter.next(), Some(((1, 1), &4)));

+        assert_eq!(iter.next(), None);

+    }

+

+    #[test]

+    fn indexed_iter_empty() {

+        let grid: Grid<u8> = Grid::new(0, 0);

+        let mut iter = grid.indexed_iter();

+        assert_eq!(iter.next(), None);

+    }

+

+    #[test]

+    fn indexed_iter_column_major() {

+        let grid: Grid<u8> = Grid::from_vec_with_order(vec![1, 3, 2, 4], 2, Order::ColumnMajor);

+        let mut iter = grid.indexed_iter();

+        assert_eq!(iter.next(), Some(((0, 0), &1)));

+        assert_eq!(iter.next(), Some(((1, 0), &3)));

+        assert_eq!(iter.next(), Some(((0, 1), &2)));

+        assert_eq!(iter.next(), Some(((1, 1), &4)));

+        assert_eq!(iter.next(), None);

+    }

+

+    #[test]

+    fn indexed_iter_empty_column_major() {

+        let grid: Grid<u8> = Grid::new_with_order(0, 0, Order::ColumnMajor);

+        let mut iter = grid.indexed_iter();

+        assert_eq!(iter.next(), None);

+    }

+

+    #[test]

+    fn indexed_iter_mut() {

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

+        assert_eq!(iter.next(), Some(((0, 1), &mut 2)));

+        assert_eq!(iter.next(), Some(((1, 0), &mut 3)));

+        assert_eq!(iter.next(), Some(((1, 1), &mut 4)));

+        assert_eq!(iter.next(), None);

+    }

+

+    #[test]

+    fn indexed_iter_mut_empty() {

+        let mut grid: Grid<u8> = Grid::new(0, 0);

+        let mut iter = grid.indexed_iter_mut();

+        assert_eq!(iter.next(), None);

+    }

+

+    #[test]

+    fn indexed_iter_mut_column_major() {

+        let mut grid: Grid<u8> = Grid::from_vec_with_order(vec![1, 3, 2, 4], 2, Order::ColumnMajor);

+        let mut iter = grid.indexed_iter_mut();

+        assert_eq!(iter.next(), Some(((0, 0), &mut 1)));

+        assert_eq!(iter.next(), Some(((1, 0), &mut 3)));

+        assert_eq!(iter.next(), Some(((0, 1), &mut 2)));

+        assert_eq!(iter.next(), Some(((1, 1), &mut 4)));

+        assert_eq!(iter.next(), None);

+    }

+

+    #[test]

+    fn indexed_iter_mut_empty_column_major() {

+        let mut grid: Grid<u8> = Grid::new_with_order(0, 0, Order::ColumnMajor);

+        let mut iter = grid.indexed_iter_mut();

+        assert_eq!(iter.next(), None);

+    }

+

+    #[test]

+    fn clear() {

+        let mut grid: Grid<u8> = grid![[1, 2, 3]];

+        assert!(!grid.is_empty());

+        grid.clear();

+        assert!(grid.is_empty());

+    }

+

+    #[test]

+    fn is_empty_false() {

+        let grid: Grid<u8> = grid![[1, 2, 3]];

+        assert!(!grid.is_empty());

+    }

+

+    #[test]

+    fn is_empty() {

+        let mut g: Grid<u8> = grid![[]];

+        assert!(g.is_empty());

+        g = grid![];

+        assert!(g.is_empty());

+        g = Grid::from_vec(vec![], 0);

+        assert!(g.is_empty());

+        g = Grid::new(0, 0);

+        assert!(g.is_empty());

+        g = Grid::new(0, 1);

+        assert!(g.is_empty());

+        g = Grid::new(1, 0);

+        assert!(g.is_empty());

+        g = Grid::init(0, 0, 10);

+        assert!(g.is_empty());

+    }

+

+    #[test]

+    fn fmt_empty() {

+        let grid: Grid<u8> = grid![];

+        assert_eq!(format!("{grid:?}"), "[]");

+    }

+

+    #[test]

+    fn fmt_row() {

+        let grid: Grid<u8> = grid![[1, 2, 3]];

+        assert_eq!(format!("{grid:?}"), "[[1, 2, 3]]");

+    }

+

+    #[test]

+    fn fmt_grid() {

+        let grid: Grid<u8> = grid![[1,2,3][4,5,6][7,8,9]];

+        assert_eq!(format!("{grid:?}"), "[[1, 2, 3][4, 5, 6][7, 8, 9]]");

+    }

+

+    #[test]

+    fn fmt_column_major() {

+        let grid = Grid::from_vec_with_order(vec![1, 4, 2, 5, 3, 6], 3, Order::ColumnMajor);

+        assert_eq!(format!("{grid:?}"), "[[1, 2, 3][4, 5, 6]]");

+    }

+

+    #[test]

+    fn fmt_pretty_empty() {

+        let grid: Grid<f32> = grid![];

+        assert_eq!(format!("{grid:#?}"), "[]");

+    }

+

+    #[test]

+    fn fmt_pretty_int() {

+        let grid: Grid<u8> = grid![

+            [1,2,3]

+            [4,5,6]

+            [7,8,95]

+        ];

+

+        let expected_output = r"[

+    [  1,  2,  3]

+    [  4,  5,  6]

+    [  7,  8, 95]

+]";

+

+        assert_eq!(format!("{grid:#?}"), expected_output);

+

+        let expected_output = r"[

+    [   1,   2,   3]

+    [   4,   5,   6]

+    [   7,   8,  95]

+]";

+

+        assert_eq!(format!("{grid:#3?}"), expected_output);

+    }

+

+    #[test]

+    fn fmt_pretty_float() {

+        let grid: Grid<f32> = grid![

+            [1.5,2.6,3.44]

+            [4.775,5.,6.]

+            [7.1,8.23444,95.55]

+        ];

+

+        let expected_output = r"[

+    [   1.5,   2.6,   3.4]

+    [   4.8,   5.0,   6.0]

+    [   7.1,   8.2,  95.6]

+]";

+

+        assert_eq!(format!("{grid:#5.1?}"), expected_output);

+

+        let expected_output = r"[

+    [  1.50000,  2.60000,  3.44000]

+    [  4.77500,  5.00000,  6.00000]

+    [  7.10000,  8.23444, 95.55000]

+]";

+

+        assert_eq!(format!("{grid:#8.5?}"), expected_output);

+    }

+

+    #[test]

+    fn fmt_pretty_tuple() {

+        let grid: Grid<(i32, i32)> = grid![

+            [(5,66), (432, 55)]

+            [(80, 90), (5, 6)]

+        ];

+

+        let expected_output = r"[

+    [ (        5,        66), (      432,        55)]

+    [ (       80,        90), (        5,         6)]

+]";

+

+        assert_eq!(format!("{grid:#?}"), expected_output);

+

+        let expected_output = r"[

+    [ (  5,  66), (432,  55)]

+    [ ( 80,  90), (  5,   6)]

+]";

+

+        assert_eq!(format!("{grid:#3?}"), expected_output);

+    }

+

+    #[test]

+    fn fmt_pretty_struct_derived() {

+        #[derive(Debug)]

+        struct Person {

+            _name: String,

+            _precise_age: f32,

+        }

+

+        impl Person {

+            fn new(name: &str, precise_age: f32) -> Self {

+                Self {

+                    _name: name.into(),

+                    _precise_age: precise_age,

+                }

+            }

+        }

+

+        let grid: Grid<Person> = grid![

+            [Person::new("Vic", 24.5), Person::new("Mr. Very Long Name", 1955.)]

+            [Person::new("Sam", 8.9995), Person::new("John Doe", 40.14)]

+        ];

+

+        let expected_output = r#"[

+    [ Person { _name: "Vic", _precise_age: 24.50000 }, Person { _name: "Mr. Very Long Name", _precise_age: 1955.00000 }]

+    [ Person { _name: "Sam", _precise_age: 8.99950 }, Person { _name: "John Doe", _precise_age: 40.14000 }]

+]"#;

+

+        assert_eq!(format!("{grid:#5.5?}"), expected_output);

+    }

+

+    #[test]

+    fn fmt_pretty_column_major() {

+        let grid = Grid::from_vec_with_order(vec![1, 4, 2, 5, 3, 6], 3, Order::ColumnMajor);

+        let expected_output = r"[

+    [ 1, 2, 3]

+    [ 4, 5, 6]

+]";

+        assert_eq!(format!("{grid:#?}"), expected_output);

+    }

+

+    #[test]

+    fn clone() {

+        let grid = grid![[1, 2, 3][4, 5, 6]];

+        let mut clone = grid.clone();

+        clone[(0, 2)] = 10;

+        test_grid(&grid, 2, 3, Order::RowMajor, &[1, 2, 3, 4, 5, 6]);

+        test_grid(&clone, 2, 3, Order::RowMajor, &[1, 2, 10, 4, 5, 6]);

+    }

+

+    #[cfg(feature = "std")]

+    #[test]

+    fn hash_std() {

+        let mut set = std::collections::HashSet::new();

+        set.insert(grid![[1,2,3][4,5,6]]);

+        set.insert(grid![[1,3,3][4,5,6]]);

+        set.insert(grid![[1,2,3][4,5,6]]);

+        assert_eq!(set.len(), 2);

+    }

+

+    #[test]

+    fn macro_init() {

+        let grid = grid![[1, 2, 3][4, 5, 6]];

+        test_grid(&grid, 2, 3, Order::RowMajor, &[1, 2, 3, 4, 5, 6]);

+    }

+

+    #[test]

+    fn macro_init_2() {

+        let grid = grid![[1, 2, 3]

+                         [4, 5, 6]

+                         [7, 8, 9]];

+        test_grid(&grid, 3, 3, Order::RowMajor, &[1, 2, 3, 4, 5, 6, 7, 8, 9]);

+    }

+

+    #[test]

+    fn macro_init_char() {

+        let grid = grid![['a', 'b', 'c']

+                         ['a', 'b', 'c']

+                         ['a', 'b', 'c']];

+        let expected = ['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c'];

+        test_grid(&grid, 3, 3, Order::RowMajor, &expected);

+    }

+

+    #[test]

+    fn macro_one_row() {

+        let grid: Grid<usize> = grid![[1, 2, 3, 4]];

+        test_grid(&grid, 1, 4, Order::RowMajor, &[1, 2, 3, 4]);

+    }

+

+    #[test]

+    fn macro2_empty() {

+        let grid: Grid<u8> = grid_cm![];

+        test_grid(&grid, 0, 0, Order::ColumnMajor, &[]);

+    }

+

+    #[test]

+    fn macro2_init() {

+        let grid = grid_cm![[1, 2, 3]

+                          [4, 5, 6]

+                          [7, 8, 9]];

+        let expected = [1, 4, 7, 2, 5, 8, 3, 6, 9];

+        test_grid(&grid, 3, 3, Order::ColumnMajor, &expected);

+    }

+

+    #[test]

+    fn macro2_init_char() {

+        let grid = grid_cm![['a', 'b']['c', 'd']];

+        test_grid(&grid, 2, 2, Order::ColumnMajor, &['a', 'c', 'b', 'd']);

+    }

+

+    #[test]

+    fn macro2_one_row() {

+        let grid = grid_cm![[1, 2, 3, 4]];

+        test_grid(&grid, 1, 4, Order::ColumnMajor, &[1, 2, 3, 4]);

+    }

+

+    #[test]

+    fn init() {

+        let grid = Grid::init(1, 2, 3);

+        test_grid(&grid, 1, 2, Order::RowMajor, &[3, 3]);

+

+        let grid = Grid::init(1, 2, 1.2);

+        test_grid(&grid, 1, 2, Order::RowMajor, &[1.2, 1.2]);

+

+        let grid = Grid::init(1, 2, 'a');

+        test_grid(&grid, 1, 2, Order::RowMajor, &['a', 'a']);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn init_panics() {

+        Grid::init(usize::MAX, 2, 3);

+    }

+

+    #[test]

+    fn init_empty() {

+        let grid = Grid::init(0, 1, 0);

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+

+        let grid = Grid::init(1, 0, -1);

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+    }

+

+    #[test]

+    fn init_with_order() {

+        let grid = Grid::init_with_order(1, 2, Order::RowMajor, 3);

+        test_grid(&grid, 1, 2, Order::RowMajor, &[3, 3]);

+

+        let grid = Grid::init_with_order(1, 2, Order::ColumnMajor, 1.2);

+        test_grid(&grid, 1, 2, Order::ColumnMajor, &[1.2, 1.2]);

+

+        let grid = Grid::init_with_order(1, 2, Order::ColumnMajor, 'a');

+        test_grid(&grid, 1, 2, Order::ColumnMajor, &['a', 'a']);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn init_with_order_panics() {

+        Grid::init_with_order(usize::MAX, 2, Order::ColumnMajor, 3);

+    }

+

+    #[test]

+    fn init_with_order_empty() {

+        let grid = Grid::init_with_order(0, 1, Order::ColumnMajor, 0);

+        test_grid(&grid, 0, 0, Order::ColumnMajor, &[]);

+

+        let grid = Grid::init_with_order(1, 0, Order::RowMajor, -1);

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+    }

+

+    #[test]

+    fn new() {

+        let grid: Grid<u8> = Grid::new(1, 2);

+        test_grid(&grid, 1, 2, Order::RowMajor, &[0, 0]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn new_panics() {

+        let _: Grid<u8> = Grid::new(usize::MAX, 2);

+    }

+

+    #[test]

+    fn new_empty() {

+        let grid: Grid<u8> = Grid::new(0, 1);

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+

+        let grid: Grid<u8> = Grid::new(1, 0);

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+    }

+

+    #[test]

+    fn new_with_order() {

+        let grid: Grid<u8> = Grid::new_with_order(2, 2, Order::ColumnMajor);

+        test_grid(&grid, 2, 2, Order::ColumnMajor, &[0, 0, 0, 0]);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn new_with_order_panics() {

+        let _: Grid<u8> = Grid::new_with_order(usize::MAX, 2, Order::ColumnMajor);

+    }

+

+    #[test]

+    fn new_with_order_empty() {

+        let grid: Grid<u8> = Grid::new_with_order(0, 3, Order::RowMajor);

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+

+        let grid: Grid<u8> = Grid::new_with_order(3, 0, Order::ColumnMajor);

+        test_grid(&grid, 0, 0, Order::ColumnMajor, &[]);

+    }

+

+    #[test]

+    fn with_capacity() {

+        // doesn't impl Default

+        struct Foo();

+

+        let grid: Grid<Foo> = Grid::with_capacity(20, 20);

+        assert!(grid.is_empty());

+        assert_eq!(grid.order(), Order::default());

+    }

+

+    #[test]

+    fn with_capacity_and_order() {

+        // doesn't impl Default

+        struct Foo();

+

+        let grid: Grid<Foo> = Grid::with_capacity_and_order(20, 20, Order::ColumnMajor);

+        assert!(grid.is_empty());

+        assert_eq!(grid.order(), Order::ColumnMajor);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn with_capacity_panics_internal() {

+        // doesn't impl Default

+        struct Foo();

+

+        let _grid: Grid<Foo> = Grid::with_capacity_and_order(usize::MAX, 2, Order::RowMajor);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn with_capacity_panics_vec() {

+        let rows: usize = isize::MAX.try_into().expect("isize::MAX is positive");

+        assert!(

+            core::mem::size_of::<u8>() * rows < usize::MAX,

+            "shows that panic is from Vec::with_capacity, not internal check"

+        );

+

+        let _grid: Grid<u8> = Grid::with_capacity_and_order(rows, 2, Order::RowMajor);

+    }

+

+    #[test]

+    fn get() {

+        let grid = Grid::from_vec_with_order(vec![1, 2], 2, Order::RowMajor);

+        assert_eq!(grid.get(0_i64, 1_i32), Some(&2));

+    }

+

+    #[test]

+    fn get_column_major() {

+        let grid = Grid::from_vec_with_order(vec![1, 2], 1, Order::ColumnMajor);

+        assert_eq!(grid.get(1, 0), Some(&2));

+    }

+

+    #[test]

+    fn get_none() {

+        let grid = Grid::from_vec_with_order(vec![1, 2], 2, Order::RowMajor);

+        assert_eq!(grid.get(1, 0), None);

+    }

+

+    #[test]

+    fn get_none_column_major() {

+        let grid = Grid::from_vec_with_order(vec![1, 2], 1, Order::ColumnMajor);

+        assert_eq!(grid.get(0, 1), None);

+    }

+

+    #[test]

+    fn get_mut() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 2], 2, Order::RowMajor);

+        assert_eq!(grid.get_mut(0_i64, 1_i32), Some(&mut 2));

+    }

+

+    #[test]

+    fn get_mut_column_major() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 2], 1, Order::ColumnMajor);

+        assert_eq!(grid.get_mut(1, 0), Some(&mut 2));

+    }

+

+    #[test]

+    fn get_mut_none() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 2], 2, Order::RowMajor);

+        assert_eq!(grid.get_mut(1, 0), None);

+    }

+

+    #[test]

+    fn get_mut_none_column_major() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 2], 1, Order::ColumnMajor);

+        assert_eq!(grid.get_mut(0, 1), None);

+    }

+

+    #[test]

+    fn idx_tup() {

+        let grid: Grid<u8> = Grid::from_vec(vec![1, 2, 3, 4], 2);

+        assert_eq!(grid[(0, 0)], 1);

+        assert_eq!(grid[(0, 1)], 2);

+        assert_eq!(grid[(1, 0)], 3);

+        assert_eq!(grid[(1, 1)], 4);

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn idx_tup_panic_1() {

+        let grid = Grid::init(1, 2, 3);

+        let _ = grid[(20, 0)];

+    }

+

+    #[test]

+    #[should_panic]

+    #[allow(clippy::should_panic_without_expect)]

+    fn idx_tup_panic_2() {

+        let grid = Grid::init(1, 2, 3);

+        let _ = grid[(0, 20)];

+    }

+

+    #[test]

+    fn idx_tup_set() {

+        let mut grid = Grid::init(1, 2, 3);

+        grid[(0, 0)] = 4;

+        assert_eq!(grid[(0, 0)], 4);

+    }

+

+    #[test]

+    fn size() {

+        let grid = Grid::init(1, 2, 3);

+        assert_eq!(grid.size(), (1, 2));

+    }

+

+    #[test]

+    fn transpose() {

+        let mut grid: Grid<u8> = grid![[1,2,3][4,5,6]];

+        grid.transpose();

+        assert_eq!(grid, grid![[1,4][2,5][3,6]]);

+    }

+

+    #[test]

+    fn fill() {

+        let mut grid: Grid<u8> = grid![[1,2,3][4,5,6]];

+        grid.fill(7);

+        test_grid(&grid, 2, 3, Order::RowMajor, &[7, 7, 7, 7, 7, 7]);

+    }

+

+    #[test]

+    fn fill_with() {

+        let mut grid: Grid<u8> = grid![[1,2,3][4,5,6]];

+        grid.fill_with(Default::default);

+        test_grid(&grid, 2, 3, Order::RowMajor, &[0, 0, 0, 0, 0, 0]);

+    }

+

+    #[test]

+    fn map() {

+        let grid: Grid<u8> = grid![[1,2,3][4,5,6]];

+        let mapped = grid.map(|x| x * 2);

+        test_grid(&mapped, 2, 3, Order::RowMajor, &[2, 4, 6, 8, 10, 12]);

+    }

+

+    #[test]

+    fn map_ref() {

+        let grid: Grid<u8> = grid![[1,2,3][4,5,6]];

+        let mapped = grid.map_ref(|x| *x * 2);

+        test_grid(&mapped, 2, 3, Order::RowMajor, &[2, 4, 6, 8, 10, 12]);

+    }

+

+    #[test]

+    #[allow(clippy::redundant_closure_for_method_calls)]

+    fn iter_rows() {

+        let grid: Grid<u8> = grid![[1,2,3][4,5,6]];

+        let max_by_row: Vec<u8> = grid

+            .iter_rows()

+            .map(|row| row.max().unwrap())

+            .copied()

+            .collect();

+        assert_eq!(max_by_row, vec![3, 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]);

+    }

+

+    #[test]

+    #[allow(clippy::redundant_closure_for_method_calls)]

+    fn iter_rows_rev() {

+        let grid: Grid<u8> = grid![[1,2,3][4,5,6]];

+        let max_by_row: Vec<u8> = grid

+            .iter_rows()

+            .rev()

+            .map(|row| row.max().unwrap())

+            .copied()

+            .collect();

+        assert_eq!(max_by_row, vec![6, 3]);

+

+        let sum_by_row: Vec<u8> = grid.iter_rows().rev().map(|row| row.sum()).collect();

+        assert_eq!(sum_by_row, vec![4 + 5 + 6, 1 + 2 + 3]);

+    }

+

+    #[test]

+    fn iter_rows_exact_size() {

+        let grid: Grid<u8> = grid![[1,2,3][4,5,6]];

+        let mut row_iter = grid.iter_rows();

+        assert_eq!(row_iter.len(), 2);

+        assert!(row_iter.next().is_some());

+        assert_eq!(row_iter.len(), 1);

+        assert!(row_iter.next().is_some());

+        assert_eq!(row_iter.len(), 0);

+        assert!(row_iter.next().is_none());

+    }

+

+    #[test]

+    #[allow(clippy::redundant_closure_for_method_calls)]

+    fn iter_cols() {

+        let grid: Grid<u8> = grid![[1,2,3][4,5,6]];

+        let max_by_col: Vec<u8> = grid

+            .iter_cols()

+            .map(|col| col.max().unwrap())

+            .copied()

+            .collect();

+

+        assert_eq!(max_by_col, vec![4, 5, 6]);

+

+        let sum_by_col: Vec<u8> = grid.iter_cols().map(|row| row.sum()).collect();

+        assert_eq!(sum_by_col, vec![1 + 4, 2 + 5, 3 + 6]);

+    }

+

+    #[test]

+    #[allow(clippy::redundant_closure_for_method_calls)]

+    fn iter_cols_rev() {

+        let grid: Grid<u8> = grid![[1,2,3][4,5,6]];

+        let max_by_col: Vec<u8> = grid

+            .iter_cols()

+            .rev()

+            .map(|col| col.max().unwrap())

+            .copied()

+            .collect();

+

+        assert_eq!(max_by_col, vec![6, 5, 4]);

+

+        let sum_by_col: Vec<u8> = grid.iter_cols().rev().map(|row| row.sum()).collect();

+        assert_eq!(sum_by_col, vec![3 + 6, 2 + 5, 1 + 4]);

+    }

+

+    #[test]

+    fn iter_cols_exact_size() {

+        let grid: Grid<u8> = grid![[1,2,3][4,5,6]];

+        let mut col_iter = grid.iter_cols();

+        assert_eq!(col_iter.len(), 3);

+        assert!(col_iter.next().is_some());

+        assert_eq!(col_iter.len(), 2);

+        assert!(col_iter.next().is_some());

+        assert_eq!(col_iter.len(), 1);

+        assert!(col_iter.next().is_some());

+        assert_eq!(col_iter.len(), 0);

+        assert!(col_iter.next().is_none());

+    }

+

+    #[test]

+    fn remove_row() {

+        let mut grid = grid![[1,2][3,4][5,6]];

+        assert_eq![grid.remove_row(1), Some(vec![3, 4])];

+        test_grid(&grid, 2, 2, Order::RowMajor, &[1, 2, 5, 6]);

+        assert_eq![grid.remove_row(0), Some(vec![1, 2])];

+        test_grid(&grid, 1, 2, Order::RowMajor, &[5, 6]);

+        assert_eq![grid.remove_row(0), Some(vec![5, 6])];

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+        assert_eq![grid.remove_row(0), None];

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+    }

+

+    #[test]

+    fn remove_row_out_of_bound() {

+        let mut grid = grid![[1, 2][3, 4]];

+        assert_eq![grid.remove_row(5), None];

+        test_grid(&grid, 2, 2, Order::RowMajor, &[1, 2, 3, 4]);

+        assert_eq![grid.remove_row(1), Some(vec![3, 4])];

+        test_grid(&grid, 1, 2, Order::RowMajor, &[1, 2]);

+    }

+

+    #[test]

+    fn remove_row_column_major() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 3, 5, 2, 4, 6], 2, Order::ColumnMajor);

+        assert_eq![grid.remove_row(1), Some(vec![3, 4])];

+        test_grid(&grid, 2, 2, Order::ColumnMajor, &[1, 5, 2, 6]);

+        assert_eq![grid.remove_row(0), Some(vec![1, 2])];

+        test_grid(&grid, 1, 2, Order::ColumnMajor, &[5, 6]);

+        assert_eq![grid.remove_row(0), Some(vec![5, 6])];

+        test_grid(&grid, 0, 0, Order::ColumnMajor, &[]);

+        assert_eq![grid.remove_row(0), None];

+        test_grid(&grid, 0, 0, Order::ColumnMajor, &[]);

+    }

+

+    #[test]

+    fn remove_row_out_of_bound_column_major() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 3, 2, 4], 2, Order::ColumnMajor);

+        assert_eq![grid.remove_row(5), None];

+        test_grid(&grid, 2, 2, Order::ColumnMajor, &[1, 3, 2, 4]);

+        assert_eq![grid.remove_row(1), Some(vec![3, 4])];

+        test_grid(&grid, 1, 2, Order::ColumnMajor, &[1, 2]);

+    }

+

+    #[test]

+    fn remove_col() {

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

+        let expected = [1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15];

+        test_grid(&grid, 4, 3, Order::RowMajor, &expected);

+        assert_eq![grid.remove_col(0), Some(vec![1, 5, 9, 13])];

+        test_grid(&grid, 4, 2, Order::RowMajor, &[2, 3, 6, 7, 10, 11, 14, 15]);

+        assert_eq![grid.remove_col(1), Some(vec![3, 7, 11, 15])];

+        test_grid(&grid, 4, 1, Order::RowMajor, &[2, 6, 10, 14]);

+        assert_eq![grid.remove_col(0), Some(vec![2, 6, 10, 14])];

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+        assert_eq![grid.remove_col(0), None];

+        test_grid(&grid, 0, 0, Order::RowMajor, &[]);

+    }

+

+    #[test]

+    fn remove_col_out_of_bound() {

+        let mut grid = grid![[1, 2][3, 4]];

+        assert_eq!(grid.remove_col(5), None);

+        test_grid(&grid, 2, 2, Order::RowMajor, &[1, 2, 3, 4]);

+        assert_eq!(grid.remove_col(1), Some(vec![2, 4]));

+        test_grid(&grid, 2, 1, Order::RowMajor, &[1, 3]);

+    }

+

+    #[test]

+    fn remove_col_column_major() {

+        let internal = vec![1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16];

+        let mut grid = Grid::from_vec_with_order(internal, 4, Order::ColumnMajor);

+        assert_eq![grid.remove_col(3), Some(vec![4, 8, 12, 16])];

+        let expected = [1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15];

+        test_grid(&grid, 4, 3, Order::ColumnMajor, &expected);

+        assert_eq![grid.remove_col(0), Some(vec![1, 5, 9, 13])];

+        let expected = [2, 6, 10, 14, 3, 7, 11, 15];

+        test_grid(&grid, 4, 2, Order::ColumnMajor, &expected);

+        assert_eq![grid.remove_col(1), Some(vec![3, 7, 11, 15])];

+        test_grid(&grid, 4, 1, Order::ColumnMajor, &[2, 6, 10, 14]);

+        assert_eq![grid.remove_col(0), Some(vec![2, 6, 10, 14])];

+        test_grid(&grid, 0, 0, Order::ColumnMajor, &[]);

+        assert_eq![grid.remove_col(0), None];

+        test_grid(&grid, 0, 0, Order::ColumnMajor, &[]);

+    }

+

+    #[test]

+    fn remove_col_out_of_bound_column_major() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 3, 2, 4], 2, Order::ColumnMajor);

+        assert_eq!(grid.remove_col(5), None);

+        test_grid(&grid, 2, 2, Order::ColumnMajor, &[1, 3, 2, 4]);

+        assert_eq!(grid.remove_col(1), Some(vec![2, 4]));

+        test_grid(&grid, 2, 1, Order::ColumnMajor, &[1, 3]);

+    }

+

+    #[test]

+    fn flip_cols() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 2, 3, 4], 2, Order::RowMajor);

+        grid.flip_cols();

+        test_grid(&grid, 2, 2, Order::RowMajor, &[2, 1, 4, 3]);

+    }

+

+    #[test]

+    fn flip_cols_column_major() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 3, 2, 4], 2, Order::ColumnMajor);

+        grid.flip_cols();

+        test_grid(&grid, 2, 2, Order::ColumnMajor, &[2, 4, 1, 3]);

+    }

+

+    #[test]

+    fn flip_rows() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 2, 3, 4], 2, Order::RowMajor);

+        grid.flip_rows();

+        test_grid(&grid, 2, 2, Order::RowMajor, &[3, 4, 1, 2]);

+    }

+

+    #[test]

+    fn flip_rows_column_major() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 3, 2, 4], 2, Order::ColumnMajor);

+        grid.flip_rows();

+        test_grid(&grid, 2, 2, Order::ColumnMajor, &[3, 1, 4, 2]);

+    }

+

+    #[test]

+    fn rotate_left() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 2, 3, 4, 5, 6], 3, Order::RowMajor);

+        grid.rotate_left();

+        test_grid(&grid, 3, 2, Order::ColumnMajor, &[3, 2, 1, 6, 5, 4]);

+        assert_eq!(grid, grid![[3,6][2,5][1,4]]);

+    }

+

+    #[test]

+    fn rotate_left_column_major() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 4, 2, 5, 3, 6], 3, Order::ColumnMajor);

+        grid.rotate_left();

+        test_grid(&grid, 3, 2, Order::RowMajor, &[3, 6, 2, 5, 1, 4]);

+        assert_eq!(grid, grid![[3,6][2,5][1,4]]);

+    }

+

+    #[test]

+    fn rotate_right() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 2, 3, 4, 5, 6], 3, Order::RowMajor);

+        grid.rotate_right();

+        test_grid(&grid, 3, 2, Order::ColumnMajor, &[4, 5, 6, 1, 2, 3]);

+        assert_eq!(grid, grid![[4,1][5,2][6,3]]);

+    }

+

+    #[test]

+    fn rotate_right_column_major() {

+        let mut grid = Grid::from_vec_with_order(vec![1, 4, 2, 5, 3, 6], 3, Order::ColumnMajor);

+        grid.rotate_right();

+        test_grid(&grid, 3, 2, Order::RowMajor, &[4, 1, 5, 2, 6, 3]);

+        assert_eq!(grid, grid![[4,1][5,2][6,3]]);

+    }

+

+    #[test]

+    fn iter_cols_clone() {

+        let grid = grid![[1,2,3][4,5,6]];

+        let mut cols = grid.iter_cols().skip(1);

+        let c3: u8 = cols.clone().nth(1).unwrap().sum();

+        let c2: u8 = cols.next().unwrap().sum();

+        assert_eq!(c2, 2 + 5);

+        assert_eq!(c3, 3 + 6);

+    }

+

+    #[test]

+    fn iter_rows_clone() {

+        let grid = grid![[1,2,3][4,5,6][7,8,9]];

+        let mut rows = grid.iter_rows().skip(1);

+        let r3: u8 = rows.clone().nth(1).unwrap().sum();

+        let r2: u8 = rows.next().unwrap().sum();

+        assert_eq!(r2, 4 + 5 + 6);

+        assert_eq!(r3, 7 + 8 + 9);

+    }

+

+    #[test]

+    fn swap() {

+        let mut grid = grid![[1,2][4,5]];

+        grid.swap((0, 0), (1, 0));

+        let end_grid = grid![[4,2][1,5]];

+        assert_eq!(grid, end_grid);

+    }

+

+    #[test]

+    #[should_panic(expected = "grid index out of bounds: (2,0) out of (2,2)")]

+    fn swap_out_of_bounds() {

+        let mut grid = grid![[1,2][4,5]];

+        grid.swap((0, 0), (2, 0));

+    }

+

+    #[cfg(feature = "serde")]

+    mod serde_tests {

+        use super::*;

+

+        #[test]

+        fn serialize() {

+            let grid: Grid<u8> = grid![[1, 2][3, 4]];

+            let s = serde_json::to_string(&grid).unwrap();

+            assert_eq!(s, r#"{"cols":2,"data":[1,2,3,4],"order":"RowMajor"}"#);

+        }

+

+        #[test]

+        fn deserialize() {

+            let s = "{ \"cols\": 2, \"data\": [1, 2, 3, 4] }";

+            let grid: Grid<u8> = serde_json::from_str(s).unwrap();

+            assert_eq!(grid, grid![[1, 2][3, 4]]);

+        }

+

+        #[test]

+        fn deserialize_with_order() {

+            let s = "{ \"cols\": 2, \"data\": [1, 3, 2, 4], \"order\": \"ColumnMajor\" }";

+            let grid: Grid<u8> = serde_json::from_str(s).unwrap();

+            test_grid(&grid, 2, 2, Order::ColumnMajor, &[1, 3, 2, 4]);

+        }

+    }

+}

diff --git a/pseudo_crate/Cargo.lock b/pseudo_crate/Cargo.lock
index 6fc1d93..6ba88bb 100644
--- a/pseudo_crate/Cargo.lock
+++ b/pseudo_crate/Cargo.lock
@@ -234,6 +234,7 @@
  "googletest",
  "googletest_macro",
  "gpio-cdev",
+ "grid",
  "grpcio",
  "grpcio-compiler",
  "grpcio-sys",
@@ -2560,6 +2561,12 @@
 ]
 
 [[package]]
+name = "grid"
+version = "0.16.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb6ae361963ea5fe52038156ea1729f3b4e4ccc0711c362ab2b2d2c0a259e7c3"
+
+[[package]]
 name = "grpcio"
 version = "0.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/pseudo_crate/Cargo.toml b/pseudo_crate/Cargo.toml
index 84d616a..76dbccc 100644
--- a/pseudo_crate/Cargo.toml
+++ b/pseudo_crate/Cargo.toml
@@ -143,6 +143,7 @@
 googletest = "=0.13.0"
 googletest_macro = "=0.13.0"
 gpio-cdev = "=0.6.0"
+grid = "=0.16.1"
 grpcio = "=0.13.0"
 grpcio-compiler = "=0.13.0"
 grpcio-sys = "=0.13.0"
diff --git a/pseudo_crate/crate-list.txt b/pseudo_crate/crate-list.txt
index 0f86736..81eb405 100644
--- a/pseudo_crate/crate-list.txt
+++ b/pseudo_crate/crate-list.txt
@@ -135,6 +135,7 @@
 googletest
 googletest_macro
 gpio-cdev
+grid
 grpcio
 grpcio-compiler
 grpcio-sys