From b6959ef91390238ebf9a04b364d5ec335593fbf5 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Thu, 18 Sep 2014 12:20:36 +1000 Subject: [PATCH] Implement index operators Closes #18 --- src/structs/dmat.rs | 11 +++++++++++ src/structs/dvec_macros.rs | 12 ++++++++++++ src/structs/mat.rs | 6 ++++++ src/structs/mat_macros.rs | 34 +++++++++++++++++++++++----------- src/structs/rot.rs | 3 +++ src/structs/rot_macros.rs | 16 ++++++++++++++++ src/structs/vec.rs | 6 ++++++ src/structs/vec_macros.rs | 16 ++++++++++++++++ 8 files changed, 93 insertions(+), 11 deletions(-) diff --git a/src/structs/dmat.rs b/src/structs/dmat.rs index f57caa78..b1c9f356 100644 --- a/src/structs/dmat.rs +++ b/src/structs/dmat.rs @@ -267,6 +267,17 @@ impl Indexable<(uint, uint), N> for DMat { } +// TODO: implement after DST lands +/* +impl Index for DMat { + fn index(&self, i: &uint) -> &[N] { ... } +} + +impl IndexMut for DMat { + fn index_mut(&mut self, i: &uint) -> &mut [N] { ... } +} +*/ + impl + Add + Zero> DMatMulRhs> for DMat { fn binop(left: &DMat, right: &DMat) -> DMat { assert!(left.ncols == right.nrows); diff --git a/src/structs/dvec_macros.rs b/src/structs/dvec_macros.rs index 7c6d40f9..5469d97a 100644 --- a/src/structs/dvec_macros.rs +++ b/src/structs/dvec_macros.rs @@ -85,6 +85,18 @@ macro_rules! dvec_impl( } + impl Index for $dvec { + fn index(&self, i: &uint) -> &N { + &self.as_slice()[*i] + } + } + + impl IndexMut for $dvec { + fn index_mut(&mut self, i: &uint) -> &mut N { + &mut self.as_mut_slice()[*i] + } + } + impl $dvec { /// Builds a vector filled with ones. /// diff --git a/src/structs/mat.rs b/src/structs/mat.rs index 3ea96a9c..25845468 100644 --- a/src/structs/mat.rs +++ b/src/structs/mat.rs @@ -110,6 +110,7 @@ iterable_mut_impl!(Mat1, 1) at_fast_impl!(Mat1, 1) dim_impl!(Mat1, 1) indexable_impl!(Mat1, 1) +index_impl!(Mat1, Vec1, 1) mat_mul_mat_impl!(Mat1, Mat1MulRhs, 1) mat_mul_vec_impl!(Mat1, Vec1, Mat1MulRhs, 1) vec_mul_mat_impl!(Mat1, Vec1, Vec1MulRhs, 1) @@ -211,6 +212,7 @@ iterable_impl!(Mat2, 2) iterable_mut_impl!(Mat2, 2) dim_impl!(Mat2, 2) indexable_impl!(Mat2, 2) +index_impl!(Mat2, Vec2, 2) at_fast_impl!(Mat2, 2) // (specialized) mul_impl!(Mat2, 2) // (specialized) rmul_impl!(Mat2, Vec2, 2) @@ -327,6 +329,7 @@ iterable_impl!(Mat3, 3) iterable_mut_impl!(Mat3, 3) dim_impl!(Mat3, 3) indexable_impl!(Mat3, 3) +index_impl!(Mat3, Vec3, 3) at_fast_impl!(Mat3, 3) // (specialized) mul_impl!(Mat3, 3) // (specialized) rmul_impl!(Mat3, Vec3, 3) @@ -495,6 +498,7 @@ iterable_impl!(Mat4, 4) iterable_mut_impl!(Mat4, 4) dim_impl!(Mat4, 4) indexable_impl!(Mat4, 4) +index_impl!(Mat4, Vec4, 4) at_fast_impl!(Mat4, 4) mat_mul_mat_impl!(Mat4, Mat4MulRhs, 4) mat_mul_vec_impl!(Mat4, Vec4, Mat4MulRhs, 4) @@ -679,6 +683,7 @@ iterable_impl!(Mat5, 5) iterable_mut_impl!(Mat5, 5) dim_impl!(Mat5, 5) indexable_impl!(Mat5, 5) +index_impl!(Mat5, Vec5, 5) at_fast_impl!(Mat5, 5) mat_mul_mat_impl!(Mat5, Mat5MulRhs, 5) mat_mul_vec_impl!(Mat5, Vec5, Mat5MulRhs, 5) @@ -915,6 +920,7 @@ iterable_impl!(Mat6, 6) iterable_mut_impl!(Mat6, 6) dim_impl!(Mat6, 6) indexable_impl!(Mat6, 6) +index_impl!(Mat6, Vec6, 6) at_fast_impl!(Mat6, 6) mat_mul_mat_impl!(Mat6, Mat6MulRhs, 6) mat_mul_vec_impl!(Mat6, Vec6, Mat6MulRhs, 6) diff --git a/src/structs/mat_macros.rs b/src/structs/mat_macros.rs index 6233d69e..2edb38bf 100644 --- a/src/structs/mat_macros.rs +++ b/src/structs/mat_macros.rs @@ -225,6 +225,26 @@ macro_rules! indexable_impl( ) ) +macro_rules! index_impl( + ($t: ident, $tv: ident, $dim: expr) => ( + impl Index> for $t { + fn index(&self, i: &uint) -> &$tv { + unsafe { + &mem::transmute::<&$t, &[$tv, ..$dim]>(self)[*i] + } + } + } + + impl IndexMut> for $t { + fn index_mut(&mut self, i: &uint) -> &mut $tv { + unsafe { + &mut mem::transmute::<&mut $t, &mut [$tv, ..$dim]>(self)[*i] + } + } + } + ) +) + macro_rules! col_slice_impl( ($t: ident, $tv: ident, $slice: ident, $dim: expr) => ( impl ColSlice<$slice> for $t { @@ -239,7 +259,7 @@ macro_rules! col_slice_impl( macro_rules! row_impl( ($t: ident, $tv: ident, $dim: expr) => ( - impl Row<$tv> for $t { + impl Row<$tv> for $t { #[inline] fn nrows(&self) -> uint { Dim::dim(None::<$t>) @@ -247,20 +267,12 @@ macro_rules! row_impl( #[inline] fn set_row(&mut self, row: uint, v: $tv) { - for (i, e) in v.iter().enumerate() { - self.set((row, i), e.clone()); - } + self[row] = v; } #[inline] fn row(&self, row: uint) -> $tv { - let mut res: $tv = Zero::zero(); - - for (i, e) in res.mut_iter().enumerate() { - *e = self.at((row, i)); - } - - res + self[row].clone() } } ) diff --git a/src/structs/rot.rs b/src/structs/rot.rs index 7c9b17ec..d84f49f5 100644 --- a/src/structs/rot.rs +++ b/src/structs/rot.rs @@ -363,6 +363,7 @@ one_impl!(Rot2) rotation_matrix_impl!(Rot2, Vec2, Vec1) col_impl!(Rot2, Vec2) row_impl!(Rot2, Vec2) +index_impl!(Rot2, Vec2) absolute_impl!(Rot2, Mat2) to_homogeneous_impl!(Rot2, Mat3) inv_impl!(Rot2) @@ -382,6 +383,7 @@ one_impl!(Rot3) rotation_matrix_impl!(Rot3, Vec3, Vec3) col_impl!(Rot3, Vec3) row_impl!(Rot3, Vec3) +index_impl!(Rot3, Vec3) absolute_impl!(Rot3, Mat3) to_homogeneous_impl!(Rot3, Mat4) inv_impl!(Rot3) @@ -401,6 +403,7 @@ one_impl!(Rot4) rotation_matrix_impl!(Rot4, Vec4, Vec4) col_impl!(Rot4, Vec4) row_impl!(Rot4, Vec4) +index_impl!(Rot4, Vec4) absolute_impl!(Rot4, Mat4) to_homogeneous_impl!(Rot4, Mat5) inv_impl!(Rot4) diff --git a/src/structs/rot_macros.rs b/src/structs/rot_macros.rs index 7bcf8b38..a6caa497 100644 --- a/src/structs/rot_macros.rs +++ b/src/structs/rot_macros.rs @@ -186,6 +186,22 @@ macro_rules! col_impl( ) ) +macro_rules! index_impl( + ($t: ident, $tv: ident) => ( + impl Index> for $t { + fn index(&self, i: &uint) -> &$tv { + &self.submat[*i] + } + } + + impl IndexMut> for $t { + fn index_mut(&mut self, i: &uint) -> &mut $tv { + &mut self.submat[*i] + } + } + ) +) + macro_rules! to_homogeneous_impl( ($t: ident, $tm: ident) => ( impl ToHomogeneous<$tm> for $t { diff --git a/src/structs/vec.rs b/src/structs/vec.rs index 18d4a7d6..d9bef290 100644 --- a/src/structs/vec.rs +++ b/src/structs/vec.rs @@ -53,6 +53,7 @@ ord_impl!(Vec1, x) vec_axis_impl!(Vec1, x) vec_cast_impl!(Vec1, Vec1Cast, x) as_slice_impl!(Vec1, 1) +index_impl!(Vec1) indexable_impl!(Vec1, 1) at_fast_impl!(Vec1, 1) new_repeat_impl!(Vec1, val, x) @@ -151,6 +152,7 @@ ord_impl!(Vec2, x, y) vec_axis_impl!(Vec2, x, y) vec_cast_impl!(Vec2, Vec2Cast, x, y) as_slice_impl!(Vec2, 2) +index_impl!(Vec2) indexable_impl!(Vec2, 2) at_fast_impl!(Vec2, 2) new_repeat_impl!(Vec2, val, x, y) @@ -251,6 +253,7 @@ ord_impl!(Vec3, x, y, z) vec_axis_impl!(Vec3, x, y, z) vec_cast_impl!(Vec3, Vec3Cast, x, y, z) as_slice_impl!(Vec3, 3) +index_impl!(Vec3) indexable_impl!(Vec3, 3) at_fast_impl!(Vec3, 3) new_repeat_impl!(Vec3, val, x, y, z) @@ -357,6 +360,7 @@ ord_impl!(Vec4, x, y, z, w) vec_axis_impl!(Vec4, x, y, z, w) vec_cast_impl!(Vec4, Vec4Cast, x, y, z, w) as_slice_impl!(Vec4, 4) +index_impl!(Vec4) indexable_impl!(Vec4, 4) at_fast_impl!(Vec4, 4) new_repeat_impl!(Vec4, val, x, y, z, w) @@ -461,6 +465,7 @@ ord_impl!(Vec5, x, y, z, w, a) vec_axis_impl!(Vec5, x, y, z, w, a) vec_cast_impl!(Vec5, Vec5Cast, x, y, z, w, a) as_slice_impl!(Vec5, 5) +index_impl!(Vec5) indexable_impl!(Vec5, 5) at_fast_impl!(Vec5, 5) new_repeat_impl!(Vec5, val, x, y, z, w, a) @@ -567,6 +572,7 @@ ord_impl!(Vec6, x, y, z, w, a, b) vec_axis_impl!(Vec6, x, y, z, w, a, b) vec_cast_impl!(Vec6, Vec6Cast, x, y, z, w, a, b) as_slice_impl!(Vec6, 6) +index_impl!(Vec6) indexable_impl!(Vec6, 6) at_fast_impl!(Vec6, 6) new_repeat_impl!(Vec6, val, x, y, z, w, a, b) diff --git a/src/structs/vec_macros.rs b/src/structs/vec_macros.rs index 60eea525..d6f71d21 100644 --- a/src/structs/vec_macros.rs +++ b/src/structs/vec_macros.rs @@ -210,6 +210,22 @@ macro_rules! indexable_impl( ) ) +macro_rules! index_impl( + ($t: ident) => ( + impl Index for $t { + fn index(&self, i: &uint) -> &N { + &self.as_slice()[*i] + } + } + + impl IndexMut for $t { + fn index_mut(&mut self, i: &uint) -> &mut N { + &mut self.as_mut_slice()[*i] + } + } + ) +) + macro_rules! new_repeat_impl( ($t: ident, $param: ident, $comp0: ident $(,$compN: ident)*) => ( impl $t {