From bab38ca6d50f8d2dfe02fc17d4a186a8f9449d27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Fri, 21 Nov 2014 11:21:02 +0100 Subject: [PATCH] Add conversion from/to arrays for matrices and vectors. Use `.as_array()`, `.as_array_mut()`, `.from_array_ref()`, `.from_array_mut()`. Fix #33. --- src/structs/mat.rs | 6 +++++ src/structs/mat_macros.rs | 47 ++++++++++++++++++++++++++++++++++-- src/structs/pnt.rs | 12 +++++----- src/structs/quat.rs | 5 +--- src/structs/vec.rs | 12 +++++----- src/structs/vec_macros.rs | 50 ++++++++++++++++++++++++++++----------- 6 files changed, 100 insertions(+), 32 deletions(-) diff --git a/src/structs/mat.rs b/src/structs/mat.rs index 2e3539f1..b6d6f763 100644 --- a/src/structs/mat.rs +++ b/src/structs/mat.rs @@ -48,6 +48,7 @@ add_redispatch_impl!(Mat1, Mat1AddRhs) sub_redispatch_impl!(Mat1, Mat1SubRhs) cast_redispatch_impl!(Mat1, Mat1Cast) mat_impl!(Mat1, m11) +as_array_impl!(Mat1, 1) mat_cast_impl!(Mat1, Mat1Cast, m11) add_impl!(Mat1, Mat1AddRhs, m11) sub_impl!(Mat1, Mat1SubRhs, m11) @@ -152,6 +153,7 @@ sub_redispatch_impl!(Mat2, Mat2SubRhs) cast_redispatch_impl!(Mat2, Mat2Cast) mat_impl!(Mat2, m11, m12, m21, m22) +as_array_impl!(Mat2, 2) mat_cast_impl!(Mat2, Mat2Cast, m11, m12, m21, m22) add_impl!(Mat2, Mat2AddRhs, m11, m12, m21, m22) @@ -260,6 +262,7 @@ cast_redispatch_impl!(Mat3, Mat3Cast) mat_impl!(Mat3, m11, m12, m13, m21, m22, m23, m31, m32, m33) +as_array_impl!(Mat3, 3) mat_cast_impl!(Mat3, Mat3Cast, m11, m12, m13, m21, m22, m23, m31, m32, m33) @@ -387,6 +390,7 @@ mat_impl!(Mat4, m31, m32, m33, m34, m41, m42, m43, m44 ) +as_array_impl!(Mat4, 4) mat_cast_impl!(Mat4, Mat4Cast, m11, m12, m13, m14, m21, m22, m23, m24, @@ -567,6 +571,7 @@ mat_impl!(Mat5, m41, m42, m43, m44, m45, m51, m52, m53, m54, m55 ) +as_array_impl!(Mat5, 5) mat_cast_impl!(Mat5, Mat5Cast, m11, m12, m13, m14, m15, m21, m22, m23, m24, m25, @@ -764,6 +769,7 @@ mat_impl!(Mat6, m51, m52, m53, m54, m55, m56, m61, m62, m63, m64, m65, m66 ) +as_array_impl!(Mat6, 6) mat_cast_impl!(Mat6, Mat6Cast, m11, m12, m13, m14, m15, m16, m21, m22, m23, m24, m25, m26, diff --git a/src/structs/mat_macros.rs b/src/structs/mat_macros.rs index 960fdc2d..27e82c44 100644 --- a/src/structs/mat_macros.rs +++ b/src/structs/mat_macros.rs @@ -14,6 +14,49 @@ macro_rules! mat_impl( ) ) +macro_rules! as_array_impl( + ($t: ident, $dim: expr) => ( + impl $t { + /// View this matrix as a column-major array of arrays. + #[inline] + pub fn as_array(&self) -> &[[N, ..$dim], ..$dim] { + unsafe { + mem::transmute(self) + } + } + + /// View this matrix as a column-major mutable array of arrays. + #[inline] + pub fn as_array_mut<'a>(&'a mut self) -> &'a mut [[N, ..$dim], ..$dim] { + unsafe { + mem::transmute(self) + } + } + + // FIXME: because of https://github.com/rust-lang/rust/issues/16418 we cannot do the + // array-to-mat conversion by-value: + // + // pub fn from_array(&self, array: [N, ..$dim]) -> $t + + /// View a column-major array of array as a vector. + #[inline] + pub fn from_array_ref(&self, array: &[[N, ..$dim], ..$dim]) -> &$t { + unsafe { + mem::transmute(array) + } + } + + /// View a column-major array of array as a mutable vector. + #[inline] + pub fn from_array_mut(&mut self, array: &mut [[N, ..$dim], ..$dim]) -> &mut $t { + unsafe { + mem::transmute(array) + } + } + } + ) +) + macro_rules! at_fast_impl( ($t: ident, $dim: expr) => ( impl $t { @@ -272,7 +315,7 @@ macro_rules! col_slice_impl( fn col_slice(&self, cid: uint, rstart: uint, rend: uint) -> $slice { let col = self.col(cid); - $slice::from_slice(rend - rstart, col.as_slice().slice(rstart, rend)) + $slice::from_slice(rend - rstart, col.as_array().slice(rstart, rend)) } } ) @@ -313,7 +356,7 @@ macro_rules! row_slice_impl( fn row_slice(&self, rid: uint, cstart: uint, cend: uint) -> $slice { let row = self.row(rid); - $slice::from_slice(cend - cstart, row.as_slice().slice(cstart, cend)) + $slice::from_slice(cend - cstart, row.as_array().slice(cstart, cend)) } } ) diff --git a/src/structs/pnt.rs b/src/structs/pnt.rs index 451d85de..fcd9a718 100644 --- a/src/structs/pnt.rs +++ b/src/structs/pnt.rs @@ -52,7 +52,7 @@ new_impl!(Pnt1, x) orig_impl!(Pnt1, x) ord_impl!(Pnt1, x) vec_cast_impl!(Pnt1, Pnt1Cast, x) -as_slice_impl!(Pnt1, 1) +as_array_impl!(Pnt1, 1) index_impl!(Pnt1) indexable_impl!(Pnt1, 1) at_fast_impl!(Pnt1, 1) @@ -146,7 +146,7 @@ new_impl!(Pnt2, x, y) orig_impl!(Pnt2, x, y) ord_impl!(Pnt2, x, y) vec_cast_impl!(Pnt2, Pnt2Cast, x, y) -as_slice_impl!(Pnt2, 2) +as_array_impl!(Pnt2, 2) index_impl!(Pnt2) indexable_impl!(Pnt2, 2) at_fast_impl!(Pnt2, 2) @@ -242,7 +242,7 @@ new_impl!(Pnt3, x, y, z) orig_impl!(Pnt3, x, y, z) ord_impl!(Pnt3, x, y, z) vec_cast_impl!(Pnt3, Pnt3Cast, x, y, z) -as_slice_impl!(Pnt3, 3) +as_array_impl!(Pnt3, 3) index_impl!(Pnt3) indexable_impl!(Pnt3, 3) at_fast_impl!(Pnt3, 3) @@ -340,7 +340,7 @@ new_impl!(Pnt4, x, y, z, w) orig_impl!(Pnt4, x, y, z, w) ord_impl!(Pnt4, x, y, z, w) vec_cast_impl!(Pnt4, Pnt4Cast, x, y, z, w) -as_slice_impl!(Pnt4, 4) +as_array_impl!(Pnt4, 4) index_impl!(Pnt4) indexable_impl!(Pnt4, 4) at_fast_impl!(Pnt4, 4) @@ -440,7 +440,7 @@ new_impl!(Pnt5, x, y, z, w, a) orig_impl!(Pnt5, x, y, z, w, a) ord_impl!(Pnt5, x, y, z, w, a) vec_cast_impl!(Pnt5, Pnt5Cast, x, y, z, w, a) -as_slice_impl!(Pnt5, 5) +as_array_impl!(Pnt5, 5) index_impl!(Pnt5) indexable_impl!(Pnt5, 5) at_fast_impl!(Pnt5, 5) @@ -542,7 +542,7 @@ new_impl!(Pnt6, x, y, z, w, a, b) orig_impl!(Pnt6, x, y, z, w, a, b) ord_impl!(Pnt6, x, y, z, w, a, b) vec_cast_impl!(Pnt6, Pnt6Cast, x, y, z, w, a, b) -as_slice_impl!(Pnt6, 6) +as_array_impl!(Pnt6, 6) index_impl!(Pnt6) indexable_impl!(Pnt6, 6) at_fast_impl!(Pnt6, 6) diff --git a/src/structs/quat.rs b/src/structs/quat.rs index 535e294e..163485ef 100644 --- a/src/structs/quat.rs +++ b/src/structs/quat.rs @@ -460,7 +460,7 @@ cast_redispatch_impl!(Quat, QuatCast) ord_impl!(Quat, w, i, j, k) vec_axis_impl!(Quat, w, i, j, k) vec_cast_impl!(Quat, QuatCast, w, i, j, k) -as_slice_impl!(Quat, 4) +as_array_impl!(Quat, 4) index_impl!(Quat) indexable_impl!(Quat, 4) at_fast_impl!(Quat, 4) @@ -530,6 +530,3 @@ iterable_mut_impl!(Quat, 4) double_dispatch_binop_decl_trait!(UnitQuat, UnitQuatMulRhs) mul_redispatch_impl!(UnitQuat, UnitQuatMulRhs) dim_impl!(UnitQuat, 3) -as_slice_impl!(UnitQuat, 4) -index_impl!(UnitQuat) -indexable_impl!(UnitQuat, 5) diff --git a/src/structs/vec.rs b/src/structs/vec.rs index bdb5f6dc..fa9fefda 100644 --- a/src/structs/vec.rs +++ b/src/structs/vec.rs @@ -53,7 +53,7 @@ new_impl!(Vec1, x) ord_impl!(Vec1, x) vec_axis_impl!(Vec1, x) vec_cast_impl!(Vec1, Vec1Cast, x) -as_slice_impl!(Vec1, 1) +as_array_impl!(Vec1, 1) index_impl!(Vec1) indexable_impl!(Vec1, 1) at_fast_impl!(Vec1, 1) @@ -158,7 +158,7 @@ new_impl!(Vec2, x, y) ord_impl!(Vec2, x, y) vec_axis_impl!(Vec2, x, y) vec_cast_impl!(Vec2, Vec2Cast, x, y) -as_slice_impl!(Vec2, 2) +as_array_impl!(Vec2, 2) index_impl!(Vec2) indexable_impl!(Vec2, 2) at_fast_impl!(Vec2, 2) @@ -265,7 +265,7 @@ new_impl!(Vec3, x, y, z) 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) +as_array_impl!(Vec3, 3) index_impl!(Vec3) indexable_impl!(Vec3, 3) at_fast_impl!(Vec3, 3) @@ -378,7 +378,7 @@ new_impl!(Vec4, x, y, z, w) 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) +as_array_impl!(Vec4, 4) index_impl!(Vec4) indexable_impl!(Vec4, 4) at_fast_impl!(Vec4, 4) @@ -489,7 +489,7 @@ new_impl!(Vec5, x, y, z, w, a) 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) +as_array_impl!(Vec5, 5) index_impl!(Vec5) indexable_impl!(Vec5, 5) at_fast_impl!(Vec5, 5) @@ -602,7 +602,7 @@ new_impl!(Vec6, x, y, z, w, a, b) 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) +as_array_impl!(Vec6, 6) index_impl!(Vec6) indexable_impl!(Vec6, 6) at_fast_impl!(Vec6, 6) diff --git a/src/structs/vec_macros.rs b/src/structs/vec_macros.rs index b93f9896..4fb3f9ff 100644 --- a/src/structs/vec_macros.rs +++ b/src/structs/vec_macros.rs @@ -15,20 +15,43 @@ macro_rules! new_impl( ) ) -macro_rules! as_slice_impl( +macro_rules! as_array_impl( ($t: ident, $dim: expr) => ( impl $t { - /// Slices this vector. - pub fn as_slice<'a>(&'a self) -> &'a [N] { + /// View this vector as an array. + #[inline] + pub fn as_array(&self) -> &[N, ..$dim] { unsafe { - mem::transmute::<&$t, &[N, ..$dim]>(self).as_slice() + mem::transmute(self) } } - /// Mutably slices this vector. - pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [N] { + /// View this vector as a mutable array. + #[inline] + pub fn as_array_mut(&mut self) -> &mut [N, ..$dim] { unsafe { - mem::transmute::<&mut $t, &mut [N, ..$dim]>(self).as_mut_slice() + mem::transmute(self) + } + } + + // FIXME: because of https://github.com/rust-lang/rust/issues/16418 we cannot do the + // array-to-vec conversion by-value: + // + // pub fn from_array(&self, array: [N, ..$dim]) -> $t + + /// View an array as a vector. + #[inline] + pub fn from_array_ref(&self, array: &[N, ..$dim]) -> &$t { + unsafe { + mem::transmute(array) + } + } + + /// View an array as a vector. + #[inline] + pub fn from_array_mut(&mut self, array: &mut [N, ..$dim]) -> &mut $t { + unsafe { + mem::transmute(array) } } } @@ -41,14 +64,13 @@ macro_rules! at_fast_impl( /// Unsafe read access to a vector element by index. #[inline] pub unsafe fn at_fast(&self, i: uint) -> N { - (*mem::transmute::<&$t, &[N, ..$dim]>(self) - .unsafe_get(i)).clone() + (*self.as_array().unsafe_get(i)).clone() } /// Unsafe write access to a vector element by index. #[inline] pub unsafe fn set_fast(&mut self, i: uint, val: N) { - (*mem::transmute::<&mut $t, &mut [N, ..$dim]>(self).unsafe_mut(i)) = val + (*self.as_array_mut().unsafe_mut(i)) = val } } ) @@ -216,13 +238,13 @@ macro_rules! index_impl( ($t: ident) => ( impl Index for $t { fn index(&self, i: &uint) -> &N { - &self.as_slice()[*i] + &self.as_array()[*i] } } impl IndexMut for $t { fn index_mut(&mut self, i: &uint) -> &mut N { - &mut self.as_mut_slice()[*i] + &mut self.as_array_mut()[*i] } } ) @@ -757,7 +779,7 @@ macro_rules! vec_as_pnt_impl( #[deprecated = "use `&(na::orig() + *this_vector)` instead."] #[inline] - pub fn as_pnt<'a>(&'a self) -> &'a $t { + pub fn as_pnt(&self) -> &$t { unsafe { mem::transmute(self) } @@ -771,7 +793,7 @@ macro_rules! vec_as_pnt_impl( } #[inline] - fn as_pnt<'a>(&'a self) -> &'a $t { + fn as_pnt(&self) -> &$t { self.as_pnt() } }