Skip to content

Commit 0ae539f

Browse files
committed
Move is_power_of_two into unsigned part of signedness_dependent_methods
1 parent bfc6d0f commit 0ae539f

File tree

1 file changed

+28
-40
lines changed

1 file changed

+28
-40
lines changed

library/core/src/num/nonzero.rs

Lines changed: 28 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,34 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
736736
// never being 0.
737737
unsafe { $Ty::new_unchecked(self.get().midpoint(rhs.get())) }
738738
}
739+
740+
/// Returns `true` if and only if `self == (1 << k)` for some `k`.
741+
///
742+
/// On many architectures, this function can perform better than `is_power_of_two()`
743+
/// on the underlying integer type, as special handling of zero can be avoided.
744+
///
745+
/// # Examples
746+
///
747+
/// Basic usage:
748+
///
749+
/// ```
750+
#[doc = concat!("let eight = std::num::", stringify!($Ty), "::new(8).unwrap();")]
751+
/// assert!(eight.is_power_of_two());
752+
#[doc = concat!("let ten = std::num::", stringify!($Ty), "::new(10).unwrap();")]
753+
/// assert!(!ten.is_power_of_two());
754+
/// ```
755+
#[must_use]
756+
#[stable(feature = "nonzero_is_power_of_two", since = "1.59.0")]
757+
#[rustc_const_stable(feature = "nonzero_is_power_of_two", since = "1.59.0")]
758+
#[inline]
759+
pub const fn is_power_of_two(self) -> bool {
760+
// LLVM 11 normalizes `unchecked_sub(x, 1) & x == 0` to the implementation seen here.
761+
// On the basic x86-64 target, this saves 3 instructions for the zero check.
762+
// On x86_64 with BMI1, being nonzero lets it codegen to `BLSR`, which saves an instruction
763+
// compared to the `POPCNT` implementation on the underlying integer type.
764+
765+
intrinsics::ctpop(self.get()) < 2
766+
}
739767
};
740768

741769
// Methods for signed nonzero types only.
@@ -1135,46 +1163,6 @@ macro_rules! sign_dependent_expr {
11351163
};
11361164
}
11371165

1138-
macro_rules! nonzero_unsigned_is_power_of_two {
1139-
( $( $Ty: ident )+ ) => {
1140-
$(
1141-
impl $Ty {
1142-
1143-
/// Returns `true` if and only if `self == (1 << k)` for some `k`.
1144-
///
1145-
/// On many architectures, this function can perform better than `is_power_of_two()`
1146-
/// on the underlying integer type, as special handling of zero can be avoided.
1147-
///
1148-
/// # Examples
1149-
///
1150-
/// Basic usage:
1151-
///
1152-
/// ```
1153-
#[doc = concat!("let eight = std::num::", stringify!($Ty), "::new(8).unwrap();")]
1154-
/// assert!(eight.is_power_of_two());
1155-
#[doc = concat!("let ten = std::num::", stringify!($Ty), "::new(10).unwrap();")]
1156-
/// assert!(!ten.is_power_of_two());
1157-
/// ```
1158-
#[must_use]
1159-
#[stable(feature = "nonzero_is_power_of_two", since = "1.59.0")]
1160-
#[rustc_const_stable(feature = "nonzero_is_power_of_two", since = "1.59.0")]
1161-
#[inline]
1162-
pub const fn is_power_of_two(self) -> bool {
1163-
// LLVM 11 normalizes `unchecked_sub(x, 1) & x == 0` to the implementation seen here.
1164-
// On the basic x86-64 target, this saves 3 instructions for the zero check.
1165-
// On x86_64 with BMI1, being nonzero lets it codegen to `BLSR`, which saves an instruction
1166-
// compared to the `POPCNT` implementation on the underlying integer type.
1167-
1168-
intrinsics::ctpop(self.get()) < 2
1169-
}
1170-
1171-
}
1172-
)+
1173-
}
1174-
}
1175-
1176-
nonzero_unsigned_is_power_of_two! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize }
1177-
11781166
macro_rules! nonzero_min_max_unsigned {
11791167
( $( $Ty: ident($Int: ident); )+ ) => {
11801168
$(

0 commit comments

Comments
 (0)