Move is_power_of_two into unsigned part of signedness_dependent_methods
This commit is contained in:
parent
63256af236
commit
441913626d
@ -750,6 +750,34 @@ pub const fn midpoint(self, rhs: Self) -> Self {
|
||||
// never being 0.
|
||||
unsafe { $Ty::new_unchecked(self.get().midpoint(rhs.get())) }
|
||||
}
|
||||
|
||||
/// Returns `true` if and only if `self == (1 << k)` for some `k`.
|
||||
///
|
||||
/// On many architectures, this function can perform better than `is_power_of_two()`
|
||||
/// on the underlying integer type, as special handling of zero can be avoided.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
#[doc = concat!("let eight = std::num::", stringify!($Ty), "::new(8).unwrap();")]
|
||||
/// assert!(eight.is_power_of_two());
|
||||
#[doc = concat!("let ten = std::num::", stringify!($Ty), "::new(10).unwrap();")]
|
||||
/// assert!(!ten.is_power_of_two());
|
||||
/// ```
|
||||
#[must_use]
|
||||
#[stable(feature = "nonzero_is_power_of_two", since = "1.59.0")]
|
||||
#[rustc_const_stable(feature = "nonzero_is_power_of_two", since = "1.59.0")]
|
||||
#[inline]
|
||||
pub const fn is_power_of_two(self) -> bool {
|
||||
// LLVM 11 normalizes `unchecked_sub(x, 1) & x == 0` to the implementation seen here.
|
||||
// On the basic x86-64 target, this saves 3 instructions for the zero check.
|
||||
// On x86_64 with BMI1, being nonzero lets it codegen to `BLSR`, which saves an instruction
|
||||
// compared to the `POPCNT` implementation on the underlying integer type.
|
||||
|
||||
intrinsics::ctpop(self.get()) < 2
|
||||
}
|
||||
};
|
||||
|
||||
// Methods for signed nonzero types only.
|
||||
@ -1149,46 +1177,6 @@ macro_rules! sign_dependent_expr {
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! nonzero_unsigned_is_power_of_two {
|
||||
( $( $Ty: ident )+ ) => {
|
||||
$(
|
||||
impl $Ty {
|
||||
|
||||
/// Returns `true` if and only if `self == (1 << k)` for some `k`.
|
||||
///
|
||||
/// On many architectures, this function can perform better than `is_power_of_two()`
|
||||
/// on the underlying integer type, as special handling of zero can be avoided.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
#[doc = concat!("let eight = std::num::", stringify!($Ty), "::new(8).unwrap();")]
|
||||
/// assert!(eight.is_power_of_two());
|
||||
#[doc = concat!("let ten = std::num::", stringify!($Ty), "::new(10).unwrap();")]
|
||||
/// assert!(!ten.is_power_of_two());
|
||||
/// ```
|
||||
#[must_use]
|
||||
#[stable(feature = "nonzero_is_power_of_two", since = "1.59.0")]
|
||||
#[rustc_const_stable(feature = "nonzero_is_power_of_two", since = "1.59.0")]
|
||||
#[inline]
|
||||
pub const fn is_power_of_two(self) -> bool {
|
||||
// LLVM 11 normalizes `unchecked_sub(x, 1) & x == 0` to the implementation seen here.
|
||||
// On the basic x86-64 target, this saves 3 instructions for the zero check.
|
||||
// On x86_64 with BMI1, being nonzero lets it codegen to `BLSR`, which saves an instruction
|
||||
// compared to the `POPCNT` implementation on the underlying integer type.
|
||||
|
||||
intrinsics::ctpop(self.get()) < 2
|
||||
}
|
||||
|
||||
}
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
nonzero_unsigned_is_power_of_two! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize }
|
||||
|
||||
macro_rules! nonzero_min_max_unsigned {
|
||||
( $( $Ty: ident($Int: ident); )+ ) => {
|
||||
$(
|
||||
|
Loading…
Reference in New Issue
Block a user