From 538fe8146eff5111dc33d47cc38f9dbecc462677 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Tue, 2 Jul 2024 15:00:09 -0700 Subject: [PATCH] Add edge-case examples to `{count,leading,trailing}_{ones,zeros}` methods Some architectures (i386) do not define a "count leading zeros" instruction, they define a "find first set bit" instruction (`bsf`) whose result is undefined when given zero (ie none of the bits are set). Of this family of bitwise operations, I always forget which of these things is potentially undefined for zero, and I'm also not 100% sure that Rust provides a hard guarantee for the results of these methods when given zero. So I figured there are others who have these same uncertainties, and it would be good to resolve them and answer the question via extending these doc examples/tests. See https://en.wikipedia.org/wiki/Find_first_set#Hardware_support for more info on i386 and `bsf` on zero. --- core/src/num/uint_macros.rs | 41 +++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/core/src/num/uint_macros.rs b/core/src/num/uint_macros.rs index ad72c29758bd7..40bc58204e808 100644 --- a/core/src/num/uint_macros.rs +++ b/core/src/num/uint_macros.rs @@ -65,8 +65,13 @@ macro_rules! uint_impl { /// /// ``` #[doc = concat!("let n = 0b01001100", stringify!($SelfT), ";")] - /// /// assert_eq!(n.count_ones(), 3); + /// + #[doc = concat!("let max = ", stringify!($SelfT),"::MAX;")] + #[doc = concat!("assert_eq!(max.count_ones(), ", stringify!($BITS), ");")] + /// + #[doc = concat!("let zero = 0", stringify!($SelfT), ";")] + /// assert_eq!(zero.count_ones(), 0); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_math", since = "1.32.0")] @@ -86,7 +91,11 @@ macro_rules! uint_impl { /// Basic usage: /// /// ``` - #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.count_zeros(), 0);")] + #[doc = concat!("let zero = 0", stringify!($SelfT), ";")] + #[doc = concat!("assert_eq!(zero.count_zeros(), ", stringify!($BITS), ");")] + /// + #[doc = concat!("let max = ", stringify!($SelfT),"::MAX;")] + /// assert_eq!(max.count_zeros(), 0); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_math", since = "1.32.0")] @@ -108,8 +117,13 @@ macro_rules! uint_impl { /// /// ``` #[doc = concat!("let n = ", stringify!($SelfT), "::MAX >> 2;")] - /// /// assert_eq!(n.leading_zeros(), 2); + /// + #[doc = concat!("let zero = 0", stringify!($SelfT), ";")] + #[doc = concat!("assert_eq!(zero.leading_zeros(), ", stringify!($BITS), ");")] + /// + #[doc = concat!("let max = ", stringify!($SelfT),"::MAX;")] + /// assert_eq!(max.leading_zeros(), 0); /// ``` #[doc = concat!("[`ilog2`]: ", stringify!($SelfT), "::ilog2")] #[stable(feature = "rust1", since = "1.0.0")] @@ -130,8 +144,13 @@ macro_rules! uint_impl { /// /// ``` #[doc = concat!("let n = 0b0101000", stringify!($SelfT), ";")] - /// /// assert_eq!(n.trailing_zeros(), 3); + /// + #[doc = concat!("let zero = 0", stringify!($SelfT), ";")] + #[doc = concat!("assert_eq!(zero.trailing_zeros(), ", stringify!($BITS), ");")] + /// + #[doc = concat!("let max = ", stringify!($SelfT),"::MAX;")] + #[doc = concat!("assert_eq!(max.trailing_zeros(), 0);")] /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_math", since = "1.32.0")] @@ -150,8 +169,13 @@ macro_rules! uint_impl { /// /// ``` #[doc = concat!("let n = !(", stringify!($SelfT), "::MAX >> 2);")] - /// /// assert_eq!(n.leading_ones(), 2); + /// + #[doc = concat!("let zero = 0", stringify!($SelfT), ";")] + /// assert_eq!(zero.leading_ones(), 0); + /// + #[doc = concat!("let max = ", stringify!($SelfT),"::MAX;")] + #[doc = concat!("assert_eq!(max.leading_ones(), ", stringify!($BITS), ");")] /// ``` #[stable(feature = "leading_trailing_ones", since = "1.46.0")] #[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")] @@ -171,8 +195,13 @@ macro_rules! uint_impl { /// /// ``` #[doc = concat!("let n = 0b1010111", stringify!($SelfT), ";")] - /// /// assert_eq!(n.trailing_ones(), 3); + /// + #[doc = concat!("let zero = 0", stringify!($SelfT), ";")] + /// assert_eq!(zero.trailing_ones(), 0); + /// + #[doc = concat!("let max = ", stringify!($SelfT),"::MAX;")] + #[doc = concat!("assert_eq!(max.trailing_ones(), ", stringify!($BITS), ");")] /// ``` #[stable(feature = "leading_trailing_ones", since = "1.46.0")] #[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")]