Make Angle's type parameter an associated type

This commit is contained in:
Brendan Zabarauskas 2015-12-13 12:14:57 +11:00
parent de4389759b
commit 981836626b

View file

@ -74,21 +74,21 @@ impl<S: BaseFloat> ScalarConv<S> for Deg<S> {
} }
/// Operations on angles. /// Operations on angles.
pub trait Angle pub trait Angle where
< Self: Clone + Zero,
S: BaseFloat Self: PartialEq + PartialOrd,
> // FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
: Clone + Zero Self: ApproxEq<Epsilon = <Self as Angle>::Unitless>,
+ PartialEq + PartialOrd Self: Neg<Output = Self>,
+ ApproxEq<Epsilon = S> Self: Into<Rad<<Self as Angle>::Unitless>>,
+ Neg<Output=Self> Self: Into<Deg<<Self as Angle>::Unitless>>,
+ Into<Rad<S>> Self: ScalarConv<<Self as Angle>::Unitless>,
+ Into<Deg<S>> Self: fmt::Debug,
+ ScalarConv<S>
+ fmt::Debug
{ {
type Unitless: BaseFloat;
/// Create a new angle from any other valid angle. /// Create a new angle from any other valid angle.
fn from<A: Angle<S>>(theta: A) -> Self; fn from<A: Angle<Unitless = Self::Unitless>>(theta: A) -> Self;
/// Negate this angle, in-place. /// Negate this angle, in-place.
#[inline] fn neg_self(&mut self) { *self = -(*self).clone() } #[inline] fn neg_self(&mut self) { *self = -(*self).clone() }
@ -98,16 +98,16 @@ pub trait Angle
/// Subtract another angle from this one, returning the new angle. /// Subtract another angle from this one, returning the new angle.
#[inline] fn sub_a(&self, other: Self) -> Self { ScalarConv::from(*self.s() - *other.s()) } #[inline] fn sub_a(&self, other: Self) -> Self { ScalarConv::from(*self.s() - *other.s()) }
/// Divide this angle by another, returning the ratio. /// Divide this angle by another, returning the ratio.
#[inline] fn div_a(&self, other: Self) -> S { *self.s() / *other.s() } #[inline] fn div_a(&self, other: Self) -> Self::Unitless { *self.s() / *other.s() }
/// Take the remainder of this angle with another. /// Take the remainder of this angle with another.
#[inline] fn rem_a(&self, other: Self) -> S { *self.s() % *other.s() } #[inline] fn rem_a(&self, other: Self) -> Self::Unitless { *self.s() % *other.s() }
/// Multiply this angle by a scalar, returning the new angle. /// Multiply this angle by a scalar, returning the new angle.
#[inline] fn mul_s(&self, s: S) -> Self { ScalarConv::from(*self.s() * s) } #[inline] fn mul_s(&self, scalar: Self::Unitless) -> Self { ScalarConv::from(*self.s() * scalar) }
/// Divide this angle by a scalar, returing the new angle. /// Divide this angle by a scalar, returing the new angle.
#[inline] fn div_s(&self, s: S) -> Self { ScalarConv::from(*self.s() / s) } #[inline] fn div_s(&self, scalar: Self::Unitless) -> Self { ScalarConv::from(*self.s() / scalar) }
/// Take the remainder of this angle by a scalar, returning the new angle. /// Take the remainder of this angle by a scalar, returning the new angle.
#[inline] fn rem_s(&self, s: S) -> Self { ScalarConv::from(*self.s() % s) } #[inline] fn rem_s(&self, scalar: Self::Unitless) -> Self { ScalarConv::from(*self.s() % scalar) }
/// Add this angle with another, in-place. /// Add this angle with another, in-place.
#[inline] fn add_self_a(&mut self, other: Self) { *self.mut_s() = *self.s() + *other.s() } #[inline] fn add_self_a(&mut self, other: Self) { *self.mut_s() = *self.s() + *other.s() }
@ -115,11 +115,11 @@ pub trait Angle
#[inline] fn sub_self_a(&mut self, other: Self) { *self.mut_s() = *self.s() - *other.s() } #[inline] fn sub_self_a(&mut self, other: Self) { *self.mut_s() = *self.s() - *other.s() }
/// Multiply this angle by a scalar, in-place. /// Multiply this angle by a scalar, in-place.
#[inline] fn mul_self_s(&mut self, s: S) { *self.mut_s() = *self.s() * s } #[inline] fn mul_self_s(&mut self, scalar: Self::Unitless) { *self.mut_s() = *self.s() * scalar }
/// Divide this angle by a scalar, in-place. /// Divide this angle by a scalar, in-place.
#[inline] fn div_self_s(&mut self, s: S) { *self.mut_s() = *self.s() / s } #[inline] fn div_self_s(&mut self, scalar: Self::Unitless) { *self.mut_s() = *self.s() / scalar }
/// Take the remainder of this angle by a scalar, in-place. /// Take the remainder of this angle by a scalar, in-place.
#[inline] fn rem_self_s(&mut self, s: S) { *self.mut_s() = *self.s() % s } #[inline] fn rem_self_s(&mut self, scalar: Self::Unitless) { *self.mut_s() = *self.s() % scalar }
/// Return the angle, normalized to the range `[0, full_turn)`. /// Return the angle, normalized to the range `[0, full_turn)`.
#[inline] #[inline]
@ -159,7 +159,7 @@ pub trait Angle
#[inline] fn equiv(&self, other: &Self) -> bool { self.normalize() == other.normalize() } #[inline] fn equiv(&self, other: &Self) -> bool { self.normalize() == other.normalize() }
} }
#[inline] pub fn bisect<S: BaseFloat, A: Angle<S>>(a: A, b: A) -> A { a.bisect(b) } #[inline] pub fn bisect<A: Angle>(a: A, b: A) -> A { a.bisect(b) }
impl<R: Into<Rad<S>>, S: BaseFloat> Add<R> for Rad<S> { impl<R: Into<Rad<S>>, S: BaseFloat> Add<R> for Rad<S> {
type Output = Rad<S>; type Output = Rad<S>;
@ -239,15 +239,16 @@ impl<S: BaseFloat> One for Deg<S> {
} }
const PI_2: f64 = f64::consts::PI * 2f64; const PI_2: f64 = f64::consts::PI * 2f64;
impl<S: BaseFloat>
Angle<S> for Rad<S> { impl<S: BaseFloat> Angle for Rad<S> {
#[inline] fn from<A: Angle<S>>(theta: A) -> Rad<S> { theta.into() } type Unitless = S;
#[inline] fn from<A: Angle<Unitless = S>>(theta: A) -> Rad<S> { theta.into() }
#[inline] fn full_turn() -> Rad<S> { rad(cast(PI_2).unwrap()) } #[inline] fn full_turn() -> Rad<S> { rad(cast(PI_2).unwrap()) }
} }
impl<S: BaseFloat> impl<S: BaseFloat> Angle for Deg<S> {
Angle<S> for Deg<S> { type Unitless = S;
#[inline] fn from<A: Angle<S>>(theta: A) -> Deg<S> { theta.into() } #[inline] fn from<A: Angle<Unitless = S>>(theta: A) -> Deg<S> { theta.into() }
#[inline] fn full_turn() -> Deg<S> { deg(cast(360i32).unwrap()) } #[inline] fn full_turn() -> Deg<S> { deg(cast(360i32).unwrap()) }
} }
@ -265,8 +266,7 @@ Angle<S> for Deg<S> {
#[inline] pub fn atan<S: BaseFloat, R: From<Rad<S>>>(s: S) -> R { rad(s.atan()).into() } #[inline] pub fn atan<S: BaseFloat, R: From<Rad<S>>>(s: S) -> R { rad(s.atan()).into() }
#[inline] pub fn atan2<S: BaseFloat, R: From<Rad<S>>>(a: S, b: S) -> R { rad(a.atan2(b)).into() } #[inline] pub fn atan2<S: BaseFloat, R: From<Rad<S>>>(a: S, b: S) -> R { rad(a.atan2(b)).into() }
impl<S: BaseFloat + fmt::Debug> impl<S: BaseFloat + fmt::Debug> fmt::Debug for Rad<S> {
fmt::Debug for Rad<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?} rad", self.s) write!(f, "{:?} rad", self.s)
} }