@@ -286,3 +286,43 @@ nonzero_integers_div! {
286286 NonZeroU128 ( u128 ) ;
287287 NonZeroUsize ( usize ) ;
288288}
289+
290+ macro_rules! nonzero_unsigned_is_power_of_two {
291+ ( $( $Ty: ident ) + ) => {
292+ $(
293+ impl $Ty {
294+
295+ /// Returns `true` if and only if `self == (1 << k)` for some `k`.
296+ ///
297+ /// On many architectures, this function can perform better than `is_power_of_two()`
298+ /// on the underlying integer type, as special handling of zero can be avoided.
299+ ///
300+ /// # Examples
301+ ///
302+ /// Basic usage:
303+ ///
304+ /// ```
305+ /// #![feature(nonzero_is_power_of_two)]
306+ ///
307+ #[ doc = concat!( "let eight = std::num::" , stringify!( $Ty) , "::new(8).unwrap();" ) ]
308+ /// assert!(eight.is_power_of_two());
309+ #[ doc = concat!( "let ten = std::num::" , stringify!( $Ty) , "::new(10).unwrap();" ) ]
310+ /// assert!(!ten.is_power_of_two());
311+ /// ```
312+ #[ unstable( feature = "nonzero_is_power_of_two" , issue = "81106" ) ]
313+ #[ inline]
314+ pub const fn is_power_of_two( self ) -> bool {
315+ // LLVM 11 normalizes `unchecked_sub(x, 1) & x == 0` to the implementation seen here.
316+ // On the basic x86-64 target, this saves 3 instructions for the zero check.
317+ // On x86_64 with BMI1, being nonzero lets it codegen to `BLSR`, which saves an instruction
318+ // compared to the `POPCNT` implementation on the underlying integer type.
319+
320+ intrinsics:: ctpop( self . get( ) ) < 2
321+ }
322+
323+ }
324+ ) +
325+ }
326+ }
327+
328+ nonzero_unsigned_is_power_of_two ! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize }
0 commit comments