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 {
($MatrixN:ident <$S:ident>, $VectorN: ident, $n:expr) => {
impl<$S> Index<usize> for $MatrixN<$S> {
type Output = $VectorN<$S>;
($MatrixN:ident<$S:ident>, $n:expr, $Output:ty, $I:ty) => {
impl<$S> Index<$I> for $MatrixN<$S> {
type Output = $Output;
#[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();
From::from(&v[i])
}
}
impl<$S> IndexMut<usize> for $MatrixN<$S> {
impl<$S> IndexMut<$I> for $MatrixN<$S> {
#[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();
From::from(&mut v[i])
}
}
};
}
}
index_operators!(Matrix2<S>, Vector2, 2);
index_operators!(Matrix3<S>, Vector3, 3);
index_operators!(Matrix4<S>, Vector4, 4);
index_operators!(Matrix2<S>, 2, Vector2<S>, usize);
index_operators!(Matrix3<S>, 3, Vector3<S>, usize);
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 {
($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));
macro_rules! index_operators {
($PointN:ident <$S:ident>, $n:expr) => {
impl<$S> Index<usize> for $PointN<$S> {
type Output = $S;
($PointN:ident<$S:ident>, $n:expr, $Output:ty, $I:ty) => {
impl<$S> Index<$I> for $PointN<$S> {
type Output = $Output;
#[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]
}
}
impl<$S> IndexMut<usize> for $PointN<$S> {
impl<$S> IndexMut<$I> for $PointN<$S> {
#[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]
}
}
}
}
index_operators!(Point2<S>, 2);
index_operators!(Point3<S>, 3);
index_operators!(Point2<S>, 2, S, usize);
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> {
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> {
type Output = S;
macro_rules! index_operators {
($S:ident, $Output:ty, $I:ty) => {
impl<$S: BaseFloat> Index<$I> for Quaternion<$S> {
type Output = $Output;
#[inline]
fn index<'a>(&'a self, i: usize) -> &'a S {
let v: &[S; 4] = self.as_ref(); &v[i]
#[inline]
fn index<'a>(&'a self, i: $I) -> &'a $Output {
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> {
#[inline]
fn index_mut<'a>(&'a mut self, i: usize) -> &'a mut S {
let v: &mut [S; 4] = self.as_mut(); &mut v[i]
}
}
index_operators!(S, S, usize);
index_operators!(S, [S], Range<usize>);
index_operators!(S, [S], RangeTo<usize>);
index_operators!(S, [S], RangeFrom<usize>);
index_operators!(S, [S], RangeFull);
impl<S: BaseFloat + Rand> Rand for Quaternion<S> {
#[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));
macro_rules! index_operators {
($Self_:ident <$S:ident>, $n:expr) => {
impl<$S> Index<usize> for $Self_<$S> {
type Output = $S;
($VectorN:ident<$S:ident>, $n:expr, $Output:ty, $I:ty) => {
impl<$S> Index<$I> for $VectorN<$S> {
type Output = $Output;
#[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]
}
}
impl<$S> IndexMut<usize> for $Self_<$S> {
impl<$S> IndexMut<$I> for $VectorN<$S> {
#[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]
}
}
}
}
index_operators!(Vector2<S>, 2);
index_operators!(Vector3<S>, 3);
index_operators!(Vector4<S>, 4);
index_operators!(Vector2<S>, 2, S, usize);
index_operators!(Vector3<S>, 3, S, usize);
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.
impl<S: BaseNum> Vector2<S> {