Skip to content

Commit 8b74790

Browse files
authored
Rollup merge of #148797 - sorairolake:feature/non-zero-uint-bit-width, r=scottmcm
feat: Add `bit_width` for unsigned `NonZero<T>` - Tracking issue: #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 #142328, but I think adding the `NonZero::bit_width` method is useful because it accomplishes the same thing a little more succinctly.
2 parents 3732c3c + a25950d commit 8b74790

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

library/core/src/num/nonzero.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1781,6 +1781,33 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
17811781
// SAFETY: `self.get()` can't be zero
17821782
unsafe { NonZero::new_unchecked(self.get().cast_signed()) }
17831783
}
1784+
1785+
/// Returns the minimum number of bits required to represent `self`.
1786+
///
1787+
/// # Examples
1788+
///
1789+
/// ```
1790+
/// #![feature(uint_bit_width)]
1791+
///
1792+
/// # use core::num::NonZero;
1793+
/// #
1794+
/// # fn main() { test().unwrap(); }
1795+
/// # fn test() -> Option<()> {
1796+
#[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::MIN.bit_width(), NonZero::new(1)?);")]
1797+
#[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::new(0b111)?.bit_width(), NonZero::new(3)?);")]
1798+
#[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::new(0b1110)?.bit_width(), NonZero::new(4)?);")]
1799+
/// # Some(())
1800+
/// # }
1801+
/// ```
1802+
#[unstable(feature = "uint_bit_width", issue = "142326")]
1803+
#[must_use = "this returns the result of the operation, \
1804+
without modifying the original"]
1805+
#[inline(always)]
1806+
pub const fn bit_width(self) -> NonZero<u32> {
1807+
// SAFETY: Since `self.leading_zeros()` is always less than
1808+
// `Self::BITS`, this subtraction can never be zero.
1809+
unsafe { NonZero::new_unchecked(Self::BITS - self.leading_zeros()) }
1810+
}
17841811
};
17851812

17861813
// Associated items for signed nonzero types only.

library/coretests/tests/nonzero.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,3 +570,21 @@ fn test_nonzero_lowest_one() {
570570
nonzero_int_impl!(i8, i16, i32, i64, i128, isize);
571571
nonzero_uint_impl!(u8, u16, u32, u64, u128, usize);
572572
}
573+
574+
#[test]
575+
fn test_nonzero_bit_width() {
576+
macro_rules! nonzero_uint_impl {
577+
($($T:ty),+) => {
578+
$(
579+
{
580+
assert_eq!(NonZero::<$T>::new(0b010_1100).unwrap().bit_width(), NonZero::new(6).unwrap());
581+
assert_eq!(NonZero::<$T>::new(0b111_1001).unwrap().bit_width(), NonZero::new(7).unwrap());
582+
assert_eq!(NonZero::<$T>::MIN.bit_width(), NonZero::new(1).unwrap());
583+
assert_eq!(NonZero::<$T>::MAX.bit_width(), NonZero::new(<$T>::BITS).unwrap());
584+
}
585+
)+
586+
};
587+
}
588+
589+
nonzero_uint_impl!(u8, u16, u32, u64, u128, usize);
590+
}

0 commit comments

Comments
 (0)