Skip to content

Commit f846ed5

Browse files
committed
Move leading_zeros and trailing_zeros methods into nonzero_integer macro
1 parent a78d9a6 commit f846ed5

File tree

1 file changed

+75
-71
lines changed

1 file changed

+75
-71
lines changed

library/core/src/num/nonzero.rs

Lines changed: 75 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,12 @@ macro_rules! nonzero_integer {
2626
(
2727
Self = $Ty:ident,
2828
Primitive = $signedness:ident $Int:ident,
29+
UnsignedPrimitive = $UnsignedPrimitive:ty,
2930
feature = $feature:literal,
3031
original_stabilization = $since:literal,
32+
33+
// Used in doc comments.
34+
leading_zeros_test = $leading_zeros_test:expr,
3135
) => {
3236
/// An integer that is known not to equal zero.
3337
///
@@ -122,6 +126,53 @@ macro_rules! nonzero_integer {
122126
}
123127
self.0
124128
}
129+
130+
/// Returns the number of leading zeros in the binary representation of `self`.
131+
///
132+
/// On many architectures, this function can perform better than `leading_zeros()` on the underlying integer type, as special handling of zero can be avoided.
133+
///
134+
/// # Examples
135+
///
136+
/// Basic usage:
137+
///
138+
/// ```
139+
#[doc = concat!("let n = std::num::", stringify!($Ty), "::new(", stringify!($leading_zeros_test), ").unwrap();")]
140+
///
141+
/// assert_eq!(n.leading_zeros(), 0);
142+
/// ```
143+
#[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
144+
#[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
145+
#[must_use = "this returns the result of the operation, \
146+
without modifying the original"]
147+
#[inline]
148+
pub const fn leading_zeros(self) -> u32 {
149+
// SAFETY: since `self` cannot be zero, it is safe to call `ctlz_nonzero`.
150+
unsafe { intrinsics::ctlz_nonzero(self.get() as $UnsignedPrimitive) as u32 }
151+
}
152+
153+
/// Returns the number of trailing zeros in the binary representation
154+
/// of `self`.
155+
///
156+
/// On many architectures, this function can perform better than `trailing_zeros()` on the underlying integer type, as special handling of zero can be avoided.
157+
///
158+
/// # Examples
159+
///
160+
/// Basic usage:
161+
///
162+
/// ```
163+
#[doc = concat!("let n = std::num::", stringify!($Ty), "::new(0b0101000).unwrap();")]
164+
///
165+
/// assert_eq!(n.trailing_zeros(), 3);
166+
/// ```
167+
#[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
168+
#[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
169+
#[must_use = "this returns the result of the operation, \
170+
without modifying the original"]
171+
#[inline]
172+
pub const fn trailing_zeros(self) -> u32 {
173+
// SAFETY: since `self` cannot be zero, it is safe to call `cttz_nonzero`.
174+
unsafe { intrinsics::cttz_nonzero(self.get() as $UnsignedPrimitive) as u32 }
175+
}
125176
}
126177

127178
#[stable(feature = "from_nonzero", since = "1.31.0")]
@@ -206,77 +257,6 @@ macro_rules! nonzero_integer {
206257
};
207258
}
208259

209-
macro_rules! nonzero_leading_trailing_zeros {
210-
( $( $Ty: ident($Uint: ty) , $LeadingTestExpr:expr ;)+ ) => {
211-
$(
212-
impl $Ty {
213-
/// Returns the number of leading zeros in the binary representation of `self`.
214-
///
215-
/// On many architectures, this function can perform better than `leading_zeros()` on the underlying integer type, as special handling of zero can be avoided.
216-
///
217-
/// # Examples
218-
///
219-
/// Basic usage:
220-
///
221-
/// ```
222-
#[doc = concat!("let n = std::num::", stringify!($Ty), "::new(", stringify!($LeadingTestExpr), ").unwrap();")]
223-
///
224-
/// assert_eq!(n.leading_zeros(), 0);
225-
/// ```
226-
#[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
227-
#[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
228-
#[must_use = "this returns the result of the operation, \
229-
without modifying the original"]
230-
#[inline]
231-
pub const fn leading_zeros(self) -> u32 {
232-
// SAFETY: since `self` cannot be zero, it is safe to call `ctlz_nonzero`.
233-
unsafe { intrinsics::ctlz_nonzero(self.get() as $Uint) as u32 }
234-
}
235-
236-
/// Returns the number of trailing zeros in the binary representation
237-
/// of `self`.
238-
///
239-
/// On many architectures, this function can perform better than `trailing_zeros()` on the underlying integer type, as special handling of zero can be avoided.
240-
///
241-
/// # Examples
242-
///
243-
/// Basic usage:
244-
///
245-
/// ```
246-
#[doc = concat!("let n = std::num::", stringify!($Ty), "::new(0b0101000).unwrap();")]
247-
///
248-
/// assert_eq!(n.trailing_zeros(), 3);
249-
/// ```
250-
#[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
251-
#[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
252-
#[must_use = "this returns the result of the operation, \
253-
without modifying the original"]
254-
#[inline]
255-
pub const fn trailing_zeros(self) -> u32 {
256-
// SAFETY: since `self` cannot be zero, it is safe to call `cttz_nonzero`.
257-
unsafe { intrinsics::cttz_nonzero(self.get() as $Uint) as u32 }
258-
}
259-
260-
}
261-
)+
262-
}
263-
}
264-
265-
nonzero_leading_trailing_zeros! {
266-
NonZeroU8(u8), u8::MAX;
267-
NonZeroU16(u16), u16::MAX;
268-
NonZeroU32(u32), u32::MAX;
269-
NonZeroU64(u64), u64::MAX;
270-
NonZeroU128(u128), u128::MAX;
271-
NonZeroUsize(usize), usize::MAX;
272-
NonZeroI8(u8), -1i8;
273-
NonZeroI16(u16), -1i16;
274-
NonZeroI32(u32), -1i32;
275-
NonZeroI64(u64), -1i64;
276-
NonZeroI128(u128), -1i128;
277-
NonZeroIsize(usize), -1isize;
278-
}
279-
280260
macro_rules! nonzero_integer_impl_div_rem {
281261
($Ty:ident signed $Int:ty) => {
282262
// nothing for signed ints
@@ -1376,83 +1356,107 @@ nonzero_bits! {
13761356
nonzero_integer! {
13771357
Self = NonZeroU8,
13781358
Primitive = unsigned u8,
1359+
UnsignedPrimitive = u8,
13791360
feature = "nonzero",
13801361
original_stabilization = "1.28.0",
1362+
leading_zeros_test = u8::MAX,
13811363
}
13821364

13831365
nonzero_integer! {
13841366
Self = NonZeroU16,
13851367
Primitive = unsigned u16,
1368+
UnsignedPrimitive = u16,
13861369
feature = "nonzero",
13871370
original_stabilization = "1.28.0",
1371+
leading_zeros_test = u16::MAX,
13881372
}
13891373

13901374
nonzero_integer! {
13911375
Self = NonZeroU32,
13921376
Primitive = unsigned u32,
1377+
UnsignedPrimitive = u32,
13931378
feature = "nonzero",
13941379
original_stabilization = "1.28.0",
1380+
leading_zeros_test = u32::MAX,
13951381
}
13961382

13971383
nonzero_integer! {
13981384
Self = NonZeroU64,
13991385
Primitive = unsigned u64,
1386+
UnsignedPrimitive = u64,
14001387
feature = "nonzero",
14011388
original_stabilization = "1.28.0",
1389+
leading_zeros_test = u64::MAX,
14021390
}
14031391

14041392
nonzero_integer! {
14051393
Self = NonZeroU128,
14061394
Primitive = unsigned u128,
1395+
UnsignedPrimitive = u128,
14071396
feature = "nonzero",
14081397
original_stabilization = "1.28.0",
1398+
leading_zeros_test = u128::MAX,
14091399
}
14101400

14111401
nonzero_integer! {
14121402
Self = NonZeroUsize,
14131403
Primitive = unsigned usize,
1404+
UnsignedPrimitive = usize,
14141405
feature = "nonzero",
14151406
original_stabilization = "1.28.0",
1407+
leading_zeros_test = usize::MAX,
14161408
}
14171409

14181410
nonzero_integer! {
14191411
Self = NonZeroI8,
14201412
Primitive = signed i8,
1413+
UnsignedPrimitive = u8,
14211414
feature = "signed_nonzero",
14221415
original_stabilization = "1.34.0",
1416+
leading_zeros_test = -1i8,
14231417
}
14241418

14251419
nonzero_integer! {
14261420
Self = NonZeroI16,
14271421
Primitive = signed i16,
1422+
UnsignedPrimitive = u16,
14281423
feature = "signed_nonzero",
14291424
original_stabilization = "1.34.0",
1425+
leading_zeros_test = -1i16,
14301426
}
14311427

14321428
nonzero_integer! {
14331429
Self = NonZeroI32,
14341430
Primitive = signed i32,
1431+
UnsignedPrimitive = u32,
14351432
feature = "signed_nonzero",
14361433
original_stabilization = "1.34.0",
1434+
leading_zeros_test = -1i32,
14371435
}
14381436

14391437
nonzero_integer! {
14401438
Self = NonZeroI64,
14411439
Primitive = signed i64,
1440+
UnsignedPrimitive = u64,
14421441
feature = "signed_nonzero",
14431442
original_stabilization = "1.34.0",
1443+
leading_zeros_test = -1i64,
14441444
}
14451445

14461446
nonzero_integer! {
14471447
Self = NonZeroI128,
14481448
Primitive = signed i128,
1449+
UnsignedPrimitive = u128,
14491450
feature = "signed_nonzero",
14501451
original_stabilization = "1.34.0",
1452+
leading_zeros_test = -1i128,
14511453
}
14521454

14531455
nonzero_integer! {
14541456
Self = NonZeroIsize,
14551457
Primitive = signed isize,
1458+
UnsignedPrimitive = usize,
14561459
feature = "signed_nonzero",
14571460
original_stabilization = "1.34.0",
1461+
leading_zeros_test = -1isize,
14581462
}

0 commit comments

Comments
 (0)