#2d #array #matrix

no-std toodee

A lightweight 2D wrapper around a Vec

11 releases

0.3.0 Feb 20, 2021
0.2.4 Nov 19, 2020
0.2.3 Oct 24, 2020
0.2.1 Jun 11, 2020
0.1.2 May 28, 2020

#449 in Data structures

Download history 23/week @ 2022-11-28 30/week @ 2022-12-05 45/week @ 2022-12-12 27/week @ 2022-12-19 62/week @ 2022-12-26 21/week @ 2023-01-02 26/week @ 2023-01-09 26/week @ 2023-01-16 39/week @ 2023-01-23 41/week @ 2023-01-30 33/week @ 2023-02-06 66/week @ 2023-02-13 60/week @ 2023-02-20 18/week @ 2023-02-27 26/week @ 2023-03-06 26/week @ 2023-03-13

149 downloads per month
Used in 3 crates



Build Status Current Version Documentation License: MIT OR Apache-2.0


TooDee is a lightweight and high performance two-dimensional wrapper around a growable Vec.

TooDeeView and TooDeeViewMut allow you create two-dimensional wrappers around a slice.

Core features

  • Raw access to the underlying vector's slice via data() and data_mut().
  • Creation of performant two-dimensional subsets using view() and view_mut().
  • get_unchecked(Coordinate) and get_unchecked_row(usize) for faster (unsafe) access to cells or rows.
  • Most operations are implemented for both TooDee and TooDeeViewMut structs - see below for how this pattern can be extended.
  • Get/set specific cells using indexing, e.g., let my_row = toodee[row]; my_row[col] = val;.
  • Index with a Coordinate if you prefer, e.g., toodee[(col, row)] = val.
  • Index by row index (i.e., row major) to access row slices, e.g., &toodee[row].
  • Iteration, any which way - rows(), rows_mut(), col(), col_mut(), cells(), cells_mut().
  • #[no_std] compliant.
  • Can create a new TooDeeView from a &[T], or a TooDeeViewMut from a &mut [T].
  • insert_col(), remove_col(), insert_row(), and remove_row() implementations with good performance.

Additional Algorithms

CopyOps (copy feature, included by default)

Various operations that copy data within the same 2D array, or copy data from one array to another. Many of these operations are named like their slice counterparts, e.g., copy_from_slice() or copy_from_toodee().

TranslateOps (translate feature, included by default)

The TranslateOps trait provides common translation algorithms, including:

  • translate_with_wrap(), a way to shift data around vertically and horizontally.
  • flip_rows(), i.e., a mirror translation of data about the center row.
  • flip_cols(), i.e., a mirror translation of data about the center column.

SortOps (sort feature, included by default)

The SortOps trait provides efficient implementations of:

  • sort_by_row() operations, with stable and unstable variants.
  • sort_by_col() operations, with stable and unstable variants.

Build Your Own 2D Algorithms

Traits such as SortOps contain additional algorithms. These traits are defined by extending the TooDeeOpsMut trait, which has been implemented for TooDee and TooDeeViewMut. I recommend taking the same approach because the algorithms you implement will then work on both structs. This may not seem useful at first glance, but a great use case would be sorting a spreadsheet by column. If each column had a header row, you'd want to exclude that header row from sorting. You can achieve this by creating a TooDeeViewMut and sorting the view.

The implementation of your new trait could look something like:

pub trait FooOps<T> : TooDeeOpsMut<T> {

    fn foo(&mut self) -> Bar {
        return bar;

The above code would provide a default foo() implementation that could be overridden if required. Then it's simply a matter of stating that both TooDee and TooDeeOpsMut implement FooOps:

impl<T> FooOps<T> for TooDeeViewMut<'_, T> {}

impl<T> FooOps<T> for TooDee<T> {}

Once the implementations are available, just call the methods, e.g.,

let bar = my_toodee.foo();
let bar_view = my_toodee_mut_view.foo();

Happy coding :)


  • Pathfinding algorithms?
  • Image/bitmap algorithms?!


Similar libraries do exist, but they lacked either performance, flexibility, or functionality.

Here's a small feature comparison chart:

Storage orderStructs supportedGrowable?Mutable views?Raw data access?Iterate over row slices?Notes
toodee::TooDeeRow-majorAnything (Sized)YesYesYesYes
image::ImageBufferRow-majorimage::PixelNoNoYesNoGood for image processing - see the imageproc crate.
grid::GridRow-majorCloneYesNoYesNoSimilar to TooDee, but not as functionally rich.
imgref::ImgRow-majorAnything (Sized)NoYesYesYes
nalgebra::MatrixColumn-majorScalarYesYesYesNoUse this for vector/matrix math.


  • High performance and good flexibility, with the constraint of using a 1-D vector.
  • Suitable for use in image processing, but not restricted to this problem domain.
  • Provide solid implementations of non-trivial 2D operations.


  • GPU integration


  • Views are not nested for the time being, The only impact is that the bounds() of a view are always relative to the underlying TooDee array.


Licensed under either of

at your option.


Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

No runtime deps