Skip to content

Commit 1d5f6d4

Browse files
committed
Auto merge of #68165 - thomcc:lt_ones, r=sfackler
Add leading_ones and trailing_ones methods to the primitive integer types I was surprised these were missing (given that `leading_zeros` and `trailing_zeros` exist), and they seem trivial and hopefully not controversial. Note that there's some precedent in that `count_ones` and `count_zeros` are both supported even though only one of these has an intrinsic. I'm not sure if these need a `rustc_const_unstable` flag (the tests don't seem to mind that it's missing). I just made them const, since there's not really any reason for these to be non-const when the `_zeros` variants are const. Note: My understanding is trivial stuff like (hopefully) this can land without an RFC, but I'm not fully sure about the process though. Questions like "when does the tracking issue get filed?", are a total mystery to me. So, any guidance is appreciated, and sorry in advance if I should have gone through some more involved process for this.
2 parents 320ada6 + 783a7dc commit 1d5f6d4

File tree

4 files changed

+138
-0
lines changed

4 files changed

+138
-0
lines changed

src/libcore/num/mod.rs

+83
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,48 @@ $EndFeature, "
393393
}
394394
}
395395

396+
doc_comment! {
397+
concat!("Returns the number of leading ones in the binary representation of `self`.
398+
399+
# Examples
400+
401+
Basic usage:
402+
403+
```
404+
", $Feature, "#![feature(leading_trailing_ones)]
405+
let n = -1", stringify!($SelfT), ";
406+
407+
assert_eq!(n.leading_ones(), ", stringify!($BITS), ");",
408+
$EndFeature, "
409+
```"),
410+
#[unstable(feature = "leading_trailing_ones", issue = "57969")]
411+
#[inline]
412+
pub const fn leading_ones(self) -> u32 {
413+
(self as $UnsignedT).leading_ones()
414+
}
415+
}
416+
417+
doc_comment! {
418+
concat!("Returns the number of trailing ones in the binary representation of `self`.
419+
420+
# Examples
421+
422+
Basic usage:
423+
424+
```
425+
", $Feature, "#![feature(leading_trailing_ones)]
426+
let n = 3", stringify!($SelfT), ";
427+
428+
assert_eq!(n.trailing_ones(), 2);",
429+
$EndFeature, "
430+
```"),
431+
#[unstable(feature = "leading_trailing_ones", issue = "57969")]
432+
#[inline]
433+
pub const fn trailing_ones(self) -> u32 {
434+
(self as $UnsignedT).trailing_ones()
435+
}
436+
}
437+
396438
doc_comment! {
397439
concat!("Shifts the bits to the left by a specified amount, `n`,
398440
wrapping the truncated bits to the end of the resulting integer.
@@ -2485,6 +2527,47 @@ assert_eq!(n.trailing_zeros(), 3);", $EndFeature, "
24852527
}
24862528
}
24872529

2530+
doc_comment! {
2531+
concat!("Returns the number of leading ones in the binary representation of `self`.
2532+
2533+
# Examples
2534+
2535+
Basic usage:
2536+
2537+
```
2538+
", $Feature, "#![feature(leading_trailing_ones)]
2539+
let n = !(", stringify!($SelfT), "::max_value() >> 2);
2540+
2541+
assert_eq!(n.leading_ones(), 2);", $EndFeature, "
2542+
```"),
2543+
#[unstable(feature = "leading_trailing_ones", issue = "57969")]
2544+
#[inline]
2545+
pub const fn leading_ones(self) -> u32 {
2546+
(!self).leading_zeros()
2547+
}
2548+
}
2549+
2550+
doc_comment! {
2551+
concat!("Returns the number of trailing ones in the binary representation
2552+
of `self`.
2553+
2554+
# Examples
2555+
2556+
Basic usage:
2557+
2558+
```
2559+
", $Feature, "#![feature(leading_trailing_ones)]
2560+
let n = 0b1010111", stringify!($SelfT), ";
2561+
2562+
assert_eq!(n.trailing_ones(), 3);", $EndFeature, "
2563+
```"),
2564+
#[unstable(feature = "leading_trailing_ones", issue = "57969")]
2565+
#[inline]
2566+
pub const fn trailing_ones(self) -> u32 {
2567+
(!self).trailing_zeros()
2568+
}
2569+
}
2570+
24882571
doc_comment! {
24892572
concat!("Shifts the bits to the left by a specified amount, `n`,
24902573
wrapping the truncated bits to the end of the resulting integer.

src/libcore/tests/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#![feature(const_raw_ptr_deref)]
4343
#![feature(never_type)]
4444
#![feature(unwrap_infallible)]
45+
#![feature(leading_trailing_ones)]
4546

4647
extern crate test;
4748

src/libcore/tests/num/int_macros.rs

+27
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,33 @@ macro_rules! int_module {
8989
assert_eq!(C.count_zeros(), bits as u32 - 5);
9090
}
9191

92+
#[test]
93+
fn test_leading_trailing_ones() {
94+
let bits = (mem::size_of::<$T>() * 8) as u32;
95+
96+
let a: $T = 0b0101_1111;
97+
assert_eq!(a.trailing_ones(), 5);
98+
assert_eq!((!a).leading_ones(), bits - 7);
99+
100+
assert_eq!(a.reverse_bits().leading_ones(), 5);
101+
102+
assert_eq!(_1.leading_ones(), bits);
103+
assert_eq!(_1.trailing_ones(), bits);
104+
105+
assert_eq!((_1 << 1).trailing_ones(), 0);
106+
assert_eq!(MAX.leading_ones(), 0);
107+
108+
assert_eq!((_1 << 1).leading_ones(), bits - 1);
109+
assert_eq!(MAX.trailing_ones(), bits - 1);
110+
111+
assert_eq!(_0.leading_ones(), 0);
112+
assert_eq!(_0.trailing_ones(), 0);
113+
114+
let x: $T = 0b0010_1100;
115+
assert_eq!(x.leading_ones(), 0);
116+
assert_eq!(x.trailing_ones(), 0);
117+
}
118+
92119
#[test]
93120
fn test_rotate() {
94121
assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);

src/libcore/tests/num/uint_macros.rs

+27
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,33 @@ macro_rules! uint_module {
5353
assert!(C.count_zeros() == bits as u32 - 5);
5454
}
5555

56+
#[test]
57+
fn test_leading_trailing_ones() {
58+
let bits = (mem::size_of::<$T>() * 8) as u32;
59+
60+
let a: $T = 0b0101_1111;
61+
assert_eq!(a.trailing_ones(), 5);
62+
assert_eq!((!a).leading_ones(), bits - 7);
63+
64+
assert_eq!(a.reverse_bits().leading_ones(), 5);
65+
66+
assert_eq!(_1.leading_ones(), bits);
67+
assert_eq!(_1.trailing_ones(), bits);
68+
69+
assert_eq!((_1 << 1).trailing_ones(), 0);
70+
assert_eq!((_1 >> 1).leading_ones(), 0);
71+
72+
assert_eq!((_1 << 1).leading_ones(), bits - 1);
73+
assert_eq!((_1 >> 1).trailing_ones(), bits - 1);
74+
75+
assert_eq!(_0.leading_ones(), 0);
76+
assert_eq!(_0.trailing_ones(), 0);
77+
78+
let x: $T = 0b0010_1100;
79+
assert_eq!(x.leading_ones(), 0);
80+
assert_eq!(x.trailing_ones(), 0);
81+
}
82+
5683
#[test]
5784
fn test_rotate() {
5885
assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);

0 commit comments

Comments
 (0)