From 36d3e88cb0b68415dfe3c6e7036ef3680eab7244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Tue, 28 Oct 2014 19:17:04 +0100 Subject: [PATCH] Do not automatically impl Scalar{Mul,Div,Add,Sub}. This makes them implementable without using the double dispatch trick. --- src/structs/pnt.rs | 9 ++++++++- src/structs/quat.rs | 4 +++- src/structs/vec.rs | 9 ++++++++- src/structs/vec_macros.rs | 32 ++++++++++++++++++++++++++++++++ src/traits/operations.rs | 28 ---------------------------- 5 files changed, 51 insertions(+), 31 deletions(-) diff --git a/src/structs/pnt.rs b/src/structs/pnt.rs index c303b3fd..b546f15f 100644 --- a/src/structs/pnt.rs +++ b/src/structs/pnt.rs @@ -7,7 +7,8 @@ use std::num::{Zero, One, Bounded}; use std::slice::{Items, MutItems}; use std::iter::{Iterator, FromIterator}; use traits::operations::{ApproxEq, POrd, POrdering, PartialLess, PartialEqual, - PartialGreater, NotComparable, Axpy}; + PartialGreater, NotComparable, Axpy, ScalarAdd, ScalarSub, ScalarMul, + ScalarDiv}; use traits::structure::{Cast, Dim, Indexable, Iterable, IterableMut, PntAsVec, Shape, NumPnt, FloatPnt}; use traits::geometry::{Orig, FromHomogeneous, ToHomogeneous}; @@ -65,6 +66,7 @@ pnt_sub_impl!(Pnt1, Vec1, Pnt1SubRhs) neg_impl!(Pnt1, x) pnt_add_vec_impl!(Pnt1, Vec1, Pnt1AddRhs, x) pnt_sub_vec_impl!(Pnt1, Vec1, Pnt1SubRhs, x) +scalar_ops_impl!(Pnt1, x) vec_mul_scalar_impl!(Pnt1, f64, Pnt1MulRhs, x) vec_mul_scalar_impl!(Pnt1, f32, Pnt1MulRhs, x) vec_mul_scalar_impl!(Pnt1, u64, Pnt1MulRhs, x) @@ -158,6 +160,7 @@ pnt_sub_impl!(Pnt2, Vec2, Pnt2SubRhs) neg_impl!(Pnt2, x, y) pnt_add_vec_impl!(Pnt2, Vec2, Pnt2AddRhs, x, y) pnt_sub_vec_impl!(Pnt2, Vec2, Pnt2SubRhs, x, y) +scalar_ops_impl!(Pnt2, x, y) vec_mul_scalar_impl!(Pnt2, f64, Pnt2MulRhs, x, y) vec_mul_scalar_impl!(Pnt2, f32, Pnt2MulRhs, x, y) vec_mul_scalar_impl!(Pnt2, u64, Pnt2MulRhs, x, y) @@ -253,6 +256,7 @@ pnt_sub_impl!(Pnt3, Vec3, Pnt3SubRhs) neg_impl!(Pnt3, x, y, z) pnt_add_vec_impl!(Pnt3, Vec3, Pnt3AddRhs, x, y, z) pnt_sub_vec_impl!(Pnt3, Vec3, Pnt3SubRhs, x, y, z) +scalar_ops_impl!(Pnt3, x, y, z) vec_mul_scalar_impl!(Pnt3, f64, Pnt3MulRhs, x, y, z) vec_mul_scalar_impl!(Pnt3, f32, Pnt3MulRhs, x, y, z) vec_mul_scalar_impl!(Pnt3, u64, Pnt3MulRhs, x, y, z) @@ -350,6 +354,7 @@ pnt_sub_impl!(Pnt4, Vec4, Pnt4SubRhs) neg_impl!(Pnt4, x, y, z, w) pnt_add_vec_impl!(Pnt4, Vec4, Pnt4AddRhs, x, y, z, w) pnt_sub_vec_impl!(Pnt4, Vec4, Pnt4SubRhs, x, y, z, w) +scalar_ops_impl!(Pnt4, x, y, z, w) vec_mul_scalar_impl!(Pnt4, f64, Pnt4MulRhs, x, y, z, w) vec_mul_scalar_impl!(Pnt4, f32, Pnt4MulRhs, x, y, z, w) vec_mul_scalar_impl!(Pnt4, u64, Pnt4MulRhs, x, y, z, w) @@ -449,6 +454,7 @@ pnt_sub_impl!(Pnt5, Vec5, Pnt5SubRhs) neg_impl!(Pnt5, x, y, z, w, a) pnt_add_vec_impl!(Pnt5, Vec5, Pnt5AddRhs, x, y, z, w, a) pnt_sub_vec_impl!(Pnt5, Vec5, Pnt5SubRhs, x, y, z, w, a) +scalar_ops_impl!(Pnt5, x, y, z, w, a) vec_mul_scalar_impl!(Pnt5, f64, Pnt5MulRhs, x, y, z, w, a) vec_mul_scalar_impl!(Pnt5, f32, Pnt5MulRhs, x, y, z, w, a) vec_mul_scalar_impl!(Pnt5, u64, Pnt5MulRhs, x, y, z, w, a) @@ -550,6 +556,7 @@ pnt_sub_impl!(Pnt6, Vec6, Pnt6SubRhs) neg_impl!(Pnt6, x, y, z, w, a, b) pnt_add_vec_impl!(Pnt6, Vec6, Pnt6AddRhs, x, y, z, w, a, b) pnt_sub_vec_impl!(Pnt6, Vec6, Pnt6SubRhs, x, y, z, w, a, b) +scalar_ops_impl!(Pnt6, x, y, z, w, a, b) vec_mul_scalar_impl!(Pnt6, f64, Pnt6MulRhs, x, y, z, w, a, b) vec_mul_scalar_impl!(Pnt6, f32, Pnt6MulRhs, x, y, z, w, a, b) vec_mul_scalar_impl!(Pnt6, u64, Pnt6MulRhs, x, y, z, w, a, b) diff --git a/src/structs/quat.rs b/src/structs/quat.rs index a34a098c..02a6660e 100644 --- a/src/structs/quat.rs +++ b/src/structs/quat.rs @@ -9,7 +9,8 @@ use std::rand::{Rand, Rng}; use std::slice::{Items, MutItems}; use structs::{Vec3, Pnt3, Rot3, Mat3, Vec3MulRhs, Pnt3MulRhs}; use traits::operations::{ApproxEq, Inv, POrd, POrdering, NotComparable, PartialLess, - PartialGreater, PartialEqual, Axpy}; + PartialGreater, PartialEqual, Axpy, ScalarAdd, ScalarSub, ScalarMul, + ScalarDiv}; use traits::structure::{Cast, Indexable, Iterable, IterableMut, Dim, Shape}; use traits::geometry::{Norm, Cross, Rotation, Rotate, Transform}; @@ -470,6 +471,7 @@ container_impl!(Quat) add_impl!(Quat, QuatAddRhs, w, i, j, k) sub_impl!(Quat, QuatSubRhs, w, i, j, k) neg_impl!(Quat, w, i, j, k) +scalar_ops_impl!(Quat, w, i, j, k) vec_mul_scalar_impl!(Quat, f64, QuatMulRhs, w, i, j, k) vec_mul_scalar_impl!(Quat, f32, QuatMulRhs, w, i, j, k) vec_mul_scalar_impl!(Quat, u64, QuatMulRhs, w, i, j, k) diff --git a/src/structs/vec.rs b/src/structs/vec.rs index 387ea26c..ec743466 100644 --- a/src/structs/vec.rs +++ b/src/structs/vec.rs @@ -7,7 +7,8 @@ use std::num::{Zero, One, Float, Bounded}; use std::slice::{Items, MutItems}; use std::iter::{Iterator, FromIterator}; use traits::operations::{ApproxEq, POrd, POrdering, PartialLess, PartialEqual, - PartialGreater, NotComparable, Axpy}; + PartialGreater, NotComparable, Axpy, ScalarAdd, ScalarSub, ScalarMul, + ScalarDiv}; use traits::geometry::{Transform, Rotate, FromHomogeneous, ToHomogeneous, Dot, Norm, Translation, Translate}; use traits::structure::{Basis, Cast, Dim, Indexable, Iterable, IterableMut, VecAsPnt, Shape, @@ -68,6 +69,7 @@ mul_impl!(Vec1, Vec1MulRhs, x) div_impl!(Vec1, Vec1DivRhs, x) neg_impl!(Vec1, x) dot_impl!(Vec1, x) +scalar_ops_impl!(Vec1, x) vec_mul_scalar_impl!(Vec1, f64, Vec1MulRhs, x) vec_mul_scalar_impl!(Vec1, f32, Vec1MulRhs, x) vec_mul_scalar_impl!(Vec1, u64, Vec1MulRhs, x) @@ -171,6 +173,7 @@ mul_impl!(Vec2, Vec2MulRhs, x, y) div_impl!(Vec2, Vec2DivRhs, x, y) neg_impl!(Vec2, x, y) dot_impl!(Vec2, x, y) +scalar_ops_impl!(Vec2, x, y) vec_mul_scalar_impl!(Vec2, f64, Vec2MulRhs, x, y) vec_mul_scalar_impl!(Vec2, f32, Vec2MulRhs, x, y) vec_mul_scalar_impl!(Vec2, u64, Vec2MulRhs, x, y) @@ -276,6 +279,7 @@ mul_impl!(Vec3, Vec3MulRhs, x, y, z) div_impl!(Vec3, Vec3DivRhs, x, y, z) neg_impl!(Vec3, x, y, z) dot_impl!(Vec3, x, y, z) +scalar_ops_impl!(Vec3, x, y, z) vec_mul_scalar_impl!(Vec3, f64, Vec3MulRhs, x, y, z) vec_mul_scalar_impl!(Vec3, f32, Vec3MulRhs, x, y, z) vec_mul_scalar_impl!(Vec3, u64, Vec3MulRhs, x, y, z) @@ -387,6 +391,7 @@ mul_impl!(Vec4, Vec4MulRhs, x, y, z, w) div_impl!(Vec4, Vec4DivRhs, x, y, z, w) neg_impl!(Vec4, x, y, z, w) dot_impl!(Vec4, x, y, z, w) +scalar_ops_impl!(Vec4, x, y, z, w) vec_mul_scalar_impl!(Vec4, f64, Vec4MulRhs, x, y, z, w) vec_mul_scalar_impl!(Vec4, f32, Vec4MulRhs, x, y, z, w) vec_mul_scalar_impl!(Vec4, u64, Vec4MulRhs, x, y, z, w) @@ -496,6 +501,7 @@ mul_impl!(Vec5, Vec5MulRhs, x, y, z, w, a) div_impl!(Vec5, Vec5DivRhs, x, y, z, w, a) neg_impl!(Vec5, x, y, z, w, a) dot_impl!(Vec5, x, y, z, w, a) +scalar_ops_impl!(Vec5, x, y, z, w, a) vec_mul_scalar_impl!(Vec5, f64, Vec5MulRhs, x, y, z, w, a) vec_mul_scalar_impl!(Vec5, f32, Vec5MulRhs, x, y, z, w, a) vec_mul_scalar_impl!(Vec5, u64, Vec5MulRhs, x, y, z, w, a) @@ -607,6 +613,7 @@ mul_impl!(Vec6, Vec6MulRhs, x, y, z, w, a, b) div_impl!(Vec6, Vec6DivRhs, x, y, z, w, a, b) neg_impl!(Vec6, x, y, z, w, a, b) dot_impl!(Vec6, x, y, z, w, a, b) +scalar_ops_impl!(Vec6, x, y, z, w, a, b) vec_mul_scalar_impl!(Vec6, f64, Vec6MulRhs, x, y, z, w, a, b) vec_mul_scalar_impl!(Vec6, f32, Vec6MulRhs, x, y, z, w, a, b) vec_mul_scalar_impl!(Vec6, u64, Vec6MulRhs, x, y, z, w, a, b) diff --git a/src/structs/vec_macros.rs b/src/structs/vec_macros.rs index 75c2c8ff..9568a69c 100644 --- a/src/structs/vec_macros.rs +++ b/src/structs/vec_macros.rs @@ -433,6 +433,38 @@ macro_rules! dot_impl( ) ) +macro_rules! scalar_ops_impl( + ($t: ident, $comp0: ident $(,$compN: ident)*) => ( + impl> ScalarMul for $t { + #[inline] + fn mul_s(&self, other: &N) -> $t { + $t::new(self.$comp0 * *other $(, self.$compN * *other)*) + } + } + + impl> ScalarDiv for $t { + #[inline] + fn div_s(&self, other: &N) -> $t { + $t::new(self.$comp0 / *other $(, self.$compN / *other)*) + } + } + + impl> ScalarAdd for $t { + #[inline] + fn add_s(&self, other: &N) -> $t { + $t::new(self.$comp0 + *other $(, self.$compN + *other)*) + } + } + + impl> ScalarSub for $t { + #[inline] + fn sub_s(&self, other: &N) -> $t { + $t::new(self.$comp0 - *other $(, self.$compN - *other)*) + } + } + ) +) + macro_rules! vec_mul_scalar_impl( ($t: ident, $n: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => ( impl $trhs<$n, $t<$n>> for $n { diff --git a/src/traits/operations.rs b/src/traits/operations.rs index 1d756ac6..3f2973c9 100644 --- a/src/traits/operations.rs +++ b/src/traits/operations.rs @@ -321,52 +321,24 @@ pub trait ScalarAdd { fn add_s(&self, n: &N) -> Self; } -impl> ScalarAdd for T { - /// Gets the result of `self + n`. - fn add_s(&self, n: &N) -> T { - *self + *n - } -} - /// Trait of objects having a subtraction with a scalar. pub trait ScalarSub { /// Gets the result of `self - n`. fn sub_s(&self, n: &N) -> Self; } -impl> ScalarSub for T { - /// Gets the result of `self - n`. - fn sub_s(&self, n: &N) -> T { - *self - *n - } -} - /// Trait of objects having a multiplication with a scalar. pub trait ScalarMul { /// Gets the result of `self * n`. fn mul_s(&self, n: &N) -> Self; } -impl> ScalarMul for T { - /// Gets the result of `self * n`. - fn mul_s(&self, n: &N) -> T { - *self * *n - } -} - /// Trait of objects having a division by a scalar. pub trait ScalarDiv { /// Gets the result of `self / n`. fn div_s(&self, n: &N) -> Self; } -impl> ScalarDiv for T { - /// Gets the result of `self / n`. - fn div_s(&self, n: &N) -> T { - *self / *n - } -} - /// Trait of objects implementing the `y = ax + y` operation. pub trait Axpy { /// Adds $$a * x$$ to `self`.