Implement most assignment operators

This commit is contained in:
Brendan Zabarauskas 2015-12-21 07:24:56 +11:00
parent 1b4420d2af
commit 59d5e6f53a
9 changed files with 105 additions and 3 deletions

View file

@ -3,7 +3,7 @@ sudo: false
language: rust
rust:
# - nightly
- nightly
- beta
- stable

View file

@ -26,6 +26,9 @@ keywords = ["gamedev", "math", "matrix", "vector", "quaternion"]
[lib]
name = "cgmath"
[features]
unstable = []
[dependencies.rustc-serialize]
rustc_serialize = "0.3"

View file

@ -179,6 +179,15 @@ macro_rules! impl_angle {
impl_operator!(<S: BaseFloat> Rem<$Angle<S> > for $Angle<S> {
fn rem(lhs, rhs) -> $Angle<S> { $Angle::new(lhs.s % rhs.s) }
});
impl_assignment_operator!(<S: BaseFloat> AddAssign<$Angle<S> > for $Angle<S> {
fn add_assign(&mut self, other) { self.s + other.s; }
});
impl_assignment_operator!(<S: BaseFloat> SubAssign<$Angle<S> > for $Angle<S> {
fn sub_assign(&mut self, other) { self.s - other.s; }
});
impl_assignment_operator!(<S: BaseFloat> RemAssign<$Angle<S> > for $Angle<S> {
fn rem_assign(&mut self, other) { self.s % other.s; }
});
impl_operator!(<S: BaseFloat> Mul<S> for $Angle<S> {
fn mul(lhs, scalar) -> $Angle<S> { $Angle::new(lhs.s * scalar) }
@ -186,6 +195,12 @@ macro_rules! impl_angle {
impl_operator!(<S: BaseFloat> Div<S> for $Angle<S> {
fn div(lhs, scalar) -> $Angle<S> { $Angle::new(lhs.s / scalar) }
});
impl_assignment_operator!(<S: BaseFloat> MulAssign<S> for $Angle<S> {
fn mul_assign(&mut self, scalar) { self.s * scalar; }
});
impl_assignment_operator!(<S: BaseFloat> DivAssign<S> for $Angle<S> {
fn div_assign(&mut self, scalar) { self.s / scalar; }
});
impl<S: BaseFloat> ApproxEq for $Angle<S> {
type Epsilon = S;

View file

@ -27,6 +27,8 @@
//! `look_at`, `from_angle`, `from_euler`, and `from_axis_angle` methods.
//! These are provided for convenience.
#![cfg_attr(feature = "unstable", feature(augmented_assignments, op_assign_traits))]
extern crate num as rust_num;
extern crate rustc_serialize;
extern crate rand;

View file

@ -97,6 +97,18 @@ macro_rules! impl_operator {
};
}
macro_rules! impl_assignment_operator {
(<$S:ident: $Constraint:ident> $Op:ident<$Rhs:ty> for $Lhs:ty {
fn $op:ident(&mut $lhs:ident, $rhs:ident) $body:block
}) => {
#[cfg(feature = "unstable")]
impl<$S: $Constraint + $Op<$S>> $Op<$Rhs> for $Lhs {
#[inline]
fn $op(&mut $lhs, $rhs: $Rhs) $body
}
};
}
macro_rules! fold_array {
(&$method:ident, { $x:expr, $y:expr }) => { $x.$method(&$y) };
(&$method:ident, { $x:expr, $y:expr, $z:expr }) => { $x.$method(&$y).$method(&$z) };

View file

@ -266,6 +266,7 @@ pub trait Matrix where
Self: Add<Self, Output = Self>,
Self: Sub<Self, Output = Self>,
Self: Neg<Output = Self>,
Self: Mul<<Self as Matrix>::Element, Output = Self>,
Self: Div<<Self as Matrix>::Element, Output = Self>,
@ -830,6 +831,15 @@ macro_rules! impl_operators {
impl_operator!(<S: BaseFloat> Rem<S> for $MatrixN<S> {
fn rem(matrix, scalar) -> $MatrixN<S> { $MatrixN { $($field: matrix.$field % scalar),+ } }
});
impl_assignment_operator!(<S: BaseFloat> MulAssign<S> for $MatrixN<S> {
fn mul_assign(&mut self, scalar) { $(self.$field *= scalar);+ }
});
impl_assignment_operator!(<S: BaseFloat> DivAssign<S> for $MatrixN<S> {
fn div_assign(&mut self, scalar) { $(self.$field /= scalar);+ }
});
impl_assignment_operator!(<S: BaseFloat> RemAssign<S> for $MatrixN<S> {
fn rem_assign(&mut self, scalar) { $(self.$field %= scalar);+ }
});
impl_operator!(<S: BaseFloat> Add<$MatrixN<S> > for $MatrixN<S> {
fn add(lhs, rhs) -> $MatrixN<S> { $MatrixN { $($field: lhs.$field + rhs.$field),+ } }
@ -837,6 +847,14 @@ macro_rules! impl_operators {
impl_operator!(<S: BaseFloat> Sub<$MatrixN<S> > for $MatrixN<S> {
fn sub(lhs, rhs) -> $MatrixN<S> { $MatrixN { $($field: lhs.$field - rhs.$field),+ } }
});
#[cfg(feature = "unstable")]
impl<S: BaseFloat + AddAssign<S>> AddAssign<$MatrixN<S>> for $MatrixN<S> {
fn add_assign(&mut self, other: $MatrixN<S>) { $(self.$field += other.$field);+ }
}
#[cfg(feature = "unstable")]
impl<S: BaseFloat + SubAssign<S>> SubAssign<$MatrixN<S>> for $MatrixN<S> {
fn sub_assign(&mut self, other: $MatrixN<S>) { $(self.$field -= other.$field);+ }
}
impl_operator!(<S: BaseFloat> Mul<$VectorN<S> > for $MatrixN<S> {
fn mul(matrix, vector) -> $VectorN<S> { $VectorN::new($(matrix.row($row_index).dot(vector.clone())),+) }

View file

@ -145,6 +145,9 @@ macro_rules! impl_point {
impl_operator!(<S: BaseNum> Add<$VectorN<S> > for $PointN<S> {
fn add(lhs, rhs) -> $PointN<S> { $PointN::new($(lhs.$field + rhs.$field),+) }
});
impl_assignment_operator!(<S: BaseNum> AddAssign<$VectorN<S> > for $PointN<S> {
fn add_assign(&mut self, vector) { $(self.$field += vector.$field);+ }
});
impl_operator!(<S: BaseNum> Sub<$PointN<S> > for $PointN<S> {
fn sub(lhs, rhs) -> $VectorN<S> { $VectorN::new($(lhs.$field - rhs.$field),+) }
@ -153,14 +156,21 @@ macro_rules! impl_point {
impl_operator!(<S: BaseNum> Mul<S> for $PointN<S> {
fn mul(point, scalar) -> $PointN<S> { $PointN::new($(point.$field * scalar),+) }
});
impl_operator!(<S: BaseNum> Div<S> for $PointN<S> {
fn div(point, scalar) -> $PointN<S> { $PointN::new($(point.$field / scalar),+) }
});
impl_operator!(<S: BaseNum> Rem<S> for $PointN<S> {
fn rem(point, scalar) -> $PointN<S> { $PointN::new($(point.$field % scalar),+) }
});
impl_assignment_operator!(<S: BaseNum> MulAssign<S> for $PointN<S> {
fn mul_assign(&mut self, scalar) { $(self.$field *= scalar);+ }
});
impl_assignment_operator!(<S: BaseNum> DivAssign<S> for $PointN<S> {
fn div_assign(&mut self, scalar) { $(self.$field /= scalar);+ }
});
impl_assignment_operator!(<S: BaseNum> RemAssign<S> for $PointN<S> {
fn rem_assign(&mut self, scalar) { $(self.$field %= scalar);+ }
});
impl_index_operators!($PointN<S>, $n, S, usize);
impl_index_operators!($PointN<S>, $n, [S], Range<usize>);

View file

@ -119,12 +119,18 @@ impl_operator!(<S: BaseFloat> Mul<S> for Quaternion<S> {
Quaternion::from_sv(lhs.s * rhs, lhs.v * rhs)
}
});
impl_assignment_operator!(<S: BaseFloat> MulAssign<S> for Quaternion<S> {
fn mul_assign(&mut self, scalar) { self.s *= scalar; self.v *= scalar; }
});
impl_operator!(<S: BaseFloat> Div<S> for Quaternion<S> {
fn div(lhs, rhs) -> Quaternion<S> {
Quaternion::from_sv(lhs.s / rhs, lhs.v / rhs)
}
});
impl_assignment_operator!(<S: BaseFloat> DivAssign<S> for Quaternion<S> {
fn div_assign(&mut self, scalar) { self.s /= scalar; self.v /= scalar; }
});
impl_operator!(<S: BaseFloat> Mul<Vector3<S> > for Quaternion<S> {
fn mul(lhs, rhs) -> Vector3<S> {{
@ -140,12 +146,18 @@ impl_operator!(<S: BaseFloat> Add<Quaternion<S> > for Quaternion<S> {
Quaternion::from_sv(lhs.s + rhs.s, lhs.v + rhs.v)
}
});
impl_assignment_operator!(<S: BaseFloat> AddAssign<Quaternion<S> > for Quaternion<S> {
fn add_assign(&mut self, other) { self.s += other.s; self.v += other.v; }
});
impl_operator!(<S: BaseFloat> Sub<Quaternion<S> > for Quaternion<S> {
fn sub(lhs, rhs) -> Quaternion<S> {
Quaternion::from_sv(lhs.s - rhs.s, lhs.v - rhs.v)
}
});
impl_assignment_operator!(<S: BaseFloat> SubAssign<Quaternion<S> > for Quaternion<S> {
fn sub_assign(&mut self, other) { self.s -= other.s; self.v -= other.v; }
});
impl_operator!(<S: BaseFloat> Mul<Quaternion<S> > for Quaternion<S> {
fn mul(lhs, rhs) -> Quaternion<S> {

View file

@ -218,6 +218,12 @@ macro_rules! impl_vector {
impl_operator!(<S: BaseNum> Add<$VectorN<S> > for $VectorN<S> {
fn add(lhs, rhs) -> $VectorN<S> { $VectorN::new($(lhs.$field + rhs.$field),+) }
});
impl_assignment_operator!(<S: BaseNum> AddAssign<S> for $VectorN<S> {
fn add_assign(&mut self, scalar) { $(self.$field += scalar);+ }
});
impl_assignment_operator!(<S: BaseNum> AddAssign<$VectorN<S> > for $VectorN<S> {
fn add_assign(&mut self, other) { $(self.$field += other.$field);+ }
});
impl_operator!(<S: BaseNum> Sub<S> for $VectorN<S> {
fn sub(vector, scalar) -> $VectorN<S> { $VectorN::new($(vector.$field - scalar),+) }
@ -225,6 +231,12 @@ macro_rules! impl_vector {
impl_operator!(<S: BaseNum> Sub<$VectorN<S> > for $VectorN<S> {
fn sub(lhs, rhs) -> $VectorN<S> { $VectorN::new($(lhs.$field - rhs.$field),+) }
});
impl_assignment_operator!(<S: BaseNum> SubAssign<S> for $VectorN<S> {
fn sub_assign(&mut self, scalar) { $(self.$field -= scalar);+ }
});
impl_assignment_operator!(<S: BaseNum> SubAssign<$VectorN<S> > for $VectorN<S> {
fn sub_assign(&mut self, other) { $(self.$field -= other.$field);+ }
});
impl_operator!(<S: BaseNum> Mul<S> for $VectorN<S> {
fn mul(vector, scalar) -> $VectorN<S> { $VectorN::new($(vector.$field * scalar),+) }
@ -232,6 +244,12 @@ macro_rules! impl_vector {
impl_operator!(<S: BaseNum> Mul<$VectorN<S> > for $VectorN<S> {
fn mul(lhs, rhs) -> $VectorN<S> { $VectorN::new($(lhs.$field * rhs.$field),+) }
});
impl_assignment_operator!(<S: BaseNum> MulAssign<S> for $VectorN<S> {
fn mul_assign(&mut self, scalar) { $(self.$field *= scalar);+ }
});
impl_assignment_operator!(<S: BaseNum> MulAssign<$VectorN<S> > for $VectorN<S> {
fn mul_assign(&mut self, other) { $(self.$field *= other.$field);+ }
});
impl_operator!(<S: BaseNum> Div<S> for $VectorN<S> {
fn div(vector, scalar) -> $VectorN<S> { $VectorN::new($(vector.$field / scalar),+) }
@ -239,6 +257,12 @@ macro_rules! impl_vector {
impl_operator!(<S: BaseNum> Div<$VectorN<S> > for $VectorN<S> {
fn div(lhs, rhs) -> $VectorN<S> { $VectorN::new($(lhs.$field / rhs.$field),+) }
});
impl_assignment_operator!(<S: BaseNum> DivAssign<S> for $VectorN<S> {
fn div_assign(&mut self, scalar) { $(self.$field /= scalar);+ }
});
impl_assignment_operator!(<S: BaseNum> DivAssign<$VectorN<S> > for $VectorN<S> {
fn div_assign(&mut self, other) { $(self.$field /= other.$field);+ }
});
impl_operator!(<S: BaseNum> Rem<S> for $VectorN<S> {
fn rem(vector, scalar) -> $VectorN<S> { $VectorN::new($(vector.$field % scalar),+) }
@ -246,6 +270,12 @@ macro_rules! impl_vector {
impl_operator!(<S: BaseNum> Rem<$VectorN<S> > for $VectorN<S> {
fn rem(lhs, rhs) -> $VectorN<S> { $VectorN::new($(lhs.$field % rhs.$field),+) }
});
impl_assignment_operator!(<S: BaseNum> RemAssign<S> for $VectorN<S> {
fn rem_assign(&mut self, scalar) { $(self.$field %= scalar);+ }
});
impl_assignment_operator!(<S: BaseNum> RemAssign<$VectorN<S> > for $VectorN<S> {
fn rem_assign(&mut self, other) { $(self.$field %= other.$field);+ }
});
impl_index_operators!($VectorN<S>, $n, S, usize);
impl_index_operators!($VectorN<S>, $n, [S], Range<usize>);