From 0b7a3385725430ce92456bfb1d6dc836805826bb Mon Sep 17 00:00:00 2001 From: Jason Smith Date: Thu, 12 May 2016 15:49:24 -0400 Subject: [PATCH] Added the ability for vectors to use assignment operators. This added the AddAssign, SubAssign, MulAssign, DivAssign, and RemAssign. This needs to be looked at a little further to see if the other functions need to removed now. --- src/number.rs | 5 +- src/vector.rs | 61 +++++++++++- tests/vector.rs | 256 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 318 insertions(+), 4 deletions(-) diff --git a/src/number.rs b/src/number.rs index ce5129f..eb8684e 100644 --- a/src/number.rs +++ b/src/number.rs @@ -2,6 +2,7 @@ use std::cmp::PartialEq; use std::mem::size_of; use std::num::{Zero, One}; use std::ops::{Add, Sub, Mul, Div, Rem}; +use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign}; use super::bounded::Bounded; @@ -10,7 +11,9 @@ use super::bounded::Bounded; /// a number. pub trait Number : Zero + One + Add + Sub + Mul + Div + Rem + - PartialEq + Copy + Clone + AddAssign + SubAssign + MulAssign + + DivAssign + RemAssign + PartialEq + + Copy + Clone { type StrRadixError; diff --git a/src/vector.rs b/src/vector.rs index 943c2f6..47d68a2 100644 --- a/src/vector.rs +++ b/src/vector.rs @@ -3,6 +3,7 @@ //! [1]: https://en.wikipedia.org/wiki/Vector_(mathematics_and_physics) use std::num::{Zero, One}; use std::ops::{Add, Sub, Mul, Div, Rem, Neg}; +use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign}; use super::number::Number; use super::real::Real; @@ -414,7 +415,7 @@ macro_rules! perform_method_on_components }; } -/// A macro that will define a binary operation +/// A macro that will define a binary operation for /// a Vector and its components. macro_rules! binary_operator_impl { @@ -461,7 +462,7 @@ macro_rules! binary_operator_impl } } - impl<'a, T> $traitName<$structName> for $structName + impl $traitName<$structName> for $structName where T: Number { type Output = $structName; @@ -483,7 +484,7 @@ macro_rules! binary_operator_impl } } - impl<'a, 'b, T> $traitName<&'a $structName> for $structName + impl<'a, T> $traitName<&'a $structName> for $structName where T: Number { type Output = $structName; @@ -507,6 +508,48 @@ macro_rules! binary_operator_impl } } +/// A macro that will define a binary operation for +/// a Vector and its components. +macro_rules! binary_operator_assign_impl +{ + ($traitName: ident :: $funcName: ident, + $structName: ident {$($field: ident),+}) => + { + impl $traitName<$structName> for $structName where T: Number + { + fn $funcName(&mut self, rhs: $structName) + { + $(self.$field.$funcName(rhs.$field);)+ + } + } + + impl $traitName for $structName where T: Number + { + fn $funcName(&mut self, rhs: T) + { + $(self.$field.$funcName(rhs);)+ + } + } + + impl<'a, T> $traitName<&'a $structName> for $structName + where T: Number + { + fn $funcName(&mut self, rhs: &'a $structName) + { + $(self.$field.$funcName(rhs.$field);)+ + } + } + + impl<'a, T> $traitName<&'a T> for $structName where T: Number + { + fn $funcName(&mut self, rhs: &'a T) + { + $(self.$field.$funcName(*rhs);)+ + } + } + } +} + /// A macro that defines a Vector structure /// that implements the Vector trait. macro_rules! define_vector @@ -660,6 +703,18 @@ macro_rules! define_vector binary_operator_impl!(Mul::mul, $structName {$($field),+}); binary_operator_impl!(Div::div, $structName {$($field),+}); binary_operator_impl!(Rem::rem, $structName {$($field),+}); + + // Handle the assignment operators. + binary_operator_assign_impl!(AddAssign::add_assign, + $structName {$($field),+}); + binary_operator_assign_impl!(SubAssign::sub_assign, + $structName {$($field),+}); + binary_operator_assign_impl!(MulAssign::mul_assign, + $structName {$($field),+}); + binary_operator_assign_impl!(DivAssign::div_assign, + $structName {$($field),+}); + binary_operator_assign_impl!(RemAssign::rem_assign, + $structName {$($field),+}); } } diff --git a/tests/vector.rs b/tests/vector.rs index 5ff6375..9795ba5 100644 --- a/tests/vector.rs +++ b/tests/vector.rs @@ -1,6 +1,7 @@ extern crate sigils; use std::ops::{Add, Sub, Mul, Div, Rem}; +use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign}; use sigils::vector::*; @@ -356,3 +357,258 @@ fn vector_rem() assert_eq!(v_three.y, 3.0f32); assert_eq!(v_three.z, 3.0f32); } + +#[test] +fn vector_add_assign() +{ + let v: Vector3 = Vector3::::from_value(1.0f32); + + let v_two: Vector3 = Vector3::::from_value(4.0f32); + let scalar: f32 = 4.0f32; + + let mut v_three = v.clone(); + v_three.add_assign(&v_two); + assert_eq!(v_three.x, 5.0f32); + assert_eq!(v_three.y, 5.0f32); + assert_eq!(v_three.z, 5.0f32); + + let mut v_three = v.clone(); + v_three.add_assign(v_two); + assert_eq!(v_three.x, 5.0f32); + assert_eq!(v_three.y, 5.0f32); + assert_eq!(v_three.z, 5.0f32); + + let mut v_three = v.clone(); + v_three += &v_two; + assert_eq!(v_three.x, 5.0f32); + assert_eq!(v_three.y, 5.0f32); + assert_eq!(v_three.z, 5.0f32); + + let mut v_three = v.clone(); + v_three += v_two; + assert_eq!(v_three.x, 5.0f32); + assert_eq!(v_three.y, 5.0f32); + assert_eq!(v_three.z, 5.0f32); + + let mut v_three = v.clone(); + v_three += 4.0f32; + assert_eq!(v_three.x, 5.0f32); + assert_eq!(v_three.y, 5.0f32); + assert_eq!(v_three.z, 5.0f32); + + let mut v_three = v.clone(); + v_three += scalar; + assert_eq!(v_three.x, 5.0f32); + assert_eq!(v_three.y, 5.0f32); + assert_eq!(v_three.z, 5.0f32); + + let mut v_three = v.clone(); + v_three += &scalar; + assert_eq!(v_three.x, 5.0f32); + assert_eq!(v_three.y, 5.0f32); + assert_eq!(v_three.z, 5.0f32); +} + +#[test] +fn vector_sub_assign() +{ + let v: Vector3 = Vector3::::from_value(9.0f32); + + let v_two: Vector3 = Vector3::::from_value(4.0f32); + let scalar: f32 = 4.0f32; + + let mut v_three = v.clone(); + v_three.sub_assign(&v_two); + assert_eq!(v_three.x, 5.0f32); + assert_eq!(v_three.y, 5.0f32); + assert_eq!(v_three.z, 5.0f32); + + let mut v_three = v.clone(); + v_three.sub_assign(v_two); + assert_eq!(v_three.x, 5.0f32); + assert_eq!(v_three.y, 5.0f32); + assert_eq!(v_three.z, 5.0f32); + + let mut v_three = v.clone(); + v_three -= &v_two; + assert_eq!(v_three.x, 5.0f32); + assert_eq!(v_three.y, 5.0f32); + assert_eq!(v_three.z, 5.0f32); + + let mut v_three = v.clone(); + v_three -= v_two; + assert_eq!(v_three.x, 5.0f32); + assert_eq!(v_three.y, 5.0f32); + assert_eq!(v_three.z, 5.0f32); + + let mut v_three = v.clone(); + v_three -= 4.0f32; + assert_eq!(v_three.x, 5.0f32); + assert_eq!(v_three.y, 5.0f32); + assert_eq!(v_three.z, 5.0f32); + + let mut v_three = v.clone(); + v_three -= scalar; + assert_eq!(v_three.x, 5.0f32); + assert_eq!(v_three.y, 5.0f32); + assert_eq!(v_three.z, 5.0f32); + + let mut v_three = v.clone(); + v_three -= &scalar; + assert_eq!(v_three.x, 5.0f32); + assert_eq!(v_three.y, 5.0f32); + assert_eq!(v_three.z, 5.0f32); +} + +#[test] +fn vector_mul_assign() +{ + let v: Vector3 = Vector3::::from_value(3.0f32); + + let v_two: Vector3 = Vector3::::from_value(5.0f32); + let scalar: f32 = 5.0f32; + + let mut v_three = v.clone(); + v_three.mul_assign(&v_two); + assert_eq!(v_three.x, 15.0f32); + assert_eq!(v_three.y, 15.0f32); + assert_eq!(v_three.z, 15.0f32); + + let mut v_three = v.clone(); + v_three.mul_assign(v_two); + assert_eq!(v_three.x, 15.0f32); + assert_eq!(v_three.y, 15.0f32); + assert_eq!(v_three.z, 15.0f32); + + let mut v_three = v.clone(); + v_three *= &v_two; + assert_eq!(v_three.x, 15.0f32); + assert_eq!(v_three.y, 15.0f32); + assert_eq!(v_three.z, 15.0f32); + + let mut v_three = v.clone(); + v_three *= v_two; + assert_eq!(v_three.x, 15.0f32); + assert_eq!(v_three.y, 15.0f32); + assert_eq!(v_three.z, 15.0f32); + + let mut v_three = v.clone(); + v_three *= 5.0f32; + assert_eq!(v_three.x, 15.0f32); + assert_eq!(v_three.y, 15.0f32); + assert_eq!(v_three.z, 15.0f32); + + let mut v_three = v.clone(); + v_three*= scalar; + assert_eq!(v_three.x, 15.0f32); + assert_eq!(v_three.y, 15.0f32); + assert_eq!(v_three.z, 15.0f32); + + let mut v_three = v.clone(); + v_three *= &scalar; + assert_eq!(v_three.x, 15.0f32); + assert_eq!(v_three.y, 15.0f32); + assert_eq!(v_three.z, 15.0f32); +} + +#[test] +fn vector_div_assign() +{ + let v: Vector3 = Vector3::::from_value(15.0f32); + + let v_two: Vector3 = Vector3::::from_value(5.0f32); + let scalar: f32 = 5.0f32; + + let mut v_three = v.clone(); + v_three.div_assign(&v_two); + assert_eq!(v_three.x, 3.0f32); + assert_eq!(v_three.y, 3.0f32); + assert_eq!(v_three.z, 3.0f32); + + let mut v_three = v.clone(); + v_three.div_assign(v_two); + assert_eq!(v_three.x, 3.0f32); + assert_eq!(v_three.y, 3.0f32); + assert_eq!(v_three.z, 3.0f32); + + let mut v_three = v.clone(); + v_three /= &v_two; + assert_eq!(v_three.x, 3.0f32); + assert_eq!(v_three.y, 3.0f32); + assert_eq!(v_three.z, 3.0f32); + + let mut v_three = v.clone(); + v_three /= v_two; + assert_eq!(v_three.x, 3.0f32); + assert_eq!(v_three.y, 3.0f32); + assert_eq!(v_three.z, 3.0f32); + + let mut v_three = v.clone(); + v_three /= 5.0f32; + assert_eq!(v_three.x, 3.0f32); + assert_eq!(v_three.y, 3.0f32); + assert_eq!(v_three.z, 3.0f32); + + let mut v_three = v.clone(); + v_three /= scalar; + assert_eq!(v_three.x, 3.0f32); + assert_eq!(v_three.y, 3.0f32); + assert_eq!(v_three.z, 3.0f32); + + let mut v_three = v.clone(); + v_three /= &scalar; + assert_eq!(v_three.x, 3.0f32); + assert_eq!(v_three.y, 3.0f32); + assert_eq!(v_three.z, 3.0f32); +} + +#[test] +fn vector_rem_assign() +{ + let v: Vector3 = Vector3::::from_value(15.0f32); + + let v_two: Vector3 = Vector3::::from_value(6.0f32); + let scalar: f32 = 6.0f32; + + let mut v_three = v.clone(); + v_three.rem_assign(&v_two); + assert_eq!(v_three.x, 3.0f32); + assert_eq!(v_three.y, 3.0f32); + assert_eq!(v_three.z, 3.0f32); + + let mut v_three = v.clone(); + v_three.rem_assign(v_two); + assert_eq!(v_three.x, 3.0f32); + assert_eq!(v_three.y, 3.0f32); + assert_eq!(v_three.z, 3.0f32); + + let mut v_three = v.clone(); + v_three %= &v_two; + assert_eq!(v_three.x, 3.0f32); + assert_eq!(v_three.y, 3.0f32); + assert_eq!(v_three.z, 3.0f32); + + let mut v_three = v.clone(); + v_three %= v_two; + assert_eq!(v_three.x, 3.0f32); + assert_eq!(v_three.y, 3.0f32); + assert_eq!(v_three.z, 3.0f32); + + let mut v_three = v.clone(); + v_three %= 6.0f32; + assert_eq!(v_three.x, 3.0f32); + assert_eq!(v_three.y, 3.0f32); + assert_eq!(v_three.z, 3.0f32); + + let mut v_three = v.clone(); + v_three %= scalar; + assert_eq!(v_three.x, 3.0f32); + assert_eq!(v_three.y, 3.0f32); + assert_eq!(v_three.z, 3.0f32); + + let mut v_three = v.clone(); + v_three %= &scalar; + assert_eq!(v_three.x, 3.0f32); + assert_eq!(v_three.y, 3.0f32); + assert_eq!(v_three.z, 3.0f32); +}