summaryrefslogtreecommitdiffstats
path: root/library/core/src/num/int_macros.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/core/src/num/int_macros.rs')
-rw-r--r--library/core/src/num/int_macros.rs80
1 files changed, 55 insertions, 25 deletions
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 2cae98b8e..aec15212d 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -1,11 +1,31 @@
macro_rules! int_impl {
- ($SelfT:ty, $ActualT:ident, $UnsignedT:ty, $BITS:expr, $BITS_MINUS_ONE:expr, $Min:expr, $Max:expr,
- $rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr,
- $reversed:expr, $le_bytes:expr, $be_bytes:expr,
- $to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr,
- $bound_condition:expr) => {
+ (
+ Self = $SelfT:ty,
+ ActualT = $ActualT:ident,
+ UnsignedT = $UnsignedT:ty,
+
+ // There are all for use *only* in doc comments.
+ // As such, they're all passed as literals -- passing them as a string
+ // literal is fine if they need to be multiple code tokens.
+ // In non-comments, use the associated constants rather than these.
+ BITS = $BITS:literal,
+ BITS_MINUS_ONE = $BITS_MINUS_ONE:literal,
+ Min = $Min:literal,
+ Max = $Max:literal,
+ rot = $rot:literal,
+ rot_op = $rot_op:literal,
+ rot_result = $rot_result:literal,
+ swap_op = $swap_op:literal,
+ swapped = $swapped:literal,
+ reversed = $reversed:literal,
+ le_bytes = $le_bytes:literal,
+ be_bytes = $be_bytes:literal,
+ to_xe_bytes_doc = $to_xe_bytes_doc:expr,
+ from_xe_bytes_doc = $from_xe_bytes_doc:expr,
+ bound_condition = $bound_condition:literal,
+ ) => {
/// The smallest value that can be represented by this integer type
- #[doc = concat!("(&minus;2<sup>", $BITS_MINUS_ONE, "</sup>", $bound_condition, ")")]
+ #[doc = concat!("(&minus;2<sup>", $BITS_MINUS_ONE, "</sup>", $bound_condition, ").")]
///
/// # Examples
///
@@ -15,10 +35,10 @@ macro_rules! int_impl {
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN, ", stringify!($Min), ");")]
/// ```
#[stable(feature = "assoc_int_consts", since = "1.43.0")]
- pub const MIN: Self = !0 ^ ((!0 as $UnsignedT) >> 1) as Self;
+ pub const MIN: Self = !Self::MAX;
/// The largest value that can be represented by this integer type
- #[doc = concat!("(2<sup>", $BITS_MINUS_ONE, "</sup> &minus; 1", $bound_condition, ")")]
+ #[doc = concat!("(2<sup>", $BITS_MINUS_ONE, "</sup> &minus; 1", $bound_condition, ").")]
///
/// # Examples
///
@@ -28,7 +48,7 @@ macro_rules! int_impl {
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX, ", stringify!($Max), ");")]
/// ```
#[stable(feature = "assoc_int_consts", since = "1.43.0")]
- pub const MAX: Self = !Self::MIN;
+ pub const MAX: Self = (<$UnsignedT>::MAX >> 1) as Self;
/// The size of this integer type in bits.
///
@@ -38,7 +58,7 @@ macro_rules! int_impl {
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::BITS, ", stringify!($BITS), ");")]
/// ```
#[stable(feature = "int_bits_const", since = "1.53.0")]
- pub const BITS: u32 = $BITS;
+ pub const BITS: u32 = <$UnsignedT>::BITS;
/// Converts a string slice in a given base to an integer.
///
@@ -1365,7 +1385,7 @@ macro_rules! int_impl {
// SAFETY: the masking by the bitsize of the type ensures that we do not shift
// out of bounds
unsafe {
- self.unchecked_shl(rhs & ($BITS - 1))
+ self.unchecked_shl(rhs & (Self::BITS - 1))
}
}
@@ -1395,7 +1415,7 @@ macro_rules! int_impl {
// SAFETY: the masking by the bitsize of the type ensures that we do not shift
// out of bounds
unsafe {
- self.unchecked_shr(rhs & ($BITS - 1))
+ self.unchecked_shr(rhs & (Self::BITS - 1))
}
}
@@ -1901,7 +1921,7 @@ macro_rules! int_impl {
without modifying the original"]
#[inline]
pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
- (self.wrapping_shl(rhs), (rhs > ($BITS - 1)))
+ (self.wrapping_shl(rhs), rhs >= Self::BITS)
}
/// Shifts self right by `rhs` bits.
@@ -1924,7 +1944,7 @@ macro_rules! int_impl {
without modifying the original"]
#[inline]
pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
- (self.wrapping_shr(rhs), (rhs > ($BITS - 1)))
+ (self.wrapping_shr(rhs), rhs >= Self::BITS)
}
/// Computes the absolute value of `self`.
@@ -2331,14 +2351,17 @@ macro_rules! int_impl {
/// ```
#[stable(feature = "int_log", since = "1.67.0")]
#[rustc_const_stable(feature = "int_log", since = "1.67.0")]
- #[rustc_allow_const_fn_unstable(const_option)]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
#[track_caller]
pub const fn ilog(self, base: Self) -> u32 {
assert!(base >= 2, "base of integer logarithm must be at least 2");
- self.checked_ilog(base).expect("argument of integer logarithm must be positive")
+ if let Some(log) = self.checked_ilog(base) {
+ log
+ } else {
+ int_log10::panic_for_nonpositive_argument()
+ }
}
/// Returns the base 2 logarithm of the number, rounded down.
@@ -2354,13 +2377,16 @@ macro_rules! int_impl {
/// ```
#[stable(feature = "int_log", since = "1.67.0")]
#[rustc_const_stable(feature = "int_log", since = "1.67.0")]
- #[rustc_allow_const_fn_unstable(const_option)]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
#[track_caller]
pub const fn ilog2(self) -> u32 {
- self.checked_ilog2().expect("argument of integer logarithm must be positive")
+ if let Some(log) = self.checked_ilog2() {
+ log
+ } else {
+ int_log10::panic_for_nonpositive_argument()
+ }
}
/// Returns the base 10 logarithm of the number, rounded down.
@@ -2376,13 +2402,16 @@ macro_rules! int_impl {
/// ```
#[stable(feature = "int_log", since = "1.67.0")]
#[rustc_const_stable(feature = "int_log", since = "1.67.0")]
- #[rustc_allow_const_fn_unstable(const_option)]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
#[track_caller]
pub const fn ilog10(self) -> u32 {
- self.checked_ilog10().expect("argument of integer logarithm must be positive")
+ if let Some(log) = self.checked_ilog10() {
+ log
+ } else {
+ int_log10::panic_for_nonpositive_argument()
+ }
}
/// Returns the logarithm of the number with respect to an arbitrary base,
@@ -2574,12 +2603,13 @@ macro_rules! int_impl {
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
+ #[rustc_allow_const_fn_unstable(const_cmp)]
pub const fn signum(self) -> Self {
- match self {
- n if n > 0 => 1,
- 0 => 0,
- _ => -1,
- }
+ // Picking the right way to phrase this is complicated
+ // (<https://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign>)
+ // so delegate it to `Ord` which is already producing -1/0/+1
+ // exactly like we need and can be the place to deal with the complexity.
+ self.cmp(&0) as _
}
/// Returns `true` if `self` is positive and `false` if the number is zero or