Add conversion from/to arrays for matrices and vectors.

Use `.as_array()`, `.as_array_mut()`, `.from_array_ref()`, `.from_array_mut()`.
Fix #33.
This commit is contained in:
Sébastien Crozet 2014-11-21 11:21:02 +01:00
parent 7d65e0a143
commit bab38ca6d5
6 changed files with 100 additions and 32 deletions

View File

@ -48,6 +48,7 @@ add_redispatch_impl!(Mat1, Mat1AddRhs)
sub_redispatch_impl!(Mat1, Mat1SubRhs) sub_redispatch_impl!(Mat1, Mat1SubRhs)
cast_redispatch_impl!(Mat1, Mat1Cast) cast_redispatch_impl!(Mat1, Mat1Cast)
mat_impl!(Mat1, m11) mat_impl!(Mat1, m11)
as_array_impl!(Mat1, 1)
mat_cast_impl!(Mat1, Mat1Cast, m11) mat_cast_impl!(Mat1, Mat1Cast, m11)
add_impl!(Mat1, Mat1AddRhs, m11) add_impl!(Mat1, Mat1AddRhs, m11)
sub_impl!(Mat1, Mat1SubRhs, m11) sub_impl!(Mat1, Mat1SubRhs, m11)
@ -152,6 +153,7 @@ sub_redispatch_impl!(Mat2, Mat2SubRhs)
cast_redispatch_impl!(Mat2, Mat2Cast) cast_redispatch_impl!(Mat2, Mat2Cast)
mat_impl!(Mat2, m11, m12, mat_impl!(Mat2, m11, m12,
m21, m22) m21, m22)
as_array_impl!(Mat2, 2)
mat_cast_impl!(Mat2, Mat2Cast, m11, m12, mat_cast_impl!(Mat2, Mat2Cast, m11, m12,
m21, m22) m21, m22)
add_impl!(Mat2, Mat2AddRhs, 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, mat_impl!(Mat3, m11, m12, m13,
m21, m22, m23, m21, m22, m23,
m31, m32, m33) m31, m32, m33)
as_array_impl!(Mat3, 3)
mat_cast_impl!(Mat3, Mat3Cast, m11, m12, m13, mat_cast_impl!(Mat3, Mat3Cast, m11, m12, m13,
m21, m22, m23, m21, m22, m23,
m31, m32, m33) m31, m32, m33)
@ -387,6 +390,7 @@ mat_impl!(Mat4,
m31, m32, m33, m34, m31, m32, m33, m34,
m41, m42, m43, m44 m41, m42, m43, m44
) )
as_array_impl!(Mat4, 4)
mat_cast_impl!(Mat4, Mat4Cast, mat_cast_impl!(Mat4, Mat4Cast,
m11, m12, m13, m14, m11, m12, m13, m14,
m21, m22, m23, m24, m21, m22, m23, m24,
@ -567,6 +571,7 @@ mat_impl!(Mat5,
m41, m42, m43, m44, m45, m41, m42, m43, m44, m45,
m51, m52, m53, m54, m55 m51, m52, m53, m54, m55
) )
as_array_impl!(Mat5, 5)
mat_cast_impl!(Mat5, Mat5Cast, mat_cast_impl!(Mat5, Mat5Cast,
m11, m12, m13, m14, m15, m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25, m21, m22, m23, m24, m25,
@ -764,6 +769,7 @@ mat_impl!(Mat6,
m51, m52, m53, m54, m55, m56, m51, m52, m53, m54, m55, m56,
m61, m62, m63, m64, m65, m66 m61, m62, m63, m64, m65, m66
) )
as_array_impl!(Mat6, 6)
mat_cast_impl!(Mat6, Mat6Cast, mat_cast_impl!(Mat6, Mat6Cast,
m11, m12, m13, m14, m15, m16, m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26, m21, m22, m23, m24, m25, m26,

View File

@ -14,6 +14,49 @@ macro_rules! mat_impl(
) )
) )
macro_rules! as_array_impl(
($t: ident, $dim: expr) => (
impl<N> $t<N> {
/// 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<N>
/// View a column-major array of array as a vector.
#[inline]
pub fn from_array_ref(&self, array: &[[N, ..$dim], ..$dim]) -> &$t<N> {
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<N> {
unsafe {
mem::transmute(array)
}
}
}
)
)
macro_rules! at_fast_impl( macro_rules! at_fast_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dim: expr) => (
impl<N: Clone> $t<N> { impl<N: Clone> $t<N> {
@ -272,7 +315,7 @@ macro_rules! col_slice_impl(
fn col_slice(&self, cid: uint, rstart: uint, rend: uint) -> $slice<N> { fn col_slice(&self, cid: uint, rstart: uint, rend: uint) -> $slice<N> {
let col = self.col(cid); 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<N> { fn row_slice(&self, rid: uint, cstart: uint, cend: uint) -> $slice<N> {
let row = self.row(rid); 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))
} }
} }
) )

View File

@ -52,7 +52,7 @@ new_impl!(Pnt1, x)
orig_impl!(Pnt1, x) orig_impl!(Pnt1, x)
ord_impl!(Pnt1, x) ord_impl!(Pnt1, x)
vec_cast_impl!(Pnt1, Pnt1Cast, x) vec_cast_impl!(Pnt1, Pnt1Cast, x)
as_slice_impl!(Pnt1, 1) as_array_impl!(Pnt1, 1)
index_impl!(Pnt1) index_impl!(Pnt1)
indexable_impl!(Pnt1, 1) indexable_impl!(Pnt1, 1)
at_fast_impl!(Pnt1, 1) at_fast_impl!(Pnt1, 1)
@ -146,7 +146,7 @@ new_impl!(Pnt2, x, y)
orig_impl!(Pnt2, x, y) orig_impl!(Pnt2, x, y)
ord_impl!(Pnt2, x, y) ord_impl!(Pnt2, x, y)
vec_cast_impl!(Pnt2, Pnt2Cast, x, y) vec_cast_impl!(Pnt2, Pnt2Cast, x, y)
as_slice_impl!(Pnt2, 2) as_array_impl!(Pnt2, 2)
index_impl!(Pnt2) index_impl!(Pnt2)
indexable_impl!(Pnt2, 2) indexable_impl!(Pnt2, 2)
at_fast_impl!(Pnt2, 2) at_fast_impl!(Pnt2, 2)
@ -242,7 +242,7 @@ new_impl!(Pnt3, x, y, z)
orig_impl!(Pnt3, x, y, z) orig_impl!(Pnt3, x, y, z)
ord_impl!(Pnt3, x, y, z) ord_impl!(Pnt3, x, y, z)
vec_cast_impl!(Pnt3, Pnt3Cast, x, y, z) vec_cast_impl!(Pnt3, Pnt3Cast, x, y, z)
as_slice_impl!(Pnt3, 3) as_array_impl!(Pnt3, 3)
index_impl!(Pnt3) index_impl!(Pnt3)
indexable_impl!(Pnt3, 3) indexable_impl!(Pnt3, 3)
at_fast_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) orig_impl!(Pnt4, x, y, z, w)
ord_impl!(Pnt4, x, y, z, w) ord_impl!(Pnt4, x, y, z, w)
vec_cast_impl!(Pnt4, Pnt4Cast, 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) index_impl!(Pnt4)
indexable_impl!(Pnt4, 4) indexable_impl!(Pnt4, 4)
at_fast_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) orig_impl!(Pnt5, x, y, z, w, a)
ord_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) vec_cast_impl!(Pnt5, Pnt5Cast, x, y, z, w, a)
as_slice_impl!(Pnt5, 5) as_array_impl!(Pnt5, 5)
index_impl!(Pnt5) index_impl!(Pnt5)
indexable_impl!(Pnt5, 5) indexable_impl!(Pnt5, 5)
at_fast_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) orig_impl!(Pnt6, x, y, z, w, a, b)
ord_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) vec_cast_impl!(Pnt6, Pnt6Cast, x, y, z, w, a, b)
as_slice_impl!(Pnt6, 6) as_array_impl!(Pnt6, 6)
index_impl!(Pnt6) index_impl!(Pnt6)
indexable_impl!(Pnt6, 6) indexable_impl!(Pnt6, 6)
at_fast_impl!(Pnt6, 6) at_fast_impl!(Pnt6, 6)

View File

@ -460,7 +460,7 @@ cast_redispatch_impl!(Quat, QuatCast)
ord_impl!(Quat, w, i, j, k) ord_impl!(Quat, w, i, j, k)
vec_axis_impl!(Quat, w, i, j, k) vec_axis_impl!(Quat, w, i, j, k)
vec_cast_impl!(Quat, QuatCast, 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) index_impl!(Quat)
indexable_impl!(Quat, 4) indexable_impl!(Quat, 4)
at_fast_impl!(Quat, 4) at_fast_impl!(Quat, 4)
@ -530,6 +530,3 @@ iterable_mut_impl!(Quat, 4)
double_dispatch_binop_decl_trait!(UnitQuat, UnitQuatMulRhs) double_dispatch_binop_decl_trait!(UnitQuat, UnitQuatMulRhs)
mul_redispatch_impl!(UnitQuat, UnitQuatMulRhs) mul_redispatch_impl!(UnitQuat, UnitQuatMulRhs)
dim_impl!(UnitQuat, 3) dim_impl!(UnitQuat, 3)
as_slice_impl!(UnitQuat, 4)
index_impl!(UnitQuat)
indexable_impl!(UnitQuat, 5)

View File

@ -53,7 +53,7 @@ new_impl!(Vec1, x)
ord_impl!(Vec1, x) ord_impl!(Vec1, x)
vec_axis_impl!(Vec1, x) vec_axis_impl!(Vec1, x)
vec_cast_impl!(Vec1, Vec1Cast, x) vec_cast_impl!(Vec1, Vec1Cast, x)
as_slice_impl!(Vec1, 1) as_array_impl!(Vec1, 1)
index_impl!(Vec1) index_impl!(Vec1)
indexable_impl!(Vec1, 1) indexable_impl!(Vec1, 1)
at_fast_impl!(Vec1, 1) at_fast_impl!(Vec1, 1)
@ -158,7 +158,7 @@ new_impl!(Vec2, x, y)
ord_impl!(Vec2, x, y) ord_impl!(Vec2, x, y)
vec_axis_impl!(Vec2, x, y) vec_axis_impl!(Vec2, x, y)
vec_cast_impl!(Vec2, Vec2Cast, x, y) vec_cast_impl!(Vec2, Vec2Cast, x, y)
as_slice_impl!(Vec2, 2) as_array_impl!(Vec2, 2)
index_impl!(Vec2) index_impl!(Vec2)
indexable_impl!(Vec2, 2) indexable_impl!(Vec2, 2)
at_fast_impl!(Vec2, 2) at_fast_impl!(Vec2, 2)
@ -265,7 +265,7 @@ new_impl!(Vec3, x, y, z)
ord_impl!(Vec3, x, y, z) ord_impl!(Vec3, x, y, z)
vec_axis_impl!(Vec3, x, y, z) vec_axis_impl!(Vec3, x, y, z)
vec_cast_impl!(Vec3, Vec3Cast, x, y, z) vec_cast_impl!(Vec3, Vec3Cast, x, y, z)
as_slice_impl!(Vec3, 3) as_array_impl!(Vec3, 3)
index_impl!(Vec3) index_impl!(Vec3)
indexable_impl!(Vec3, 3) indexable_impl!(Vec3, 3)
at_fast_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) ord_impl!(Vec4, x, y, z, w)
vec_axis_impl!(Vec4, x, y, z, w) vec_axis_impl!(Vec4, x, y, z, w)
vec_cast_impl!(Vec4, Vec4Cast, 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) index_impl!(Vec4)
indexable_impl!(Vec4, 4) indexable_impl!(Vec4, 4)
at_fast_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) ord_impl!(Vec5, x, y, z, w, a)
vec_axis_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) vec_cast_impl!(Vec5, Vec5Cast, x, y, z, w, a)
as_slice_impl!(Vec5, 5) as_array_impl!(Vec5, 5)
index_impl!(Vec5) index_impl!(Vec5)
indexable_impl!(Vec5, 5) indexable_impl!(Vec5, 5)
at_fast_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) ord_impl!(Vec6, x, y, z, w, a, b)
vec_axis_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) vec_cast_impl!(Vec6, Vec6Cast, x, y, z, w, a, b)
as_slice_impl!(Vec6, 6) as_array_impl!(Vec6, 6)
index_impl!(Vec6) index_impl!(Vec6)
indexable_impl!(Vec6, 6) indexable_impl!(Vec6, 6)
at_fast_impl!(Vec6, 6) at_fast_impl!(Vec6, 6)

View File

@ -15,20 +15,43 @@ macro_rules! new_impl(
) )
) )
macro_rules! as_slice_impl( macro_rules! as_array_impl(
($t: ident, $dim: expr) => ( ($t: ident, $dim: expr) => (
impl<N> $t<N> { impl<N> $t<N> {
/// Slices this vector. /// View this vector as an array.
pub fn as_slice<'a>(&'a self) -> &'a [N] { #[inline]
pub fn as_array(&self) -> &[N, ..$dim] {
unsafe { unsafe {
mem::transmute::<&$t<N>, &[N, ..$dim]>(self).as_slice() mem::transmute(self)
} }
} }
/// Mutably slices this vector. /// View this vector as a mutable array.
pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [N] { #[inline]
pub fn as_array_mut(&mut self) -> &mut [N, ..$dim] {
unsafe { unsafe {
mem::transmute::<&mut $t<N>, &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<N>
/// View an array as a vector.
#[inline]
pub fn from_array_ref(&self, array: &[N, ..$dim]) -> &$t<N> {
unsafe {
mem::transmute(array)
}
}
/// View an array as a vector.
#[inline]
pub fn from_array_mut(&mut self, array: &mut [N, ..$dim]) -> &mut $t<N> {
unsafe {
mem::transmute(array)
} }
} }
} }
@ -41,14 +64,13 @@ macro_rules! at_fast_impl(
/// Unsafe read access to a vector element by index. /// Unsafe read access to a vector element by index.
#[inline] #[inline]
pub unsafe fn at_fast(&self, i: uint) -> N { pub unsafe fn at_fast(&self, i: uint) -> N {
(*mem::transmute::<&$t<N>, &[N, ..$dim]>(self) (*self.as_array().unsafe_get(i)).clone()
.unsafe_get(i)).clone()
} }
/// Unsafe write access to a vector element by index. /// Unsafe write access to a vector element by index.
#[inline] #[inline]
pub unsafe fn set_fast(&mut self, i: uint, val: N) { pub unsafe fn set_fast(&mut self, i: uint, val: N) {
(*mem::transmute::<&mut $t<N>, &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) => ( ($t: ident) => (
impl<N> Index<uint, N> for $t<N> { impl<N> Index<uint, N> for $t<N> {
fn index(&self, i: &uint) -> &N { fn index(&self, i: &uint) -> &N {
&self.as_slice()[*i] &self.as_array()[*i]
} }
} }
impl<N> IndexMut<uint, N> for $t<N> { impl<N> IndexMut<uint, N> for $t<N> {
fn index_mut(&mut self, i: &uint) -> &mut N { 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."] #[deprecated = "use `&(na::orig() + *this_vector)` instead."]
#[inline] #[inline]
pub fn as_pnt<'a>(&'a self) -> &'a $t<N> { pub fn as_pnt(&self) -> &$t<N> {
unsafe { unsafe {
mem::transmute(self) mem::transmute(self)
} }
@ -771,7 +793,7 @@ macro_rules! vec_as_pnt_impl(
} }
#[inline] #[inline]
fn as_pnt<'a>(&'a self) -> &'a $t<N> { fn as_pnt(&self) -> &$t<N> {
self.as_pnt() self.as_pnt()
} }
} }