Do not automatically impl Scalar{Mul,Div,Add,Sub}.

This makes them implementable without using the double dispatch trick.
This commit is contained in:
Sébastien Crozet 2014-10-28 19:17:04 +01:00
parent 93b184815f
commit 36d3e88cb0
5 changed files with 51 additions and 31 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -433,6 +433,38 @@ macro_rules! dot_impl(
)
)
macro_rules! scalar_ops_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Mul<N, N>> ScalarMul<N> for $t<N> {
#[inline]
fn mul_s(&self, other: &N) -> $t<N> {
$t::new(self.$comp0 * *other $(, self.$compN * *other)*)
}
}
impl<N: Div<N, N>> ScalarDiv<N> for $t<N> {
#[inline]
fn div_s(&self, other: &N) -> $t<N> {
$t::new(self.$comp0 / *other $(, self.$compN / *other)*)
}
}
impl<N: Add<N, N>> ScalarAdd<N> for $t<N> {
#[inline]
fn add_s(&self, other: &N) -> $t<N> {
$t::new(self.$comp0 + *other $(, self.$compN + *other)*)
}
}
impl<N: Sub<N, N>> ScalarSub<N> for $t<N> {
#[inline]
fn sub_s(&self, other: &N) -> $t<N> {
$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 {

View File

@ -321,52 +321,24 @@ pub trait ScalarAdd<N> {
fn add_s(&self, n: &N) -> Self;
}
impl<N, T: Add<N, T>> ScalarAdd<N> 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<N> {
/// Gets the result of `self - n`.
fn sub_s(&self, n: &N) -> Self;
}
impl<N, T: Sub<N, T>> ScalarSub<N> 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<N> {
/// Gets the result of `self * n`.
fn mul_s(&self, n: &N) -> Self;
}
impl<N, T: Mul<N, T>> ScalarMul<N> 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<N> {
/// Gets the result of `self / n`.
fn div_s(&self, n: &N) -> Self;
}
impl<N, T: Div<N, T>> ScalarDiv<N> 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<N> {
/// Adds $$a * x$$ to `self`.