about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/core/src/num/int_macros.rs60
-rw-r--r--library/core/src/num/uint_macros.rs54
2 files changed, 114 insertions, 0 deletions
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 17cf2a7b261..0ec178448e4 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -1312,6 +1312,33 @@ macro_rules! int_impl {
             }
         }
 
+        /// Unbounded shift left. Computes `self << rhs`, without bounding the value of `rhs`
+        /// 
+        /// If `rhs` is larger or equal to the number of bits in `self`, 
+        /// the entire value is shifted out, and `0` is returned.
+        ///
+        /// # Examples
+        /// 
+        /// Basic usage:
+        /// ```
+        #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(4), 0x10);")]
+        #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(129), 0);")]
+        /// ```
+        #[unstable(feature = "unbounded_shifts", issue = "129375")]
+        #[rustc_allow_const_fn_unstable(unchecked_shifts)]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn unbounded_shl(self, v: u32) -> $SelfT{
+            if v < Self::BITS{
+                // SAFETY:
+                // v is just checked to be in-range above
+                unsafe{self.unchecked_shl(v)}
+            }else{
+                0
+            }
+        }
+
         /// Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is
         /// larger than or equal to the number of bits in `self`.
         ///
@@ -1410,6 +1437,39 @@ macro_rules! int_impl {
             }
         }
 
+        /// Unbounded shift right. Computes `self >> rhs`, without bounding the value of `rhs`
+        /// 
+        /// If `rhs` is larger or equal to the number of bits in `self`, 
+        /// the entire value is shifted out, which yields `0` for a positive number,
+        /// and `-1` for a negative number.
+        ///
+        /// # Examples
+        /// 
+        /// Basic usage:
+        /// ```
+        #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shl(4), 0x1);")]
+        #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(129), 0);")]
+        #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.unbounded_shr(129), -1);")]
+        /// ```
+        #[unstable(feature = "unbounded_shifts", issue = "129375")]
+        #[rustc_allow_const_fn_unstable(unchecked_shifts)]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn unbounded_shr(self, v: u32) -> $SelfT{
+            if v < Self::BITS{
+                // SAFETY:
+                // v is just checked to be in-range above
+                unsafe{self.unchecked_shr(v)}
+            }else{
+                // A shift by `Self::BITS-1` suffices for signed integers, because the sign bit is copied for each of the shifted bits.
+
+                // SAFETY:
+                // `Self::BITS-1` is guaranteed to be less than `Self::BITS`
+                unsafe{self.unchecked_shr(Self::BITS - 1)}
+            }
+        }
+
         /// Checked absolute value. Computes `self.abs()`, returning `None` if
         /// `self == MIN`.
         ///
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 719a6a55940..5a2f1876ca2 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -1501,6 +1501,33 @@ macro_rules! uint_impl {
             }
         }
 
+                /// Unbounded shift left. Computes `self << rhs`, without bounding the value of `rhs`
+        /// 
+        /// If `rhs` is larger or equal to the number of bits in `self`, 
+        /// the entire value is shifted out, and `0` is returned.
+        ///
+        /// # Examples
+        /// 
+        /// Basic usage:
+        /// ```
+        #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(4), 0x10);")]
+        #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(129), 0);")]
+        /// ```
+        #[unstable(feature = "unbounded_shifts", issue = "129375")]
+        #[rustc_allow_const_fn_unstable(unchecked_shifts)]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn unbounded_shl(self, v: u32) -> $SelfT{
+            if v < Self::BITS{
+                // SAFETY:
+                // v is just checked to be in-range above
+                unsafe{self.unchecked_shl(v)}
+            }else{
+                0
+            }
+        }
+
         /// Checked shift right. Computes `self >> rhs`, returning `None`
         /// if `rhs` is larger than or equal to the number of bits in `self`.
         ///
@@ -1599,6 +1626,33 @@ macro_rules! uint_impl {
             }
         }
 
+        /// Unbounded shift right. Computes `self >> rhs`, without bounding the value of `rhs`
+        /// 
+        /// If `rhs` is larger or equal to the number of bits in `self`, 
+        /// the entire value is shifted out, and `0` is returned.
+        ///
+        /// # Examples
+        /// 
+        /// Basic usage:
+        /// ```
+        #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(4), 0x10);")]
+        #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(129), 0);")]
+        /// ```
+        #[unstable(feature = "unbounded_shifts", issue = "129375")]
+        #[rustc_allow_const_fn_unstable(unchecked_shifts)]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn unbounded_shr(self, v: u32) -> $SelfT{
+            if v < Self::BITS{
+                // SAFETY:
+                // v is just checked to be in-range above
+                unsafe{self.unchecked_shr(v)}
+            }else{
+                0
+            }
+        }
+
         /// Checked exponentiation. Computes `self.pow(exp)`, returning `None` if
         /// overflow occurred.
         ///