Add range index operators

This commit is contained in:
Brendan Zabarauskas 2015-09-21 07:56:03 +10:00
parent 0ce28fbe10
commit aff340dc1e
4 changed files with 80 additions and 38 deletions

View file

@ -1142,30 +1142,42 @@ impl<S: BaseFloat> ApproxEq<S> for Matrix4<S> {
} }
macro_rules! index_operators { macro_rules! index_operators {
($MatrixN:ident <$S:ident>, $VectorN: ident, $n:expr) => { ($MatrixN:ident<$S:ident>, $n:expr, $Output:ty, $I:ty) => {
impl<$S> Index<usize> for $MatrixN<$S> { impl<$S> Index<$I> for $MatrixN<$S> {
type Output = $VectorN<$S>; type Output = $Output;
#[inline] #[inline]
fn index<'a>(&'a self, i: usize) -> &'a $VectorN<$S> { fn index<'a>(&'a self, i: $I) -> &'a $Output {
let v: &[[$S; $n]; $n] = self.as_ref(); let v: &[[$S; $n]; $n] = self.as_ref();
From::from(&v[i]) From::from(&v[i])
} }
} }
impl<$S> IndexMut<usize> for $MatrixN<$S> { impl<$S> IndexMut<$I> for $MatrixN<$S> {
#[inline] #[inline]
fn index_mut<'a>(&'a mut self, i: usize) -> &'a mut $VectorN<$S> { fn index_mut<'a>(&'a mut self, i: $I) -> &'a mut $Output {
let v: &mut [[$S; $n]; $n] = self.as_mut(); let v: &mut [[$S; $n]; $n] = self.as_mut();
From::from(&mut v[i]) From::from(&mut v[i])
} }
} }
}; }
} }
index_operators!(Matrix2<S>, Vector2, 2); index_operators!(Matrix2<S>, 2, Vector2<S>, usize);
index_operators!(Matrix3<S>, Vector3, 3); index_operators!(Matrix3<S>, 3, Vector3<S>, usize);
index_operators!(Matrix4<S>, Vector4, 4); index_operators!(Matrix4<S>, 4, Vector4<S>, usize);
// index_operators!(Matrix2<S>, 2, [Vector2<S>], Range<usize>);
// index_operators!(Matrix3<S>, 3, [Vector3<S>], Range<usize>);
// index_operators!(Matrix4<S>, 4, [Vector4<S>], Range<usize>);
// index_operators!(Matrix2<S>, 2, [Vector2<S>], RangeTo<usize>);
// index_operators!(Matrix3<S>, 3, [Vector3<S>], RangeTo<usize>);
// index_operators!(Matrix4<S>, 4, [Vector4<S>], RangeTo<usize>);
// index_operators!(Matrix2<S>, 2, [Vector2<S>], RangeFrom<usize>);
// index_operators!(Matrix3<S>, 3, [Vector3<S>], RangeFrom<usize>);
// index_operators!(Matrix4<S>, 4, [Vector4<S>], RangeFrom<usize>);
// index_operators!(Matrix2<S>, 2, [Vector2<S>], RangeFull);
// index_operators!(Matrix3<S>, 3, [Vector3<S>], RangeFull);
// index_operators!(Matrix4<S>, 4, [Vector4<S>], RangeFull);
macro_rules! fixed_array_conversions { macro_rules! fixed_array_conversions {
($MatrixN:ident <$S:ident> { $($field:ident : $index:expr),+ }, $n:expr) => { ($MatrixN:ident <$S:ident> { $($field:ident : $index:expr),+ }, $n:expr) => {

View file

@ -443,27 +443,35 @@ tuple_conversions!(Point2<S> { x, y }, (S, S));
tuple_conversions!(Point3<S> { x, y, z }, (S, S, S)); tuple_conversions!(Point3<S> { x, y, z }, (S, S, S));
macro_rules! index_operators { macro_rules! index_operators {
($PointN:ident <$S:ident>, $n:expr) => { ($PointN:ident<$S:ident>, $n:expr, $Output:ty, $I:ty) => {
impl<$S> Index<usize> for $PointN<$S> { impl<$S> Index<$I> for $PointN<$S> {
type Output = $S; type Output = $Output;
#[inline] #[inline]
fn index<'a>(&'a self, i: usize) -> &'a $S { fn index<'a>(&'a self, i: $I) -> &'a $Output {
let v: &[$S; $n] = self.as_ref(); &v[i] let v: &[$S; $n] = self.as_ref(); &v[i]
} }
} }
impl<$S> IndexMut<usize> for $PointN<$S> { impl<$S> IndexMut<$I> for $PointN<$S> {
#[inline] #[inline]
fn index_mut<'a>(&'a mut self, i: usize) -> &'a mut $S { fn index_mut<'a>(&'a mut self, i: $I) -> &'a mut $Output {
let v: &mut [$S; $n] = self.as_mut(); &mut v[i] let v: &mut [$S; $n] = self.as_mut(); &mut v[i]
} }
} }
} }
} }
index_operators!(Point2<S>, 2); index_operators!(Point2<S>, 2, S, usize);
index_operators!(Point3<S>, 3); index_operators!(Point3<S>, 3, S, usize);
index_operators!(Point2<S>, 2, [S], Range<usize>);
index_operators!(Point3<S>, 3, [S], Range<usize>);
index_operators!(Point2<S>, 2, [S], RangeTo<usize>);
index_operators!(Point3<S>, 3, [S], RangeTo<usize>);
index_operators!(Point2<S>, 2, [S], RangeFrom<usize>);
index_operators!(Point3<S>, 3, [S], RangeFrom<usize>);
index_operators!(Point2<S>, 2, [S], RangeFull);
index_operators!(Point3<S>, 3, [S], RangeFull);
impl<S: BaseNum> fmt::Debug for Point2<S> { impl<S: BaseNum> fmt::Debug for Point2<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

View file

@ -503,21 +503,31 @@ impl<'a, S: BaseFloat> From<&'a mut (S, S, S, S)> for &'a mut Quaternion<S> {
} }
} }
impl<S: BaseFloat> Index<usize> for Quaternion<S> { macro_rules! index_operators {
type Output = S; ($S:ident, $Output:ty, $I:ty) => {
impl<$S: BaseFloat> Index<$I> for Quaternion<$S> {
type Output = $Output;
#[inline] #[inline]
fn index<'a>(&'a self, i: usize) -> &'a S { fn index<'a>(&'a self, i: $I) -> &'a $Output {
let v: &[S; 4] = self.as_ref(); &v[i] let v: &[$S; 4] = self.as_ref(); &v[i]
}
}
impl<$S: BaseFloat> IndexMut<$I> for Quaternion<$S> {
#[inline]
fn index_mut<'a>(&'a mut self, i: $I) -> &'a mut $Output {
let v: &mut [$S; 4] = self.as_mut(); &mut v[i]
}
}
} }
} }
impl<S: BaseFloat> IndexMut<usize> for Quaternion<S> { index_operators!(S, S, usize);
#[inline] index_operators!(S, [S], Range<usize>);
fn index_mut<'a>(&'a mut self, i: usize) -> &'a mut S { index_operators!(S, [S], RangeTo<usize>);
let v: &mut [S; 4] = self.as_mut(); &mut v[i] index_operators!(S, [S], RangeFrom<usize>);
} index_operators!(S, [S], RangeFull);
}
impl<S: BaseFloat + Rand> Rand for Quaternion<S> { impl<S: BaseFloat + Rand> Rand for Quaternion<S> {
#[inline] #[inline]

View file

@ -449,28 +449,40 @@ tuple_conversions!(Vector3<S> { x, y, z }, (S, S, S));
tuple_conversions!(Vector4<S> { x, y, z, w }, (S, S, S, S)); tuple_conversions!(Vector4<S> { x, y, z, w }, (S, S, S, S));
macro_rules! index_operators { macro_rules! index_operators {
($Self_:ident <$S:ident>, $n:expr) => { ($VectorN:ident<$S:ident>, $n:expr, $Output:ty, $I:ty) => {
impl<$S> Index<usize> for $Self_<$S> { impl<$S> Index<$I> for $VectorN<$S> {
type Output = $S; type Output = $Output;
#[inline] #[inline]
fn index<'a>(&'a self, i: usize) -> &'a $S { fn index<'a>(&'a self, i: $I) -> &'a $Output {
let v: &[$S; $n] = self.as_ref(); &v[i] let v: &[$S; $n] = self.as_ref(); &v[i]
} }
} }
impl<$S> IndexMut<usize> for $Self_<$S> { impl<$S> IndexMut<$I> for $VectorN<$S> {
#[inline] #[inline]
fn index_mut<'a>(&'a mut self, i: usize) -> &'a mut $S { fn index_mut<'a>(&'a mut self, i: $I) -> &'a mut $Output {
let v: &mut [$S; $n] = self.as_mut(); &mut v[i] let v: &mut [$S; $n] = self.as_mut(); &mut v[i]
} }
} }
} }
} }
index_operators!(Vector2<S>, 2); index_operators!(Vector2<S>, 2, S, usize);
index_operators!(Vector3<S>, 3); index_operators!(Vector3<S>, 3, S, usize);
index_operators!(Vector4<S>, 4); index_operators!(Vector4<S>, 4, S, usize);
index_operators!(Vector2<S>, 2, [S], Range<usize>);
index_operators!(Vector3<S>, 3, [S], Range<usize>);
index_operators!(Vector4<S>, 4, [S], Range<usize>);
index_operators!(Vector2<S>, 2, [S], RangeTo<usize>);
index_operators!(Vector3<S>, 3, [S], RangeTo<usize>);
index_operators!(Vector4<S>, 4, [S], RangeTo<usize>);
index_operators!(Vector2<S>, 2, [S], RangeFrom<usize>);
index_operators!(Vector3<S>, 3, [S], RangeFrom<usize>);
index_operators!(Vector4<S>, 4, [S], RangeFrom<usize>);
index_operators!(Vector2<S>, 2, [S], RangeFull);
index_operators!(Vector3<S>, 3, [S], RangeFull);
index_operators!(Vector4<S>, 4, [S], RangeFull);
/// Operations specific to numeric two-dimensional vectors. /// Operations specific to numeric two-dimensional vectors.
impl<S: BaseNum> Vector2<S> { impl<S: BaseNum> Vector2<S> {