From 9badebf24c78182801c8ef9c4e9f872be57f0c2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Thu, 8 May 2014 23:19:42 +0200 Subject: [PATCH] Give access to the traits required for generalized operator overloading. Those are `Vec3MulRhs`-like traits that allow the simulation of haskellish fundeps to allow multiple overloads of builtin operators (* / + -). They are all on the `na::overload` module. --- src/na.rs | 28 ++++++++++++++++++++++++++++ src/structs/metal.rs | 4 ++++ src/structs/mod.rs | 9 +++++++++ 3 files changed, 41 insertions(+) diff --git a/src/na.rs b/src/na.rs index 813647ab..98211927 100644 --- a/src/na.rs +++ b/src/na.rs @@ -52,6 +52,34 @@ pub use structs::{ Vec0, Vec1, Vec2, Vec3, Vec4, Vec5, Vec6 }; +/// Traits to work around the language limitations related to operator overloading. +/// +/// The trait names are formed by: +/// +/// * a type name (eg. Vec1, Vec2, Mat3, Mat4, etc.). +/// * the name of a binary operation (eg. Mul, Div, Add, Sub, etc.). +/// * the word `Rhs`. +/// +/// When implemented by the type `T`, the trait makes it possible to overload the binary operator +/// between `T` and the type name given by the trait. +/// +/// # Examples: +/// +/// * `Vec3MulRhs` will allow the overload of the `*` operator between the implementor type and +/// `Vec3`. The `Vec3` being the first argument of the multiplication. +/// * `Mat4DivRhs` will allow the overload of the `/` operator between the implementor type and +/// `Mat4`. The `Mat4` being the first argument of the division. +pub mod overload { + pub use structs::{Vec1SubRhs, Vec2MulRhs, Vec3MulRhs, Vec4MulRhs, Vec5MulRhs, Vec6MulRhs, + Vec1DivRhs, Vec2DivRhs, Vec3DivRhs, Vec4DivRhs, Vec5DivRhs, Vec6DivRhs, + Vec1AddRhs, Vec2AddRhs, Vec3AddRhs, Vec4AddRhs, Vec5AddRhs, Vec6AddRhs, + Vec1SubRhs, Vec2SubRhs, Vec3SubRhs, Vec4SubRhs, Vec5SubRhs, Vec6SubRhs, + Mat1MulRhs, Mat2MulRhs, Mat3MulRhs, Mat4MulRhs, Mat5MulRhs, Mat6MulRhs, + Mat1DivRhs, Mat2DivRhs, Mat3DivRhs, Mat4DivRhs, Mat5DivRhs, Mat6DivRhs, + Mat1AddRhs, Mat2AddRhs, Mat3AddRhs, Mat4AddRhs, Mat5AddRhs, Mat6AddRhs, + Mat1SubRhs, Mat2SubRhs, Mat3SubRhs, Mat4SubRhs, Mat5SubRhs, Mat6SubRhs}; +} + /// Change the input value to ensure it is on the range `[min, max]`. #[inline(always)] pub fn clamp(val: T, min: T, max: T) -> T { diff --git a/src/structs/metal.rs b/src/structs/metal.rs index c91d19d2..5e69c8c3 100644 --- a/src/structs/metal.rs +++ b/src/structs/metal.rs @@ -10,6 +10,10 @@ macro_rules! double_dispatch_binop_decl_trait( ($t: ident, $trhs: ident) => ( pub trait $trhs { + /// Applies the binary operation represented by this trait. + /// + /// In infix notation, assuming the operation is noted `*`, the following is computed: + /// `right * left`. fn binop(left: &$t, right: &Self) -> Res; } ) diff --git a/src/structs/mod.rs b/src/structs/mod.rs index e9c2935e..f7ebcac4 100644 --- a/src/structs/mod.rs +++ b/src/structs/mod.rs @@ -7,6 +7,15 @@ pub use self::mat::{Identity, Mat1, Mat2, Mat3, Mat4, Mat5, Mat6}; pub use self::rot::{Rot2, Rot3, Rot4}; pub use self::iso::{Iso2, Iso3, Iso4}; +pub use self::vec::{Vec1MulRhs, Vec2MulRhs, Vec3MulRhs, Vec4MulRhs, Vec5MulRhs, Vec6MulRhs, + Vec1DivRhs, Vec2DivRhs, Vec3DivRhs, Vec4DivRhs, Vec5DivRhs, Vec6DivRhs, + Vec1AddRhs, Vec2AddRhs, Vec3AddRhs, Vec4AddRhs, Vec5AddRhs, Vec6AddRhs, + Vec1SubRhs, Vec2SubRhs, Vec3SubRhs, Vec4SubRhs, Vec5SubRhs, Vec6SubRhs}; +pub use self::mat::{Mat1MulRhs, Mat2MulRhs, Mat3MulRhs, Mat4MulRhs, Mat5MulRhs, Mat6MulRhs, + Mat1DivRhs, Mat2DivRhs, Mat3DivRhs, Mat4DivRhs, Mat5DivRhs, Mat6DivRhs, + Mat1AddRhs, Mat2AddRhs, Mat3AddRhs, Mat4AddRhs, Mat5AddRhs, Mat6AddRhs, + Mat1SubRhs, Mat2SubRhs, Mat3SubRhs, Mat4SubRhs, Mat5SubRhs, Mat6SubRhs}; + mod dmat; mod dvec; mod vec;