From 4bbcabb2aa39917fe758e432468f4c443d4090f6 Mon Sep 17 00:00:00 2001 From: Andrew Cassidy Date: Mon, 22 May 2023 20:17:05 -0700 Subject: [PATCH] Document Index2D --- src/index.rs | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/index.rs b/src/index.rs index 6a2aeda..32a153c 100644 --- a/src/index.rs +++ b/src/index.rs @@ -1,12 +1,78 @@ +//! Helper trait for ergonomic matrix subscripting + use std::fmt::Debug; +/// Trait implemented by types that can be used as a matrix index +/// +/// There are currently two implementations: +/// [`usize`](#impl-Index2D-for-usize) and [`(usize,usize)`](#impl-Index2D-for-(usize,+usize)) +/// +/// # Examples +/// Indexing by a `usize` indexes starting at the first element and +/// increments linearly in row-major order. This is especially useful for column vectors. +/// +/// ``` +/// # use vector_victor::{Matrix, Vector}; +/// let m = Matrix::mat([[1,2,3],[4,5,6],[7,8,9]]); +/// assert_eq!(m[0], 1); +/// assert_eq!(m[4], 5); +/// assert_eq!(m[7], 8); +/// +/// let v = Vector::vec([4,8,15,16,23,42]); +/// assert_eq!(m[2], 15); // just like a std::vec +/// ``` +/// +/// Indexing by a `(usize,usize)` indexes by row and column +/// ``` +/// # use vector_victor::{Matrix, Vector}; +/// let m = Matrix::mat([[1,2,3],[4,5,6],[7,8,9]]); +/// assert_eq!(m[(0,0)], 1); +/// assert_eq!(m[(1,1)], 5); +/// assert_eq!(m[(2,1)], 8); +/// ``` pub trait Index2D: Copy + Debug { + /// Convert an index to its 1-D linear interpretation, given the `width` and `height` of the + /// matrix being subscripted. + /// + /// If the index is out of bounds for the given dimensions, this returns `None`, + /// otherwise it returns `Some(usize)` + /// + /// # Examples + /// ``` + /// # use vector_victor::index::Index2D; + /// assert_eq!( + /// (1usize,2usize).to_1d(3,3), + /// Some(5), + /// "(1,2) is index 5 in a 3×3 matrix"); + /// assert_eq!( + /// (3usize, 2usize).to_1d(3,3), + /// None, + /// "row 3, column 2 is out of bounds for a 3×3 matrix"); + /// ``` #[inline(always)] fn to_1d(self, height: usize, width: usize) -> Option { let (r, c) = self.to_2d(height, width)?; Some(r * width + c) } + /// Convert an index to its 2-D interpretation, given the `width` and `height` of the + /// matrix being subscripted. + /// + /// If the index is out of bounds for the given dimensions, this returns `None`, + /// otherwise it returns `Some((usize, usize))` + /// + /// # Examples + /// ``` + /// # use vector_victor::index::Index2D; + /// assert_eq!( + /// 5usize.to_2d(3,3), + /// Some((1usize,2usize)), + /// "index 5 is at row 1 column 2 in a 3×3 matrix"); + /// assert_eq!( + /// 10usize.to_2d(3,3), + /// None, + /// "a 3×3 matrix only has 9 elements, so index 10 is out of bounds."); + /// ``` fn to_2d(self, height: usize, width: usize) -> Option<(usize, usize)>; }