@@ -286,3 +286,43 @@ nonzero_integers_div! {
286
286
NonZeroU128 ( u128 ) ;
287
287
NonZeroUsize ( usize ) ;
288
288
}
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