From 730dc40b012d4694ac52869b37a98c83107a7d79 Mon Sep 17 00:00:00 2001 From: Eduard Bopp Date: Wed, 6 May 2015 13:23:14 +0200 Subject: [PATCH] Remove operator hacks The LMul, RMul and Scalar* traits were only necessary due to language limitations regarding trait bounds that are now gone. The Mat trait is now expressed in terms of regular operator traits. However, due to the removal of these traits this constitutes a breaking change. --- src/lib.rs | 4 --- src/structs/pnt.rs | 9 +----- src/structs/quat.rs | 4 +-- src/structs/vec.rs | 9 +----- src/structs/vec_macros.rs | 32 -------------------- src/traits/mod.rs | 4 +-- src/traits/operations.rs | 63 --------------------------------------- src/traits/structure.rs | 9 +++--- 8 files changed, 10 insertions(+), 124 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 93c6732d..acc43fba 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -122,7 +122,6 @@ pub use traits::{ Inv, Iterable, IterableMut, - LMul, Mat, Mean, Norm, @@ -133,11 +132,8 @@ pub use traits::{ POrd, POrdering, PntAsVec, - RMul, Rotate, Rotation, RotationMatrix, RotationWithTranslation, Row, - ScalarAdd, ScalarSub, - ScalarMul, ScalarDiv, Shape, SquareMat, ToHomogeneous, diff --git a/src/structs/pnt.rs b/src/structs/pnt.rs index b23ac4c6..fb01e1cd 100644 --- a/src/structs/pnt.rs +++ b/src/structs/pnt.rs @@ -9,8 +9,7 @@ use std::iter::{Iterator, FromIterator, IntoIterator}; use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut}; use rand::{Rand, Rng}; use num::{Zero, One}; -use traits::operations::{ApproxEq, POrd, POrdering, Axpy, ScalarAdd, ScalarSub, ScalarMul, - ScalarDiv}; +use traits::operations::{ApproxEq, POrd, POrdering, Axpy}; use traits::structure::{Cast, Dim, Indexable, Iterable, IterableMut, PntAsVec, Shape, NumPnt, FloatPnt, BaseFloat, BaseNum, Bounded}; use traits::geometry::{Orig, FromHomogeneous, ToHomogeneous}; @@ -66,7 +65,6 @@ pnt_sub_impl!(Pnt1, Vec1); neg_impl!(Pnt1, x); pnt_add_vec_impl!(Pnt1, Vec1, x); pnt_sub_vec_impl!(Pnt1, Vec1, x); -scalar_ops_impl!(Pnt1, x); approx_eq_impl!(Pnt1, x); from_iterator_impl!(Pnt1, iterator); bounded_impl!(Pnt1, x); @@ -109,7 +107,6 @@ pnt_sub_impl!(Pnt2, Vec2); neg_impl!(Pnt2, x, y); pnt_add_vec_impl!(Pnt2, Vec2, x, y); pnt_sub_vec_impl!(Pnt2, Vec2, x, y); -scalar_ops_impl!(Pnt2, x, y); approx_eq_impl!(Pnt2, x, y); from_iterator_impl!(Pnt2, iterator, iterator); bounded_impl!(Pnt2, x, y); @@ -154,7 +151,6 @@ pnt_sub_impl!(Pnt3, Vec3); neg_impl!(Pnt3, x, y, z); pnt_add_vec_impl!(Pnt3, Vec3, x, y, z); pnt_sub_vec_impl!(Pnt3, Vec3, x, y, z); -scalar_ops_impl!(Pnt3, x, y, z); approx_eq_impl!(Pnt3, x, y, z); from_iterator_impl!(Pnt3, iterator, iterator, iterator); bounded_impl!(Pnt3, x, y, z); @@ -201,7 +197,6 @@ pnt_sub_impl!(Pnt4, Vec4); neg_impl!(Pnt4, x, y, z, w); pnt_add_vec_impl!(Pnt4, Vec4, x, y, z, w); pnt_sub_vec_impl!(Pnt4, Vec4, x, y, z, w); -scalar_ops_impl!(Pnt4, x, y, z, w); approx_eq_impl!(Pnt4, x, y, z, w); from_iterator_impl!(Pnt4, iterator, iterator, iterator, iterator); bounded_impl!(Pnt4, x, y, z, w); @@ -250,7 +245,6 @@ pnt_sub_impl!(Pnt5, Vec5); neg_impl!(Pnt5, x, y, z, w, a); pnt_add_vec_impl!(Pnt5, Vec5, x, y, z, w, a); pnt_sub_vec_impl!(Pnt5, Vec5, x, y, z, w, a); -scalar_ops_impl!(Pnt5, x, y, z, w, a); approx_eq_impl!(Pnt5, x, y, z, w, a); from_iterator_impl!(Pnt5, iterator, iterator, iterator, iterator, iterator); bounded_impl!(Pnt5, x, y, z, w, a); @@ -301,7 +295,6 @@ pnt_sub_impl!(Pnt6, Vec6); neg_impl!(Pnt6, x, y, z, w, a, b); pnt_add_vec_impl!(Pnt6, Vec6, x, y, z, w, a, b); pnt_sub_vec_impl!(Pnt6, Vec6, x, y, z, w, a, b); -scalar_ops_impl!(Pnt6, x, y, z, w, a, b); approx_eq_impl!(Pnt6, x, y, z, w, a, b); from_iterator_impl!(Pnt6, iterator, iterator, iterator, iterator, iterator, iterator); bounded_impl!(Pnt6, x, y, z, w, a, b); diff --git a/src/structs/quat.rs b/src/structs/quat.rs index 94f84073..5c24e93a 100644 --- a/src/structs/quat.rs +++ b/src/structs/quat.rs @@ -9,8 +9,7 @@ use std::iter::{FromIterator, IntoIterator}; use rand::{Rand, Rng}; use num::{Zero, One}; use structs::{Vec3, Pnt3, Rot3, Mat3}; -use traits::operations::{ApproxEq, Inv, POrd, POrdering, Axpy, ScalarAdd, ScalarSub, ScalarMul, - ScalarDiv}; +use traits::operations::{ApproxEq, Inv, POrd, POrdering, Axpy}; use traits::structure::{Cast, Indexable, Iterable, IterableMut, Dim, Shape, BaseFloat, BaseNum, Bounded}; use traits::geometry::{Norm, Rotation, Rotate, Transform}; @@ -506,7 +505,6 @@ scalar_sub_impl!(Quat, w, i, j, k); scalar_mul_impl!(Quat, w, i, j, k); scalar_div_impl!(Quat, w, i, j, k); neg_impl!(Quat, w, i, j, k); -scalar_ops_impl!(Quat, w, i, j, k); zero_one_impl!(Quat, w, i, j, k); approx_eq_impl!(Quat, w, i, j, k); from_iterator_impl!(Quat, iterator, iterator, iterator, iterator); diff --git a/src/structs/vec.rs b/src/structs/vec.rs index ff1966ba..618689ad 100644 --- a/src/structs/vec.rs +++ b/src/structs/vec.rs @@ -9,8 +9,7 @@ use std::slice::{Iter, IterMut}; use std::iter::{Iterator, FromIterator, IntoIterator}; use rand::{Rand, Rng}; use num::{Zero, One}; -use traits::operations::{ApproxEq, POrd, POrdering, Axpy, ScalarAdd, ScalarSub, ScalarMul, - ScalarDiv, Absolute}; +use traits::operations::{ApproxEq, POrd, POrdering, Axpy, Absolute}; use traits::geometry::{Transform, Rotate, FromHomogeneous, ToHomogeneous, Dot, Norm, Translation, Translate}; use traits::structure::{Basis, Cast, Dim, Indexable, Iterable, IterableMut, Shape, NumVec, @@ -70,7 +69,6 @@ scalar_mul_impl!(Vec1, x); scalar_div_impl!(Vec1, x); neg_impl!(Vec1, x); dot_impl!(Vec1, x); -scalar_ops_impl!(Vec1, x); translation_impl!(Vec1); norm_impl!(Vec1, x); approx_eq_impl!(Vec1, x); @@ -124,7 +122,6 @@ scalar_mul_impl!(Vec2, x, y); scalar_div_impl!(Vec2, x, y); neg_impl!(Vec2, x, y); dot_impl!(Vec2, x, y); -scalar_ops_impl!(Vec2, x, y); translation_impl!(Vec2); norm_impl!(Vec2, x, y); approx_eq_impl!(Vec2, x, y); @@ -180,7 +177,6 @@ scalar_mul_impl!(Vec3, x, y, z); scalar_div_impl!(Vec3, x, y, z); neg_impl!(Vec3, x, y, z); dot_impl!(Vec3, x, y, z); -scalar_ops_impl!(Vec3, x, y, z); translation_impl!(Vec3); norm_impl!(Vec3, x, y ,z); approx_eq_impl!(Vec3, x, y, z); @@ -239,7 +235,6 @@ scalar_mul_impl!(Vec4, x, y, z, w); scalar_div_impl!(Vec4, 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); translation_impl!(Vec4); norm_impl!(Vec4, x, y, z, w); approx_eq_impl!(Vec4, x, y, z, w); @@ -299,7 +294,6 @@ scalar_mul_impl!(Vec5, x, y, z, w, a); scalar_div_impl!(Vec5, 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); translation_impl!(Vec5); norm_impl!(Vec5, x, y, z, w, a); approx_eq_impl!(Vec5, x, y, z, w, a); @@ -361,7 +355,6 @@ scalar_mul_impl!(Vec6, x, y, z, w, a, b); scalar_div_impl!(Vec6, 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); translation_impl!(Vec6); norm_impl!(Vec6, x, y, z, w, a, b); approx_eq_impl!(Vec6, x, y, z, w, a, b); diff --git a/src/structs/vec_macros.rs b/src/structs/vec_macros.rs index 7f9a5ed8..42ecaf1d 100644 --- a/src/structs/vec_macros.rs +++ b/src/structs/vec_macros.rs @@ -504,38 +504,6 @@ macro_rules! dot_impl( ) ); -macro_rules! scalar_ops_impl( - ($t: ident, $($compN: ident),+) => ( - impl> ScalarMul for $t { - #[inline] - fn mul_s(&self, other: &N) -> $t { - $t::new($(self.$compN * *other),+) - } - } - - impl> ScalarDiv for $t { - #[inline] - fn div_s(&self, other: &N) -> $t { - $t::new($(self.$compN / *other),+) - } - } - - impl> ScalarAdd for $t { - #[inline] - fn add_s(&self, other: &N) -> $t { - $t::new($(self.$compN + *other),+) - } - } - - impl> ScalarSub for $t { - #[inline] - fn sub_s(&self, other: &N) -> $t { - $t::new($(self.$compN - *other),+) - } - } - ) -); - macro_rules! translation_impl( ($t: ident) => ( impl + Neg> Translation<$t> for $t { diff --git a/src/traits/mod.rs b/src/traits/mod.rs index 82ed7531..39d29c00 100644 --- a/src/traits/mod.rs +++ b/src/traits/mod.rs @@ -8,8 +8,8 @@ pub use traits::structure::{FloatVec, FloatPnt, Basis, Cast, Col, Dim, Indexable IterableMut, Mat, SquareMat, Row, NumVec, NumPnt, PntAsVec, ColSlice, RowSlice, Diag, Eye, Shape, BaseFloat, BaseNum, Bounded}; -pub use traits::operations::{Absolute, ApproxEq, Axpy, Cov, Det, Inv, LMul, Mean, Outer, POrd, - RMul, ScalarAdd, ScalarSub, ScalarMul, ScalarDiv, Transpose, EigenQR}; +pub use traits::operations::{Absolute, ApproxEq, Axpy, Cov, Det, Inv, Mean, Outer, POrd, Transpose, + EigenQR}; pub use traits::operations::POrdering; pub mod geometry; diff --git a/src/traits/operations.rs b/src/traits/operations.rs index fa332c03..b3bfeb54 100644 --- a/src/traits/operations.rs +++ b/src/traits/operations.rs @@ -1,7 +1,6 @@ //! Low level operations on vectors and matrices. use num::{Float, Signed}; -use std::ops::Mul; use std::cmp::Ordering; use traits::structure::SquareMat; @@ -337,68 +336,6 @@ pub trait EigenQR: SquareMat { fn eigen_qr(&self, eps: &N, niter: usize) -> (Self, V); } -// XXX: those two traits should not exist since there is generalized operator overloading of Add -// and Sub. -// However, using the same trait multiple time as a trait bound (ex: impl + Add) -// does not work properly, mainly because the way we are doing generalized operator overloading is -// verry hacky. -// -// Hopefully, this will be fixed on a future version of the language! -/// Trait of objects having a right multiplication with another element. -pub trait RMul { - /// Computes `self * v` - fn rmul(&self, v: &V) -> V; -} - -impl, T: Copy> RMul for M { - fn rmul(&self, v: &T) -> T { - *self * *v - } -} - -/// Trait of objects having a left multiplication with another element. -pub trait LMul { - /// Computes `v * self` - fn lmul(&self, &V) -> V; -} - -impl, M: Copy> LMul for M { - fn lmul(&self, v: &T) -> T { - *v * *self - } -} - -// XXX: those traits should not exist since there is generalized operator overloading of Add and -// Sub. -// However, using the same trait multiple time as a trait bound (ex: impl + Add) -// does not work properly, mainly because the way we are doing generalized operator overloading is -// verry hacky. -// -// Hopefully, this will be fixed on a future version of the language! -/// Trait of objects having an addition with a scalar. -pub trait ScalarAdd { - /// Gets the result of `self + n`. - fn add_s(&self, n: &N) -> Self; -} - -/// 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; -} - -/// 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; -} - -/// 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; -} - /// Trait of objects implementing the `y = ax + y` operation. pub trait Axpy { /// Adds $$a * x$$ to `self`. diff --git a/src/traits/structure.rs b/src/traits/structure.rs index d1bb1c3f..8fd7b2c6 100644 --- a/src/traits/structure.rs +++ b/src/traits/structure.rs @@ -4,7 +4,7 @@ use std::{f32, f64, i8, i16, i32, i64, u8, u16, u32, u64, isize, usize}; use std::slice::{Iter, IterMut}; use std::ops::{Add, Sub, Mul, Div, Rem, Index, IndexMut}; use num::{Float, Zero, One}; -use traits::operations::{RMul, LMul, Axpy, Transpose, Inv, Absolute}; +use traits::operations::{Axpy, Transpose, Inv, Absolute}; use traits::geometry::{Dot, Norm, Orig}; /// Basic integral numeric trait. @@ -59,11 +59,12 @@ pub trait Cast { /// Trait of matrices. /// /// A matrix has rows and columns and are able to multiply them. -pub trait Mat: Row + Col + RMul + LMul + Index<(usize, usize), Output = N> { } +pub trait Mat>: Row + Col + Mul + Index<(usize, usize), Output = N> { } impl Mat for M - where M: Row + Col + RMul + LMul + Index<(usize, usize), Output = N> { -} + where M: Row + Col + Mul + Index<(usize, usize), Output = N>, + C: Mul, +{} /// Trait implemented by square matrices. pub trait SquareMat: Mat +