From 6a7a69bde9813ac2868f36a01567c633ed6cd023 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Sun, 12 Jan 2020 14:07:31 -0800 Subject: [PATCH 1/3] Add {leading,trailing}_ones to primitive int types --- src/libcore/num/mod.rs | 83 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 072966abf2c40..77fae26953f09 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -393,6 +393,48 @@ $EndFeature, " } } + doc_comment! { + concat!("Returns the number of leading ones in the binary representation of `self`. + +# Examples + +Basic usage: + +``` +", $Feature, "#![feature(leading_trailing_ones)] +let n = -1", stringify!($SelfT), "; + +assert_eq!(n.leading_ones(), ", stringify!($BITS), ");", +$EndFeature, " +```"), + #[unstable(feature = "leading_trailing_ones", reason = "newly added", issue = "0")] + #[inline] + pub const fn leading_ones(self) -> u32 { + (self as $UnsignedT).leading_ones() + } + } + + doc_comment! { + concat!("Returns the number of trailing ones in the binary representation of `self`. + +# Examples + +Basic usage: + +``` +", $Feature, "#![feature(leading_trailing_ones)] +let n = 3", stringify!($SelfT), "; + +assert_eq!(n.trailing_ones(), 2);", +$EndFeature, " +```"), + #[unstable(feature = "leading_trailing_ones", reason = "newly added", issue = "0")] + #[inline] + pub const fn trailing_ones(self) -> u32 { + (self as $UnsignedT).trailing_ones() + } + } + doc_comment! { concat!("Shifts the bits to the left by a specified amount, `n`, wrapping the truncated bits to the end of the resulting integer. @@ -2485,6 +2527,47 @@ assert_eq!(n.trailing_zeros(), 3);", $EndFeature, " } } + doc_comment! { + concat!("Returns the number of leading ones in the binary representation of `self`. + +# Examples + +Basic usage: + +``` +", $Feature, "#![feature(leading_trailing_ones)] +let n = !(", stringify!($SelfT), "::max_value() >> 2); + +assert_eq!(n.leading_ones(), 2);", $EndFeature, " +```"), + #[unstable(feature = "leading_trailing_ones", reason = "newly added", issue = "0")] + #[inline] + pub const fn leading_ones(self) -> u32 { + (!self).leading_zeros() + } + } + + doc_comment! { + concat!("Returns the number of trailing ones in the binary representation +of `self`. + +# Examples + +Basic usage: + +``` +", $Feature, "#![feature(leading_trailing_ones)] +let n = 0b1010111", stringify!($SelfT), "; + +assert_eq!(n.trailing_ones(), 3);", $EndFeature, " +```"), + #[unstable(feature = "leading_trailing_ones", reason = "newly added", issue = "0")] + #[inline] + pub const fn trailing_ones(self) -> u32 { + (!self).trailing_zeros() + } + } + doc_comment! { concat!("Shifts the bits to the left by a specified amount, `n`, wrapping the truncated bits to the end of the resulting integer. From 2330e325ccee2e91d7aec6c0d4068748619bf588 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Sun, 12 Jan 2020 14:50:00 -0800 Subject: [PATCH 2/3] Tests for leading_trailing_ones --- src/libcore/tests/lib.rs | 1 + src/libcore/tests/num/int_macros.rs | 27 +++++++++++++++++++++++++++ src/libcore/tests/num/uint_macros.rs | 27 +++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 86cf6fc104c83..36476cf01c08c 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -41,6 +41,7 @@ #![feature(const_raw_ptr_deref)] #![feature(never_type)] #![feature(unwrap_infallible)] +#![feature(leading_trailing_ones)] extern crate test; diff --git a/src/libcore/tests/num/int_macros.rs b/src/libcore/tests/num/int_macros.rs index 4a44b5f24b910..48a49073b2cf5 100644 --- a/src/libcore/tests/num/int_macros.rs +++ b/src/libcore/tests/num/int_macros.rs @@ -89,6 +89,33 @@ macro_rules! int_module { assert_eq!(C.count_zeros(), bits as u32 - 5); } + #[test] + fn test_leading_trailing_ones() { + let bits = (mem::size_of::<$T>() * 8) as u32; + + let a: $T = 0b0101_1111; + assert_eq!(a.trailing_ones(), 5); + assert_eq!((!a).leading_ones(), bits - 7); + + assert_eq!(a.reverse_bits().leading_ones(), 5); + + assert_eq!(_1.leading_ones(), bits); + assert_eq!(_1.trailing_ones(), bits); + + assert_eq!((_1 << 1).trailing_ones(), 0); + assert_eq!(MAX.leading_ones(), 0); + + assert_eq!((_1 << 1).leading_ones(), bits - 1); + assert_eq!(MAX.trailing_ones(), bits - 1); + + assert_eq!(_0.leading_ones(), 0); + assert_eq!(_0.trailing_ones(), 0); + + let x: $T = 0b0010_1100; + assert_eq!(x.leading_ones(), 0); + assert_eq!(x.trailing_ones(), 0); + } + #[test] fn test_rotate() { assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A); diff --git a/src/libcore/tests/num/uint_macros.rs b/src/libcore/tests/num/uint_macros.rs index f94b2f56bbbec..8f1ca8e6fac2c 100644 --- a/src/libcore/tests/num/uint_macros.rs +++ b/src/libcore/tests/num/uint_macros.rs @@ -53,6 +53,33 @@ macro_rules! uint_module { assert!(C.count_zeros() == bits as u32 - 5); } + #[test] + fn test_leading_trailing_ones() { + let bits = (mem::size_of::<$T>() * 8) as u32; + + let a: $T = 0b0101_1111; + assert_eq!(a.trailing_ones(), 5); + assert_eq!((!a).leading_ones(), bits - 7); + + assert_eq!(a.reverse_bits().leading_ones(), 5); + + assert_eq!(_1.leading_ones(), bits); + assert_eq!(_1.trailing_ones(), bits); + + assert_eq!((_1 << 1).trailing_ones(), 0); + assert_eq!((_1 >> 1).leading_ones(), 0); + + assert_eq!((_1 << 1).leading_ones(), bits - 1); + assert_eq!((_1 >> 1).trailing_ones(), bits - 1); + + assert_eq!(_0.leading_ones(), 0); + assert_eq!(_0.trailing_ones(), 0); + + let x: $T = 0b0010_1100; + assert_eq!(x.leading_ones(), 0); + assert_eq!(x.trailing_ones(), 0); + } + #[test] fn test_rotate() { assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A); From 783a7dc8ed03a38910b9ea5ded11139616dfa67b Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Wed, 15 Jan 2020 08:31:24 -0800 Subject: [PATCH 3/3] Mark leading_trailing_ones with tracking issue 57969 --- src/libcore/num/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 77fae26953f09..91848abd68d36 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -407,7 +407,7 @@ let n = -1", stringify!($SelfT), "; assert_eq!(n.leading_ones(), ", stringify!($BITS), ");", $EndFeature, " ```"), - #[unstable(feature = "leading_trailing_ones", reason = "newly added", issue = "0")] + #[unstable(feature = "leading_trailing_ones", issue = "57969")] #[inline] pub const fn leading_ones(self) -> u32 { (self as $UnsignedT).leading_ones() @@ -428,7 +428,7 @@ let n = 3", stringify!($SelfT), "; assert_eq!(n.trailing_ones(), 2);", $EndFeature, " ```"), - #[unstable(feature = "leading_trailing_ones", reason = "newly added", issue = "0")] + #[unstable(feature = "leading_trailing_ones", issue = "57969")] #[inline] pub const fn trailing_ones(self) -> u32 { (self as $UnsignedT).trailing_ones() @@ -2540,7 +2540,7 @@ let n = !(", stringify!($SelfT), "::max_value() >> 2); assert_eq!(n.leading_ones(), 2);", $EndFeature, " ```"), - #[unstable(feature = "leading_trailing_ones", reason = "newly added", issue = "0")] + #[unstable(feature = "leading_trailing_ones", issue = "57969")] #[inline] pub const fn leading_ones(self) -> u32 { (!self).leading_zeros() @@ -2561,7 +2561,7 @@ let n = 0b1010111", stringify!($SelfT), "; assert_eq!(n.trailing_ones(), 3);", $EndFeature, " ```"), - #[unstable(feature = "leading_trailing_ones", reason = "newly added", issue = "0")] + #[unstable(feature = "leading_trailing_ones", issue = "57969")] #[inline] pub const fn trailing_ones(self) -> u32 { (!self).trailing_zeros()