]> git.lizzy.rs Git - rust.git/blobdiff - src/libcore/num/mod.rs
Merge branch 'refactor-select' of https://github.com/aravind-pg/rust into update...
[rust.git] / src / libcore / num / mod.rs
index 43330b63f9b9c4e9338bad4ac098a3c9e18a07ea..a46ac2b5f0fee1d9af082f160b6c84218592e763 100644 (file)
@@ -321,6 +321,33 @@ pub fn swap_bytes(self) -> Self {
             (self as $UnsignedT).swap_bytes() as Self
         }
 
+        /// Reverses the bit pattern of the integer.
+        ///
+        /// # Examples
+        ///
+        /// Please note that this example is shared between integer types.
+        /// Which explains why `i16` is used here.
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(reverse_bits)]
+        ///
+        /// let n: i16 = 0b0000000_01010101;
+        /// assert_eq!(n, 85);
+        ///
+        /// let m = n.reverse_bits();
+        ///
+        /// assert_eq!(m as u16, 0b10101010_00000000);
+        /// assert_eq!(m, -22016);
+        /// ```
+        #[unstable(feature = "reverse_bits", issue = "48763")]
+        #[cfg(not(stage0))]
+        #[inline]
+        pub fn reverse_bits(self) -> Self {
+            (self as $UnsignedT).reverse_bits() as Self
+        }
+
         doc_comment! {
             concat!("Converts an integer from big endian to the target's endianness.
 
@@ -634,6 +661,46 @@ pub fn checked_abs(self) -> Option<Self> {
             }
         }
 
+        doc_comment! {
+            concat!("Checked exponentiation. Computes `self.pow(exp)`, returning `None` if
+overflow occurred.
+
+# Examples
+
+Basic usage:
+
+```
+#![feature(no_panic_pow)]
+", $Feature, "assert_eq!(8", stringify!($SelfT), ".checked_pow(2), Some(64));
+assert_eq!(", stringify!($SelfT), "::max_value().checked_pow(2), None);",
+$EndFeature, "
+```"),
+
+            #[unstable(feature = "no_panic_pow", issue = "48320")]
+            #[inline]
+            pub fn checked_pow(self, mut exp: u32) -> Option<Self> {
+                let mut base = self;
+                let mut acc: Self = 1;
+
+                while exp > 1 {
+                    if (exp & 1) == 1 {
+                        acc = acc.checked_mul(base)?;
+                    }
+                    exp /= 2;
+                    base = base.checked_mul(base)?;
+                }
+
+                // Deal with the final bit of the exponent separately, since
+                // squaring the base afterwards is not necessary and may cause a
+                // needless overflow.
+                if exp == 1 {
+                    acc = acc.checked_mul(base)?;
+                }
+
+                Some(acc)
+            }
+        }
+
         doc_comment! {
             concat!("Saturating integer addition. Computes `self + rhs`, saturating at the numeric
 bounds instead of overflowing.
@@ -713,6 +780,34 @@ pub fn saturating_mul(self, rhs: Self) -> Self {
             }
         }
 
+        doc_comment! {
+            concat!("Saturating integer exponentiation. Computes `self.pow(exp)`,
+saturating at the numeric bounds instead of overflowing.
+
+# Examples
+
+Basic usage:
+
+```
+#![feature(no_panic_pow)]
+", $Feature, "use std::", stringify!($SelfT), ";
+
+assert_eq!((-4", stringify!($SelfT), ").saturating_pow(3), -64);
+assert_eq!(", stringify!($SelfT), "::MIN.saturating_pow(2), ", stringify!($SelfT), "::MAX);
+assert_eq!(", stringify!($SelfT), "::MIN.saturating_pow(3), ", stringify!($SelfT), "::MIN);",
+$EndFeature, "
+```"),
+            #[unstable(feature = "no_panic_pow", issue = "48320")]
+            #[inline]
+            pub fn saturating_pow(self, exp: u32) -> Self {
+                match self.checked_pow(exp) {
+                    Some(x) => x,
+                    None if self < 0 && exp % 2 == 1 => Self::min_value(),
+                    None => Self::max_value(),
+                }
+            }
+        }
+
         doc_comment! {
             concat!("Wrapping (modular) addition. Computes `self + rhs`, wrapping around at the
 boundary of the type.
@@ -947,6 +1042,46 @@ pub fn wrapping_abs(self) -> Self {
             }
         }
 
+        doc_comment! {
+            concat!("Wrapping (modular) exponentiation. Computes `self.pow(exp)`,
+wrapping around at the boundary of the type.
+
+# Examples
+
+Basic usage:
+
+```
+#![feature(no_panic_pow)]
+", $Feature, "assert_eq!(3", stringify!($SelfT), ".wrapping_pow(4), 81);
+assert_eq!(3i8.wrapping_pow(5), -13);
+assert_eq!(3i8.wrapping_pow(6), -39);",
+$EndFeature, "
+```"),
+            #[unstable(feature = "no_panic_pow", issue = "48320")]
+            #[inline]
+            pub fn wrapping_pow(self, mut exp: u32) -> Self {
+                let mut base = self;
+                let mut acc: Self = 1;
+
+                while exp > 1 {
+                    if (exp & 1) == 1 {
+                        acc = acc.wrapping_mul(base);
+                    }
+                    exp /= 2;
+                    base = base.wrapping_mul(base);
+                }
+
+                // Deal with the final bit of the exponent separately, since
+                // squaring the base afterwards is not necessary and may cause a
+                // needless overflow.
+                if exp == 1 {
+                    acc = acc.wrapping_mul(base);
+                }
+
+                acc
+            }
+        }
+
         doc_comment! {
             concat!("Calculates `self` + `rhs`
 
@@ -1202,6 +1337,56 @@ pub fn overflowing_abs(self) -> (Self, bool) {
         doc_comment! {
             concat!("Raises self to the power of `exp`, using exponentiation by squaring.
 
+Returns a tuple of the exponentiation along with a bool indicating
+whether an overflow happened.
+
+# Examples
+
+Basic usage:
+
+```
+#![feature(no_panic_pow)]
+", $Feature, "assert_eq!(3", stringify!($SelfT), ".overflowing_pow(4), (81, false));
+assert_eq!(3i8.overflowing_pow(5), (-13, true));",
+$EndFeature, "
+```"),
+            #[unstable(feature = "no_panic_pow", issue = "48320")]
+            #[inline]
+            pub fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
+                let mut base = self;
+                let mut acc: Self = 1;
+                let mut overflown = false;
+                // Scratch space for storing results of overflowing_mul.
+                let mut r;
+
+                while exp > 1 {
+                    if (exp & 1) == 1 {
+                        r = acc.overflowing_mul(base);
+                        acc = r.0;
+                        overflown |= r.1;
+                    }
+                    exp /= 2;
+                    r = base.overflowing_mul(base);
+                    base = r.0;
+                    overflown |= r.1;
+                }
+
+                // Deal with the final bit of the exponent separately, since
+                // squaring the base afterwards is not necessary and may cause a
+                // needless overflow.
+                if exp == 1 {
+                    r = acc.overflowing_mul(base);
+                    acc = r.0;
+                    overflown |= r.1;
+                }
+
+                (acc, overflown)
+            }
+        }
+
+        doc_comment! {
+            concat!("Raises self to the power of `exp`, using exponentiation by squaring.
+
 # Examples
 
 Basic usage:
@@ -1615,6 +1800,33 @@ pub fn swap_bytes(self) -> Self {
             unsafe { intrinsics::bswap(self as $ActualT) as Self }
         }
 
+        /// Reverses the bit pattern of the integer.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// Please note that this example is shared between integer types.
+        /// Which explains why `u16` is used here.
+        ///
+        /// ```
+        /// #![feature(reverse_bits)]
+        ///
+        /// let n: u16 = 0b0000000_01010101;
+        /// assert_eq!(n, 85);
+        ///
+        /// let m = n.reverse_bits();
+        ///
+        /// assert_eq!(m, 0b10101010_00000000);
+        /// assert_eq!(m, 43520);
+        /// ```
+        #[unstable(feature = "reverse_bits", issue = "48763")]
+        #[cfg(not(stage0))]
+        #[inline]
+        pub fn reverse_bits(self) -> Self {
+            unsafe { intrinsics::bitreverse(self as $ActualT) as Self }
+        }
+
         doc_comment! {
             concat!("Converts an integer from big endian to the target's endianness.
 
@@ -1887,6 +2099,44 @@ pub fn checked_shr(self, rhs: u32) -> Option<Self> {
             }
         }
 
+        doc_comment! {
+            concat!("Checked exponentiation. Computes `self.pow(exp)`, returning `None` if
+overflow occurred.
+
+# Examples
+
+Basic usage:
+
+```
+#![feature(no_panic_pow)]
+", $Feature, "assert_eq!(2", stringify!($SelfT), ".checked_pow(5), Some(32));
+assert_eq!(", stringify!($SelfT), "::max_value().checked_pow(2), None);", $EndFeature, "
+```"),
+            #[unstable(feature = "no_panic_pow", issue = "48320")]
+            #[inline]
+            pub fn checked_pow(self, mut exp: u32) -> Option<Self> {
+                let mut base = self;
+                let mut acc: Self = 1;
+
+                while exp > 1 {
+                    if (exp & 1) == 1 {
+                        acc = acc.checked_mul(base)?;
+                    }
+                    exp /= 2;
+                    base = base.checked_mul(base)?;
+                }
+
+                // Deal with the final bit of the exponent separately, since
+                // squaring the base afterwards is not necessary and may cause a
+                // needless overflow.
+                if exp == 1 {
+                    acc = acc.checked_mul(base)?;
+                }
+
+                Some(acc)
+            }
+        }
+
         doc_comment! {
             concat!("Saturating integer addition. Computes `self + rhs`, saturating at
 the numeric bounds instead of overflowing.
@@ -1953,6 +2203,32 @@ pub fn saturating_mul(self, rhs: Self) -> Self {
             }
         }
 
+        doc_comment! {
+            concat!("Saturating integer exponentiation. Computes `self.pow(exp)`,
+saturating at the numeric bounds instead of overflowing.
+
+# Examples
+
+Basic usage:
+
+```
+#![feature(no_panic_pow)]
+", $Feature, "use std::", stringify!($SelfT), ";
+
+assert_eq!(4", stringify!($SelfT), ".saturating_pow(3), 64);
+assert_eq!(", stringify!($SelfT), "::MAX.saturating_pow(2), ", stringify!($SelfT), "::MAX);",
+$EndFeature, "
+```"),
+            #[unstable(feature = "no_panic_pow", issue = "48320")]
+            #[inline]
+            pub fn saturating_pow(self, exp: u32) -> Self {
+                match self.checked_pow(exp) {
+                    Some(x) => x,
+                    None => Self::max_value(),
+                }
+            }
+        }
+
         doc_comment! {
             concat!("Wrapping (modular) addition. Computes `self + rhs`,
 wrapping around at the boundary of the type.
@@ -2147,6 +2423,44 @@ pub fn wrapping_shr(self, rhs: u32) -> Self {
             }
         }
 
+        doc_comment! {
+            concat!("Wrapping (modular) exponentiation. Computes `self.pow(exp)`,
+wrapping around at the boundary of the type.
+
+# Examples
+
+Basic usage:
+
+```
+#![feature(no_panic_pow)]
+", $Feature, "assert_eq!(3", stringify!($SelfT), ".wrapping_pow(5), 243);
+assert_eq!(3u8.wrapping_pow(6), 217);", $EndFeature, "
+```"),
+            #[unstable(feature = "no_panic_pow", issue = "48320")]
+            #[inline]
+            pub fn wrapping_pow(self, mut exp: u32) -> Self {
+                let mut base = self;
+                let mut acc: Self = 1;
+
+                while exp > 1 {
+                    if (exp & 1) == 1 {
+                        acc = acc.wrapping_mul(base);
+                    }
+                    exp /= 2;
+                    base = base.wrapping_mul(base);
+                }
+
+                // Deal with the final bit of the exponent separately, since
+                // squaring the base afterwards is not necessary and may cause a
+                // needless overflow.
+                if exp == 1 {
+                    acc = acc.wrapping_mul(base);
+                }
+
+                acc
+            }
+        }
+
         doc_comment! {
             concat!("Calculates `self` + `rhs`
 
@@ -2353,7 +2667,55 @@ pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
             pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
                 (self.wrapping_shr(rhs), (rhs > ($BITS - 1)))
             }
+        }
+
+        doc_comment! {
+            concat!("Raises self to the power of `exp`, using exponentiation by squaring.
+
+Returns a tuple of the exponentiation along with a bool indicating
+whether an overflow happened.
+
+# Examples
+
+Basic usage:
+
+```
+#![feature(no_panic_pow)]
+", $Feature, "assert_eq!(3", stringify!($SelfT), ".overflowing_pow(5), (243, false));
+assert_eq!(3u8.overflowing_pow(6), (217, true));", $EndFeature, "
+```"),
+            #[unstable(feature = "no_panic_pow", issue = "48320")]
+            #[inline]
+            pub fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
+                let mut base = self;
+                let mut acc: Self = 1;
+                let mut overflown = false;
+                // Scratch space for storing results of overflowing_mul.
+                let mut r;
+
+                while exp > 1 {
+                    if (exp & 1) == 1 {
+                        r = acc.overflowing_mul(base);
+                        acc = r.0;
+                        overflown |= r.1;
+                    }
+                    exp /= 2;
+                    r = base.overflowing_mul(base);
+                    base = r.0;
+                    overflown |= r.1;
+                }
 
+                // Deal with the final bit of the exponent separately, since
+                // squaring the base afterwards is not necessary and may cause a
+                // needless overflow.
+                if exp == 1 {
+                    r = acc.overflowing_mul(base);
+                    acc = r.0;
+                    overflown |= r.1;
+                }
+
+                (acc, overflown)
+            }
         }
 
         doc_comment! {
@@ -2892,7 +3254,7 @@ pub fn is_ascii_punctuation(&self) -> bool {
     }
 
     /// Checks if the value is an ASCII graphic character:
-    /// U+0021 '@' ... U+007E '~'.
+    /// U+0021 '!' ... U+007E '~'.
     ///
     /// # Examples
     ///