Browse Source

Fix Inv trait, add Pow trait.

Clar Charr 7 years ago
parent
commit
c1f4118b4e
4 changed files with 104 additions and 20 deletions
  1. 1 0
      src/lib.rs
  2. 30 19
      src/ops/inv.rs
  3. 2 1
      src/ops/mod.rs
  4. 71 0
      src/ops/pow.rs

+ 1 - 0
src/lib.rs

@@ -34,6 +34,7 @@ pub use float::FloatConst;
 // pub use real::{FloatCore, Real}; // NOTE: Don't do this, it breaks `use num_traits::*;`.
 pub use identities::{Zero, One, zero, one};
 pub use ops::inv::Inv;
+pub use ops::pow::Pow;
 pub use ops::checked::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, CheckedShl, CheckedShr};
 pub use ops::wrapping::{WrappingAdd, WrappingMul, WrappingSub};
 pub use ops::saturating::Saturating;

+ 30 - 19
src/ops/inv.rs

@@ -3,27 +3,38 @@ pub trait Inv {
     /// The result after applying the operator.
     type Output;
 
-    /// Returns the multiplicative inverse of `Self`.
+    /// Returns the multiplicative inverse of `self`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use num_traits::{Inv, One};
+    ///
+    /// let x = 7.0;
+    /// let y = -0.0;
+    /// assert_eq!(x.inv() * x, One::one());
+    /// assert_eq!(y.inv() * y, One::one());
+    /// ```
     fn inv(self) -> Self::Output;
 }
 
-macro_rules! inv_impl {
-    ($t:ty, $out:ty, $fn:expr) => {
-        impl<'a> Inv for $t {
-            type Output = $out;
-
-            #[inline]
-            fn inv(self) -> $out {
-                ($fn)(self)
-            }
-        }
-    }
+impl Inv for f32 {
+    type Output = f32;
+    #[inline]
+    fn inv(self) -> f32 { 1.0 / self }
 }
-
-#[cfg(feature = "std")]
-mod float_impls {
-    inv_impl!(f32, f32, f32::recip);
-    inv_impl!(f64, f64, f64::recip);
-    inv_impl!(&'a f32, f32, f32::recip);
-    inv_impl!(&'a f64, f64, f64::recip);
+impl Inv for f64 {
+    type Output = f64;
+    #[inline]
+    fn inv(self) -> f64 { 1.0 / self }
+}
+impl<'a> Inv for &'a f32 {
+    type Output = f32;
+    #[inline]
+    fn inv(self) -> f32 { 1.0 / *self }
+}
+impl<'a> Inv for &'a f64 {
+    type Output = f64;
+    #[inline]
+    fn inv(self) -> f64 { 1.0 / *self }
 }

+ 2 - 1
src/ops/mod.rs

@@ -1,4 +1,5 @@
 pub mod saturating;
 pub mod checked;
 pub mod wrapping;
-pub mod new;
+pub mod inv;
+pub mod pow;

+ 71 - 0
src/ops/pow.rs

@@ -0,0 +1,71 @@
+/// Binary operator for raising a value to a power.
+pub trait Pow<RHS> {
+    /// The result after applying the operator.
+    type Output;
+
+    /// Returns `self` to the power `rhs`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use num_traits::Pow;
+    /// assert_eq!(10.pow(2), 100);
+    /// ```
+    fn pow(self, rhs: RHS) -> Self::Output;
+}
+
+macro_rules! pow_impl {
+    ($t:ty, $rhs:ty, $method:ident) => {
+        impl Pow<$rhs> for $t {
+            type Output = $t;
+
+            #[inline]
+            fn pow(self, rhs: $rhs) -> $t {
+                <$t>::$method(self, rhs)
+            }
+        }
+
+        impl<'a> Pow<&'a $rhs> for $t {
+            type Output = $t;
+            #[inline]
+            fn pow(self, rhs: &'a $rhs) -> $t {
+                <$t>::$method(self, *rhs)
+            }
+        }
+
+        impl<'a> Pow<$rhs> for &'a $t {
+            type Output = $t;
+            #[inline]
+            fn pow(self, rhs: $rhs) -> $t {
+                <$t>::$method(*self, rhs)
+            }
+        }
+
+        impl<'a, 'b> Pow<&'a $rhs> for &'b $t {
+            type Output = $t;
+            #[inline]
+            fn pow(self, rhs: &'a $rhs) -> $t {
+                <$t>::$method(*self, *rhs)
+            }
+        }
+    }
+}
+
+pow_impl!(u8, u32, pow);
+pow_impl!(i8, u32, pow);
+pow_impl!(u16, u32, pow);
+pow_impl!(i16, u32, pow);
+pow_impl!(u32, u32, pow);
+pow_impl!(i32, u32, pow);
+pow_impl!(u64, u32, pow);
+pow_impl!(i64, u32, pow);
+pow_impl!(usize, u32, pow);
+pow_impl!(isize, u32, pow);
+
+#[cfg(feature = "std")]
+mod float_impls {
+    pow_impl!(f32, i32, powi);
+    pow_impl!(f64, i32, powi);
+    pow_impl!(f32, f32, powf);
+    pow_impl!(f64, f64, powf);
+}