Implement Sum for Angle

This commit is contained in:
Brendan Zabarauskas 2017-04-26 21:11:29 +10:00
parent 77260934a1
commit ff2d15e0ff
4 changed files with 40 additions and 1 deletions

View file

@ -17,6 +17,7 @@
use std::fmt; use std::fmt;
use std::f64; use std::f64;
use std::iter;
use std::ops::*; use std::ops::*;
use rand::{Rand, Rng}; use rand::{Rand, Rng};
@ -72,6 +73,20 @@ macro_rules! impl_angle {
} }
} }
impl<S: BaseFloat> iter::Sum<$Angle<S>> for $Angle<S> {
#[inline]
fn sum<I: Iterator<Item=$Angle<S>>>(iter: I) -> $Angle<S> {
iter.fold($Angle::zero(), Add::add)
}
}
impl<'a, S: 'a + BaseFloat> iter::Sum<&'a $Angle<S>> for $Angle<S> {
#[inline]
fn sum<I: Iterator<Item=&'a $Angle<S>>>(iter: I) -> $Angle<S> {
iter.fold($Angle::zero(), Add::add)
}
}
impl<S: BaseFloat> Angle for $Angle<S> { impl<S: BaseFloat> Angle for $Angle<S> {
type Unitless = S; type Unitless = S;

View file

@ -551,6 +551,8 @@ pub trait Angle where
Self: Mul<<Self as Angle>::Unitless, Output = Self>, Self: Mul<<Self as Angle>::Unitless, Output = Self>,
Self: Div<Self, Output = <Self as Angle>::Unitless>, Self: Div<Self, Output = <Self as Angle>::Unitless>,
Self: Div<<Self as Angle>::Unitless, Output = Self>, Self: Div<<Self as Angle>::Unitless, Output = Self>,
Self: iter::Sum,
{ {
type Unitless: BaseFloat; type Unitless: BaseFloat;

View file

@ -20,7 +20,7 @@ extern crate cgmath;
use cgmath::{Rad, Deg}; use cgmath::{Rad, Deg};
#[test] #[test]
fn conv() { fn test_conv() {
let angle: Rad<_> = Deg(-5.0f64).into(); let angle: Rad<_> = Deg(-5.0f64).into();
let angle: Deg<_> = angle.into(); let angle: Deg<_> = angle.into();
assert_ulps_eq!(&angle, &Deg(-5.0f64)); assert_ulps_eq!(&angle, &Deg(-5.0f64));
@ -37,3 +37,23 @@ fn conv() {
let angle: Rad<_> = angle.into(); let angle: Rad<_> = angle.into();
assert_ulps_eq!(&angle, &Rad(30.0f64)); assert_ulps_eq!(&angle, &Rad(30.0f64));
} }
mod rad {
use cgmath::Rad;
#[test]
fn test_iter_sum() {
assert_eq!(Rad(2.0) + Rad(3.0) + Rad(4.0), [Rad(2.0), Rad(3.0), Rad(4.0)].iter().sum());
assert_eq!(Rad(2.0) + Rad(3.0) + Rad(4.0), [Rad(2.0), Rad(3.0), Rad(4.0)].iter().cloned().sum());
}
}
mod deg {
use cgmath::Deg;
#[test]
fn test_iter_sum() {
assert_eq!(Deg(2.0) + Deg(3.0) + Deg(4.0), [Deg(2.0), Deg(3.0), Deg(4.0)].iter().sum());
assert_eq!(Deg(2.0) + Deg(3.0) + Deg(4.0), [Deg(2.0), Deg(3.0), Deg(4.0)].iter().cloned().sum());
}
}

View file

@ -59,6 +59,7 @@ mod operators {
let q3 = Quaternion::from(Euler { x: Rad(1f32), y: Rad(1f32), z: Rad(2f32) }); let q3 = Quaternion::from(Euler { x: Rad(1f32), y: Rad(1f32), z: Rad(2f32) });
assert_eq!(q1 + q2 + q3, [q1, q2, q3].iter().sum()); assert_eq!(q1 + q2 + q3, [q1, q2, q3].iter().sum());
assert_eq!(q1 + q2 + q3, [q1, q2, q3].iter().cloned().sum());
} }
#[test] #[test]
@ -68,6 +69,7 @@ mod operators {
let q3 = Quaternion::from(Euler { x: Rad(1f32), y: Rad(1f32), z: Rad(2f32) }); let q3 = Quaternion::from(Euler { x: Rad(1f32), y: Rad(1f32), z: Rad(2f32) });
assert_eq!(q1 * q2 * q3, [q1, q2, q3].iter().product()); assert_eq!(q1 * q2 * q3, [q1, q2, q3].iter().product());
assert_eq!(q1 * q2 * q3, [q1, q2, q3].iter().cloned().product());
} }
} }