Skip to content

Commit 4419136

Browse files
committed
Move is_power_of_two into unsigned part of signedness_dependent_methods
1 parent 63256af commit 4419136

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
@@ -750,6 +750,34 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
750750
// never being 0.
751751
unsafe { $Ty::new_unchecked(self.get().midpoint(rhs.get())) }
752752
}
753+
754+
/// Returns `true` if and only if `self == (1 << k)` for some `k`.
755+
///
756+
/// On many architectures, this function can perform better than `is_power_of_two()`
757+
/// on the underlying integer type, as special handling of zero can be avoided.
758+
///
759+
/// # Examples
760+
///
761+
/// Basic usage:
762+
///
763+
/// ```
764+
#[doc = concat!("let eight = std::num::", stringify!($Ty), "::new(8).unwrap();")]
765+
/// assert!(eight.is_power_of_two());
766+
#[doc = concat!("let ten = std::num::", stringify!($Ty), "::new(10).unwrap();")]
767+
/// assert!(!ten.is_power_of_two());
768+
/// ```
769+
#[must_use]
770+
#[stable(feature = "nonzero_is_power_of_two", since = "1.59.0")]
771+
#[rustc_const_stable(feature = "nonzero_is_power_of_two", since = "1.59.0")]
772+
#[inline]
773+
pub const fn is_power_of_two(self) -> bool {
774+
// LLVM 11 normalizes `unchecked_sub(x, 1) & x == 0` to the implementation seen here.
775+
// On the basic x86-64 target, this saves 3 instructions for the zero check.
776+
// On x86_64 with BMI1, being nonzero lets it codegen to `BLSR`, which saves an instruction
777+
// compared to the `POPCNT` implementation on the underlying integer type.
778+
779+
intrinsics::ctpop(self.get()) < 2
780+
}
753781
};
754782

755783
// Methods for signed nonzero types only.
@@ -1149,46 +1177,6 @@ macro_rules! sign_dependent_expr {
11491177
};
11501178
}
11511179

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

0 commit comments

Comments
 (0)