Rollup merge of #148797 - sorairolake:feature/non-zero-uint-bit-width, r=scottmcm

feat: Add `bit_width` for unsigned `NonZero<T>`

- Tracking issue: rust-lang/rust#142326

This pull request adds a method to the unsigned `NonZero<T>` that return the minimum number of bits required to represent a value.

This can be achieved by using the `get` method and the methods added in rust-lang/rust#142328, but I think adding the `NonZero::bit_width` method is useful because it accomplishes the same thing a little more succinctly.
This commit is contained in:
Matthias Krüger 2025-11-19 09:48:09 +01:00 committed by GitHub
commit 8b7479003b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 45 additions and 0 deletions

View file

@ -1781,6 +1781,33 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
// SAFETY: `self.get()` can't be zero
unsafe { NonZero::new_unchecked(self.get().cast_signed()) }
}
/// Returns the minimum number of bits required to represent `self`.
///
/// # Examples
///
/// ```
/// #![feature(uint_bit_width)]
///
/// # use core::num::NonZero;
/// #
/// # fn main() { test().unwrap(); }
/// # fn test() -> Option<()> {
#[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::MIN.bit_width(), NonZero::new(1)?);")]
#[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::new(0b111)?.bit_width(), NonZero::new(3)?);")]
#[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::new(0b1110)?.bit_width(), NonZero::new(4)?);")]
/// # Some(())
/// # }
/// ```
#[unstable(feature = "uint_bit_width", issue = "142326")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
pub const fn bit_width(self) -> NonZero<u32> {
// SAFETY: Since `self.leading_zeros()` is always less than
// `Self::BITS`, this subtraction can never be zero.
unsafe { NonZero::new_unchecked(Self::BITS - self.leading_zeros()) }
}
};
// Associated items for signed nonzero types only.

View file

@ -570,3 +570,21 @@ fn test_nonzero_lowest_one() {
nonzero_int_impl!(i8, i16, i32, i64, i128, isize);
nonzero_uint_impl!(u8, u16, u32, u64, u128, usize);
}
#[test]
fn test_nonzero_bit_width() {
macro_rules! nonzero_uint_impl {
($($T:ty),+) => {
$(
{
assert_eq!(NonZero::<$T>::new(0b010_1100).unwrap().bit_width(), NonZero::new(6).unwrap());
assert_eq!(NonZero::<$T>::new(0b111_1001).unwrap().bit_width(), NonZero::new(7).unwrap());
assert_eq!(NonZero::<$T>::MIN.bit_width(), NonZero::new(1).unwrap());
assert_eq!(NonZero::<$T>::MAX.bit_width(), NonZero::new(<$T>::BITS).unwrap());
}
)+
};
}
nonzero_uint_impl!(u8, u16, u32, u64, u128, usize);
}