Skip to content

Commit

Permalink
feat(core): Add implementations for unbounded_shl/unbounded_shr
Browse files Browse the repository at this point in the history
  • Loading branch information
chorman0773 committed Aug 21, 2024
1 parent d37ebfe commit 700af56
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 0 deletions.
60 changes: 60 additions & 0 deletions core/src/num/int_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
///
Expand Down Expand Up @@ -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`.
///
Expand Down
54 changes: 54 additions & 0 deletions core/src/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
///
Expand Down Expand Up @@ -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.
///
Expand Down

0 comments on commit 700af56

Please sign in to comment.