@@ -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-
11921180macro_rules! nonzero_min_max_unsigned {
11931181 ( $( $Ty: ident( $Int: ident) ; ) + ) => {
11941182 $(
0 commit comments