Merge pull request #282 from bjz/assignment-ops
Implement most assignment operators
This commit is contained in:
commit
f60e85b61a
15 changed files with 173 additions and 87 deletions
|
@ -3,7 +3,7 @@ sudo: false
|
||||||
language: rust
|
language: rust
|
||||||
|
|
||||||
rust:
|
rust:
|
||||||
# - nightly
|
- nightly
|
||||||
- beta
|
- beta
|
||||||
- stable
|
- stable
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
parameters.
|
parameters.
|
||||||
- Weaken type constraints on `perspective` function to take an `Into<Rad<S>>`.
|
- Weaken type constraints on `perspective` function to take an `Into<Rad<S>>`.
|
||||||
- Add `Angle::new` for constructing angles from a unitless scalar.
|
- Add `Angle::new` for constructing angles from a unitless scalar.
|
||||||
|
- Implement assignment operators for nightly builds, enabled by the `"unstable"`
|
||||||
|
feature.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- `Vector`, `Matrix`, `Point`, and `Angle` are now constrained to require
|
- `Vector`, `Matrix`, `Point`, and `Angle` are now constrained to require
|
||||||
|
@ -44,9 +46,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
`Vector::from_value(1.0)`.
|
`Vector::from_value(1.0)`.
|
||||||
- Remove operator methods from `Vector`, `Matrix`, `Point`, and `Angle` traits
|
- Remove operator methods from `Vector`, `Matrix`, `Point`, and `Angle` traits
|
||||||
in favor of operator overloading.
|
in favor of operator overloading.
|
||||||
- Remove `*_self` methods from `Vector`, `Matrix`, `Point`, and `Angle`. These
|
- Remove `*_self` methods from `Vector`, `Matrix`, `Point`, and `Angle`. The
|
||||||
were of little performance benefit, and assignment operator overloading will
|
operator methods can be used via the unstable assignment operators.
|
||||||
be coming soon!
|
|
||||||
- Remove `#[derive(Hash)]` from `Deg` and `Rad`. This could never really be used
|
- Remove `#[derive(Hash)]` from `Deg` and `Rad`. This could never really be used
|
||||||
these types, because they expect to be given a `BaseFloat` under normal
|
these types, because they expect to be given a `BaseFloat` under normal
|
||||||
circumstances.
|
circumstances.
|
||||||
|
|
|
@ -26,6 +26,9 @@ keywords = ["gamedev", "math", "matrix", "vector", "quaternion"]
|
||||||
[lib]
|
[lib]
|
||||||
name = "cgmath"
|
name = "cgmath"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
unstable = []
|
||||||
|
|
||||||
[dependencies.rustc-serialize]
|
[dependencies.rustc-serialize]
|
||||||
rustc_serialize = "0.3"
|
rustc_serialize = "0.3"
|
||||||
|
|
||||||
|
|
|
@ -13,30 +13,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
macro_rules! bench_binop(
|
macro_rules! bench_binop {
|
||||||
($name: ident, $t1: ty, $t2: ty, $binop: ident) => {
|
|
||||||
#[bench]
|
|
||||||
fn $name(bh: &mut Bencher) {
|
|
||||||
const LEN: usize = 1 << 13;
|
|
||||||
|
|
||||||
let mut rng = IsaacRng::new_unseeded();
|
|
||||||
|
|
||||||
let elems1: Vec<$t1> = (0..LEN).map(|_| rng.gen::<$t1>()).collect();
|
|
||||||
let elems2: Vec<$t2> = (0..LEN).map(|_| rng.gen::<$t2>()).collect();
|
|
||||||
let mut i = 0;
|
|
||||||
|
|
||||||
bh.iter(|| {
|
|
||||||
i = (i + 1) & (LEN - 1);
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
test::black_box(elems1.get_unchecked(i).$binop(elems2.get_unchecked(i)))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
macro_rules! bench_binop_deref(
|
|
||||||
($name: ident, $t1: ty, $t2: ty, $binop: ident) => {
|
($name: ident, $t1: ty, $t2: ty, $binop: ident) => {
|
||||||
#[bench]
|
#[bench]
|
||||||
fn $name(bh: &mut Bencher) {
|
fn $name(bh: &mut Bencher) {
|
||||||
|
@ -56,10 +33,10 @@ macro_rules! bench_binop_deref(
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
);
|
}
|
||||||
|
|
||||||
macro_rules! bench_unop(
|
macro_rules! bench_unop {
|
||||||
($name: ident, $t: ty, $unop: ident) => {
|
($name: ident, $t: ty, $unop: ident) => {
|
||||||
#[bench]
|
#[bench]
|
||||||
fn $name(bh: &mut Bencher) {
|
fn $name(bh: &mut Bencher) {
|
||||||
|
@ -78,10 +55,10 @@ macro_rules! bench_unop(
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
);
|
}
|
||||||
|
|
||||||
macro_rules! bench_construction(
|
macro_rules! bench_construction {
|
||||||
($name: ident, $t: ty, $constructor: path [ $($args: ident: $types: ty),+ ]) => {
|
($name: ident, $t: ty, $constructor: path [ $($args: ident: $types: ty),+ ]) => {
|
||||||
#[bench]
|
#[bench]
|
||||||
fn $name(bh: &mut Bencher) {
|
fn $name(bh: &mut Bencher) {
|
||||||
|
@ -101,5 +78,5 @@ macro_rules! bench_construction(
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
);
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ fn bench_from_axis_angle<T: Rotation3<f32>>(bh: &mut Bencher) {
|
||||||
i = (i + 1) & (LEN - 1);
|
i = (i + 1) & (LEN - 1);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let res: T = Rotation3::from_axis_angle(axis.get_unchecked(i), *angle.get_unchecked(i));
|
let res: T = Rotation3::from_axis_angle(*axis.get_unchecked(i), *angle.get_unchecked(i));
|
||||||
test::black_box(res)
|
test::black_box(res)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -20,35 +20,37 @@ extern crate test;
|
||||||
extern crate cgmath;
|
extern crate cgmath;
|
||||||
|
|
||||||
use rand::{IsaacRng, Rng};
|
use rand::{IsaacRng, Rng};
|
||||||
|
use std::ops::*;
|
||||||
use test::Bencher;
|
use test::Bencher;
|
||||||
|
|
||||||
use cgmath::*;
|
use cgmath::*;
|
||||||
|
|
||||||
#[path="common/macros.rs"]
|
#[path="common/macros.rs"]
|
||||||
#[macro_use] mod macros;
|
#[macro_use] mod macros;
|
||||||
|
|
||||||
bench_binop!(_bench_matrix2_mul_m, Matrix2<f32>, Matrix2<f32>, mul_m);
|
bench_binop!(_bench_matrix2_mul_m, Matrix2<f32>, Matrix2<f32>, mul);
|
||||||
bench_binop!(_bench_matrix3_mul_m, Matrix3<f32>, Matrix3<f32>, mul_m);
|
bench_binop!(_bench_matrix3_mul_m, Matrix3<f32>, Matrix3<f32>, mul);
|
||||||
bench_binop!(_bench_matrix4_mul_m, Matrix4<f32>, Matrix4<f32>, mul_m);
|
bench_binop!(_bench_matrix4_mul_m, Matrix4<f32>, Matrix4<f32>, mul);
|
||||||
|
|
||||||
bench_binop!(_bench_matrix2_add_m, Matrix2<f32>, Matrix2<f32>, add_m);
|
bench_binop!(_bench_matrix2_add_m, Matrix2<f32>, Matrix2<f32>, add);
|
||||||
bench_binop!(_bench_matrix3_add_m, Matrix3<f32>, Matrix3<f32>, add_m);
|
bench_binop!(_bench_matrix3_add_m, Matrix3<f32>, Matrix3<f32>, add);
|
||||||
bench_binop!(_bench_matrix4_add_m, Matrix4<f32>, Matrix4<f32>, add_m);
|
bench_binop!(_bench_matrix4_add_m, Matrix4<f32>, Matrix4<f32>, add);
|
||||||
|
|
||||||
bench_binop!(_bench_matrix2_sub_m, Matrix2<f32>, Matrix2<f32>, sub_m);
|
bench_binop!(_bench_matrix2_sub_m, Matrix2<f32>, Matrix2<f32>, sub);
|
||||||
bench_binop!(_bench_matrix3_sub_m, Matrix3<f32>, Matrix3<f32>, sub_m);
|
bench_binop!(_bench_matrix3_sub_m, Matrix3<f32>, Matrix3<f32>, sub);
|
||||||
bench_binop!(_bench_matrix4_sub_m, Matrix4<f32>, Matrix4<f32>, sub_m);
|
bench_binop!(_bench_matrix4_sub_m, Matrix4<f32>, Matrix4<f32>, sub);
|
||||||
|
|
||||||
bench_binop!(_bench_matrix2_mul_v, Matrix2<f32>, Vector2<f32>, mul_v);
|
bench_binop!(_bench_matrix2_mul_v, Matrix2<f32>, Vector2<f32>, mul);
|
||||||
bench_binop!(_bench_matrix3_mul_v, Matrix3<f32>, Vector3<f32>, mul_v);
|
bench_binop!(_bench_matrix3_mul_v, Matrix3<f32>, Vector3<f32>, mul);
|
||||||
bench_binop!(_bench_matrix4_mul_v, Matrix4<f32>, Vector4<f32>, mul_v);
|
bench_binop!(_bench_matrix4_mul_v, Matrix4<f32>, Vector4<f32>, mul);
|
||||||
|
|
||||||
bench_binop_deref!(_bench_matrix2_mul_s, Matrix2<f32>, f32, mul_s);
|
bench_binop!(_bench_matrix2_mul_s, Matrix2<f32>, f32, mul);
|
||||||
bench_binop_deref!(_bench_matrix3_mul_s, Matrix3<f32>, f32, mul_s);
|
bench_binop!(_bench_matrix3_mul_s, Matrix3<f32>, f32, mul);
|
||||||
bench_binop_deref!(_bench_matrix4_mul_s, Matrix4<f32>, f32, mul_s);
|
bench_binop!(_bench_matrix4_mul_s, Matrix4<f32>, f32, mul);
|
||||||
|
|
||||||
bench_binop_deref!(_bench_matrix2_div_s, Matrix2<f32>, f32, div_s);
|
bench_binop!(_bench_matrix2_div_s, Matrix2<f32>, f32, div);
|
||||||
bench_binop_deref!(_bench_matrix3_div_s, Matrix3<f32>, f32, div_s);
|
bench_binop!(_bench_matrix3_div_s, Matrix3<f32>, f32, div);
|
||||||
bench_binop_deref!(_bench_matrix4_div_s, Matrix4<f32>, f32, div_s);
|
bench_binop!(_bench_matrix4_div_s, Matrix4<f32>, f32, div);
|
||||||
|
|
||||||
bench_unop!(_bench_matrix2_invert, Matrix2<f32>, invert);
|
bench_unop!(_bench_matrix2_invert, Matrix2<f32>, invert);
|
||||||
bench_unop!(_bench_matrix3_invert, Matrix3<f32>, invert);
|
bench_unop!(_bench_matrix3_invert, Matrix3<f32>, invert);
|
||||||
|
|
|
@ -20,18 +20,20 @@ extern crate test;
|
||||||
extern crate cgmath;
|
extern crate cgmath;
|
||||||
|
|
||||||
use rand::{IsaacRng, Rng};
|
use rand::{IsaacRng, Rng};
|
||||||
|
use std::ops::*;
|
||||||
use test::Bencher;
|
use test::Bencher;
|
||||||
|
|
||||||
use cgmath::*;
|
use cgmath::*;
|
||||||
|
|
||||||
#[path="common/macros.rs"]
|
#[path="common/macros.rs"]
|
||||||
#[macro_use] mod macros;
|
#[macro_use] mod macros;
|
||||||
|
|
||||||
bench_binop!(_bench_quat_add_q, Quaternion<f32>, Quaternion<f32>, add_q);
|
bench_binop!(_bench_quat_add_q, Quaternion<f32>, Quaternion<f32>, add);
|
||||||
bench_binop!(_bench_quat_sub_q, Quaternion<f32>, Quaternion<f32>, sub_q);
|
bench_binop!(_bench_quat_sub_q, Quaternion<f32>, Quaternion<f32>, sub);
|
||||||
bench_binop!(_bench_quat_mul_q, Quaternion<f32>, Quaternion<f32>, mul_q);
|
bench_binop!(_bench_quat_mul_q, Quaternion<f32>, Quaternion<f32>, mul);
|
||||||
bench_binop!(_bench_quat_mul_v, Quaternion<f32>, Vector3<f32>, mul_v);
|
bench_binop!(_bench_quat_mul_v, Quaternion<f32>, Vector3<f32>, mul);
|
||||||
bench_binop_deref!(_bench_quat_mul_s, Quaternion<f32>, f32, mul_s);
|
bench_binop!(_bench_quat_mul_s, Quaternion<f32>, f32, mul);
|
||||||
bench_binop_deref!(_bench_quat_div_s, Quaternion<f32>, f32, div_s);
|
bench_binop!(_bench_quat_div_s, Quaternion<f32>, f32, div);
|
||||||
bench_unop!(_bench_quat_invert, Quaternion<f32>, invert);
|
bench_unop!(_bench_quat_invert, Quaternion<f32>, invert);
|
||||||
bench_unop!(_bench_quat_conjugate, Quaternion<f32>, conjugate);
|
bench_unop!(_bench_quat_conjugate, Quaternion<f32>, conjugate);
|
||||||
bench_unop!(_bench_quat_normalize, Quaternion<f32>, normalize);
|
bench_unop!(_bench_quat_normalize, Quaternion<f32>, normalize);
|
||||||
|
|
|
@ -20,43 +20,45 @@ extern crate test;
|
||||||
extern crate cgmath;
|
extern crate cgmath;
|
||||||
|
|
||||||
use rand::{IsaacRng, Rng};
|
use rand::{IsaacRng, Rng};
|
||||||
|
use std::ops::*;
|
||||||
use test::Bencher;
|
use test::Bencher;
|
||||||
|
|
||||||
use cgmath::*;
|
use cgmath::*;
|
||||||
|
|
||||||
#[path="common/macros.rs"]
|
#[path="common/macros.rs"]
|
||||||
#[macro_use] mod macros;
|
#[macro_use] mod macros;
|
||||||
|
|
||||||
bench_binop!(_bench_vector2_add_v, Vector2<f32>, Vector2<f32>, add_v);
|
bench_binop!(_bench_vector2_add_v, Vector2<f32>, Vector2<f32>, add);
|
||||||
bench_binop!(_bench_vector3_add_v, Vector3<f32>, Vector3<f32>, add_v);
|
bench_binop!(_bench_vector3_add_v, Vector3<f32>, Vector3<f32>, add);
|
||||||
bench_binop!(_bench_vector4_add_v, Vector4<f32>, Vector4<f32>, add_v);
|
bench_binop!(_bench_vector4_add_v, Vector4<f32>, Vector4<f32>, add);
|
||||||
|
|
||||||
bench_binop!(_bench_vector2_sub_v, Vector2<f32>, Vector2<f32>, sub_v);
|
bench_binop!(_bench_vector2_sub_v, Vector2<f32>, Vector2<f32>, sub);
|
||||||
bench_binop!(_bench_vector3_sub_v, Vector3<f32>, Vector3<f32>, sub_v);
|
bench_binop!(_bench_vector3_sub_v, Vector3<f32>, Vector3<f32>, sub);
|
||||||
bench_binop!(_bench_vector4_sub_v, Vector4<f32>, Vector4<f32>, sub_v);
|
bench_binop!(_bench_vector4_sub_v, Vector4<f32>, Vector4<f32>, sub);
|
||||||
|
|
||||||
bench_binop!(_bench_vector2_mul_v, Vector2<f32>, Vector2<f32>, mul_v);
|
bench_binop!(_bench_vector2_mul_v, Vector2<f32>, Vector2<f32>, mul);
|
||||||
bench_binop!(_bench_vector3_mul_v, Vector3<f32>, Vector3<f32>, mul_v);
|
bench_binop!(_bench_vector3_mul_v, Vector3<f32>, Vector3<f32>, mul);
|
||||||
bench_binop!(_bench_vector4_mul_v, Vector4<f32>, Vector4<f32>, mul_v);
|
bench_binop!(_bench_vector4_mul_v, Vector4<f32>, Vector4<f32>, mul);
|
||||||
|
|
||||||
bench_binop!(_bench_vector2_div_v, Vector2<f32>, Vector2<f32>, div_v);
|
bench_binop!(_bench_vector2_div_v, Vector2<f32>, Vector2<f32>, div);
|
||||||
bench_binop!(_bench_vector3_div_v, Vector3<f32>, Vector3<f32>, div_v);
|
bench_binop!(_bench_vector3_div_v, Vector3<f32>, Vector3<f32>, div);
|
||||||
bench_binop!(_bench_vector4_div_v, Vector4<f32>, Vector4<f32>, div_v);
|
bench_binop!(_bench_vector4_div_v, Vector4<f32>, Vector4<f32>, div);
|
||||||
|
|
||||||
bench_binop_deref!(_bench_vector2_add_s, Vector2<f32>, f32, add_s);
|
bench_binop!(_bench_vector2_add_s, Vector2<f32>, f32, add);
|
||||||
bench_binop_deref!(_bench_vector3_add_s, Vector3<f32>, f32, add_s);
|
bench_binop!(_bench_vector3_add_s, Vector3<f32>, f32, add);
|
||||||
bench_binop_deref!(_bench_vector4_add_s, Vector4<f32>, f32, add_s);
|
bench_binop!(_bench_vector4_add_s, Vector4<f32>, f32, add);
|
||||||
|
|
||||||
bench_binop_deref!(_bench_vector2_sub_s, Vector2<f32>, f32, sub_s);
|
bench_binop!(_bench_vector2_sub_s, Vector2<f32>, f32, sub);
|
||||||
bench_binop_deref!(_bench_vector3_sub_s, Vector3<f32>, f32, sub_s);
|
bench_binop!(_bench_vector3_sub_s, Vector3<f32>, f32, sub);
|
||||||
bench_binop_deref!(_bench_vector4_sub_s, Vector4<f32>, f32, sub_s);
|
bench_binop!(_bench_vector4_sub_s, Vector4<f32>, f32, sub);
|
||||||
|
|
||||||
bench_binop_deref!(_bench_vector2_mul_s, Vector2<f32>, f32, mul_s);
|
bench_binop!(_bench_vector2_mul_s, Vector2<f32>, f32, mul);
|
||||||
bench_binop_deref!(_bench_vector3_mul_s, Vector3<f32>, f32, mul_s);
|
bench_binop!(_bench_vector3_mul_s, Vector3<f32>, f32, mul);
|
||||||
bench_binop_deref!(_bench_vector4_mul_s, Vector4<f32>, f32, mul_s);
|
bench_binop!(_bench_vector4_mul_s, Vector4<f32>, f32, mul);
|
||||||
|
|
||||||
bench_binop_deref!(_bench_vector2_div_s, Vector2<f32>, f32, div_s);
|
bench_binop!(_bench_vector2_div_s, Vector2<f32>, f32, div);
|
||||||
bench_binop_deref!(_bench_vector3_div_s, Vector3<f32>, f32, div_s);
|
bench_binop!(_bench_vector3_div_s, Vector3<f32>, f32, div);
|
||||||
bench_binop_deref!(_bench_vector4_div_s, Vector4<f32>, f32, div_s);
|
bench_binop!(_bench_vector4_div_s, Vector4<f32>, f32, div);
|
||||||
|
|
||||||
|
|
||||||
bench_binop!(_bench_vector2_dot, Vector2<f32>, Vector2<f32>, dot);
|
bench_binop!(_bench_vector2_dot, Vector2<f32>, Vector2<f32>, dot);
|
||||||
|
|
15
src/angle.rs
15
src/angle.rs
|
@ -179,6 +179,15 @@ macro_rules! impl_angle {
|
||||||
impl_operator!(<S: BaseFloat> Rem<$Angle<S> > for $Angle<S> {
|
impl_operator!(<S: BaseFloat> Rem<$Angle<S> > for $Angle<S> {
|
||||||
fn rem(lhs, rhs) -> $Angle<S> { $Angle::new(lhs.s % rhs.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> {
|
impl_operator!(<S: BaseFloat> Mul<S> for $Angle<S> {
|
||||||
fn mul(lhs, scalar) -> $Angle<S> { $Angle::new(lhs.s * scalar) }
|
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> {
|
impl_operator!(<S: BaseFloat> Div<S> for $Angle<S> {
|
||||||
fn div(lhs, scalar) -> $Angle<S> { $Angle::new(lhs.s / scalar) }
|
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> {
|
impl<S: BaseFloat> ApproxEq for $Angle<S> {
|
||||||
type Epsilon = S;
|
type Epsilon = S;
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
//! `look_at`, `from_angle`, `from_euler`, and `from_axis_angle` methods.
|
//! `look_at`, `from_angle`, `from_euler`, and `from_axis_angle` methods.
|
||||||
//! These are provided for convenience.
|
//! These are provided for convenience.
|
||||||
|
|
||||||
|
#![cfg_attr(feature = "unstable", feature(augmented_assignments, op_assign_traits))]
|
||||||
|
|
||||||
extern crate num as rust_num;
|
extern crate num as rust_num;
|
||||||
extern crate rustc_serialize;
|
extern crate rustc_serialize;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
|
|
|
@ -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 {
|
macro_rules! fold_array {
|
||||||
(&$method:ident, { $x:expr, $y:expr }) => { $x.$method(&$y) };
|
(&$method:ident, { $x:expr, $y:expr }) => { $x.$method(&$y) };
|
||||||
(&$method:ident, { $x:expr, $y:expr, $z:expr }) => { $x.$method(&$y).$method(&$z) };
|
(&$method:ident, { $x:expr, $y:expr, $z:expr }) => { $x.$method(&$y).$method(&$z) };
|
||||||
|
|
|
@ -266,6 +266,7 @@ pub trait Matrix where
|
||||||
|
|
||||||
Self: Add<Self, Output = Self>,
|
Self: Add<Self, Output = Self>,
|
||||||
Self: Sub<Self, Output = Self>,
|
Self: Sub<Self, Output = Self>,
|
||||||
|
Self: Neg<Output = Self>,
|
||||||
|
|
||||||
Self: Mul<<Self as Matrix>::Element, Output = Self>,
|
Self: Mul<<Self as Matrix>::Element, Output = Self>,
|
||||||
Self: Div<<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> {
|
impl_operator!(<S: BaseFloat> Rem<S> for $MatrixN<S> {
|
||||||
fn rem(matrix, scalar) -> $MatrixN<S> { $MatrixN { $($field: matrix.$field % scalar),+ } }
|
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> {
|
impl_operator!(<S: BaseFloat> Add<$MatrixN<S> > for $MatrixN<S> {
|
||||||
fn add(lhs, rhs) -> $MatrixN<S> { $MatrixN { $($field: lhs.$field + rhs.$field),+ } }
|
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> {
|
impl_operator!(<S: BaseFloat> Sub<$MatrixN<S> > for $MatrixN<S> {
|
||||||
fn sub(lhs, rhs) -> $MatrixN<S> { $MatrixN { $($field: lhs.$field - rhs.$field),+ } }
|
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> {
|
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())),+) }
|
fn mul(matrix, vector) -> $VectorN<S> { $VectorN::new($(matrix.row($row_index).dot(vector.clone())),+) }
|
||||||
|
|
14
src/point.rs
14
src/point.rs
|
@ -145,6 +145,9 @@ macro_rules! impl_point {
|
||||||
impl_operator!(<S: BaseNum> Add<$VectorN<S> > for $PointN<S> {
|
impl_operator!(<S: BaseNum> Add<$VectorN<S> > for $PointN<S> {
|
||||||
fn add(lhs, rhs) -> $PointN<S> { $PointN::new($(lhs.$field + rhs.$field),+) }
|
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> {
|
impl_operator!(<S: BaseNum> Sub<$PointN<S> > for $PointN<S> {
|
||||||
fn sub(lhs, rhs) -> $VectorN<S> { $VectorN::new($(lhs.$field - rhs.$field),+) }
|
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> {
|
impl_operator!(<S: BaseNum> Mul<S> for $PointN<S> {
|
||||||
fn mul(point, scalar) -> $PointN<S> { $PointN::new($(point.$field * scalar),+) }
|
fn mul(point, scalar) -> $PointN<S> { $PointN::new($(point.$field * scalar),+) }
|
||||||
});
|
});
|
||||||
|
|
||||||
impl_operator!(<S: BaseNum> Div<S> for $PointN<S> {
|
impl_operator!(<S: BaseNum> Div<S> for $PointN<S> {
|
||||||
fn div(point, scalar) -> $PointN<S> { $PointN::new($(point.$field / scalar),+) }
|
fn div(point, scalar) -> $PointN<S> { $PointN::new($(point.$field / scalar),+) }
|
||||||
});
|
});
|
||||||
|
|
||||||
impl_operator!(<S: BaseNum> Rem<S> for $PointN<S> {
|
impl_operator!(<S: BaseNum> Rem<S> for $PointN<S> {
|
||||||
fn rem(point, scalar) -> $PointN<S> { $PointN::new($(point.$field % scalar),+) }
|
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, usize);
|
||||||
impl_index_operators!($PointN<S>, $n, [S], Range<usize>);
|
impl_index_operators!($PointN<S>, $n, [S], Range<usize>);
|
||||||
|
|
|
@ -119,12 +119,18 @@ impl_operator!(<S: BaseFloat> Mul<S> for Quaternion<S> {
|
||||||
Quaternion::from_sv(lhs.s * rhs, lhs.v * rhs)
|
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> {
|
impl_operator!(<S: BaseFloat> Div<S> for Quaternion<S> {
|
||||||
fn div(lhs, rhs) -> Quaternion<S> {
|
fn div(lhs, rhs) -> Quaternion<S> {
|
||||||
Quaternion::from_sv(lhs.s / rhs, lhs.v / rhs)
|
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> {
|
impl_operator!(<S: BaseFloat> Mul<Vector3<S> > for Quaternion<S> {
|
||||||
fn mul(lhs, rhs) -> Vector3<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)
|
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> {
|
impl_operator!(<S: BaseFloat> Sub<Quaternion<S> > for Quaternion<S> {
|
||||||
fn sub(lhs, rhs) -> Quaternion<S> {
|
fn sub(lhs, rhs) -> Quaternion<S> {
|
||||||
Quaternion::from_sv(lhs.s - rhs.s, lhs.v - rhs.v)
|
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> {
|
impl_operator!(<S: BaseFloat> Mul<Quaternion<S> > for Quaternion<S> {
|
||||||
fn mul(lhs, rhs) -> Quaternion<S> {
|
fn mul(lhs, rhs) -> Quaternion<S> {
|
||||||
|
|
|
@ -218,6 +218,12 @@ macro_rules! impl_vector {
|
||||||
impl_operator!(<S: BaseNum> Add<$VectorN<S> > for $VectorN<S> {
|
impl_operator!(<S: BaseNum> Add<$VectorN<S> > for $VectorN<S> {
|
||||||
fn add(lhs, rhs) -> $VectorN<S> { $VectorN::new($(lhs.$field + rhs.$field),+) }
|
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> {
|
impl_operator!(<S: BaseNum> Sub<S> for $VectorN<S> {
|
||||||
fn sub(vector, scalar) -> $VectorN<S> { $VectorN::new($(vector.$field - scalar),+) }
|
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> {
|
impl_operator!(<S: BaseNum> Sub<$VectorN<S> > for $VectorN<S> {
|
||||||
fn sub(lhs, rhs) -> $VectorN<S> { $VectorN::new($(lhs.$field - rhs.$field),+) }
|
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> {
|
impl_operator!(<S: BaseNum> Mul<S> for $VectorN<S> {
|
||||||
fn mul(vector, scalar) -> $VectorN<S> { $VectorN::new($(vector.$field * scalar),+) }
|
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> {
|
impl_operator!(<S: BaseNum> Mul<$VectorN<S> > for $VectorN<S> {
|
||||||
fn mul(lhs, rhs) -> $VectorN<S> { $VectorN::new($(lhs.$field * rhs.$field),+) }
|
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> {
|
impl_operator!(<S: BaseNum> Div<S> for $VectorN<S> {
|
||||||
fn div(vector, scalar) -> $VectorN<S> { $VectorN::new($(vector.$field / scalar),+) }
|
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> {
|
impl_operator!(<S: BaseNum> Div<$VectorN<S> > for $VectorN<S> {
|
||||||
fn div(lhs, rhs) -> $VectorN<S> { $VectorN::new($(lhs.$field / rhs.$field),+) }
|
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> {
|
impl_operator!(<S: BaseNum> Rem<S> for $VectorN<S> {
|
||||||
fn rem(vector, scalar) -> $VectorN<S> { $VectorN::new($(vector.$field % scalar),+) }
|
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> {
|
impl_operator!(<S: BaseNum> Rem<$VectorN<S> > for $VectorN<S> {
|
||||||
fn rem(lhs, rhs) -> $VectorN<S> { $VectorN::new($(lhs.$field % rhs.$field),+) }
|
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, usize);
|
||||||
impl_index_operators!($VectorN<S>, $n, [S], Range<usize>);
|
impl_index_operators!($VectorN<S>, $n, [S], Range<usize>);
|
||||||
|
|
Loading…
Reference in a new issue