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