]> git.lizzy.rs Git - rust.git/blob - library/core/src/num/nonzero.rs
Rollup merge of #85663 - fee1-dead:document-arc-from, r=m-ou-se
[rust.git] / library / core / src / num / nonzero.rs
1 //! Definitions of integer that is known not to equal zero.
2
3 use crate::fmt;
4 use crate::ops::{BitOr, BitOrAssign, Div, Rem};
5 use crate::str::FromStr;
6
7 use super::from_str_radix;
8 use super::{IntErrorKind, ParseIntError};
9 use crate::intrinsics;
10
11 macro_rules! impl_nonzero_fmt {
12     ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
13         $(
14             #[$stability]
15             impl fmt::$Trait for $Ty {
16                 #[inline]
17                 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18                     self.get().fmt(f)
19                 }
20             }
21         )+
22     }
23 }
24
25 macro_rules! nonzero_integers {
26     ( $( #[$stability: meta] #[$const_new_unchecked_stability: meta] $Ty: ident($Int: ty); )+ ) => {
27         $(
28             /// An integer that is known not to equal zero.
29             ///
30             /// This enables some memory layout optimization.
31             #[doc = concat!("For example, `Option<", stringify!($Ty), ">` is the same size as `", stringify!($Int), "`:")]
32             ///
33             /// ```rust
34             /// use std::mem::size_of;
35             #[doc = concat!("assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", stringify!($Int), ">());")]
36             /// ```
37             #[$stability]
38             #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
39             #[repr(transparent)]
40             #[rustc_layout_scalar_valid_range_start(1)]
41             #[rustc_nonnull_optimization_guaranteed]
42             pub struct $Ty($Int);
43
44             impl $Ty {
45                 /// Creates a non-zero without checking whether the value is non-zero.
46                 /// This results in undefined behaviour if the value is zero.
47                 ///
48                 /// # Safety
49                 ///
50                 /// The value must not be zero.
51                 #[$stability]
52                 #[$const_new_unchecked_stability]
53                 #[inline]
54                 pub const unsafe fn new_unchecked(n: $Int) -> Self {
55                     // SAFETY: this is guaranteed to be safe by the caller.
56                     unsafe { Self(n) }
57                 }
58
59                 /// Creates a non-zero if the given value is not zero.
60                 #[$stability]
61                 #[rustc_const_stable(feature = "const_nonzero_int_methods", since = "1.47.0")]
62                 #[inline]
63                 pub const fn new(n: $Int) -> Option<Self> {
64                     if n != 0 {
65                         // SAFETY: we just checked that there's no `0`
66                         Some(unsafe { Self(n) })
67                     } else {
68                         None
69                     }
70                 }
71
72                 /// Returns the value as a primitive type.
73                 #[$stability]
74                 #[inline]
75                 #[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
76                 pub const fn get(self) -> $Int {
77                     self.0
78                 }
79
80             }
81
82             #[stable(feature = "from_nonzero", since = "1.31.0")]
83             impl From<$Ty> for $Int {
84                 #[doc = concat!("Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`")]
85                 #[inline]
86                 fn from(nonzero: $Ty) -> Self {
87                     nonzero.0
88                 }
89             }
90
91             #[stable(feature = "nonzero_bitor", since = "1.45.0")]
92             impl BitOr for $Ty {
93                 type Output = Self;
94                 #[inline]
95                 fn bitor(self, rhs: Self) -> Self::Output {
96                     // SAFETY: since `self` and `rhs` are both nonzero, the
97                     // result of the bitwise-or will be nonzero.
98                     unsafe { $Ty::new_unchecked(self.get() | rhs.get()) }
99                 }
100             }
101
102             #[stable(feature = "nonzero_bitor", since = "1.45.0")]
103             impl BitOr<$Int> for $Ty {
104                 type Output = Self;
105                 #[inline]
106                 fn bitor(self, rhs: $Int) -> Self::Output {
107                     // SAFETY: since `self` is nonzero, the result of the
108                     // bitwise-or will be nonzero regardless of the value of
109                     // `rhs`.
110                     unsafe { $Ty::new_unchecked(self.get() | rhs) }
111                 }
112             }
113
114             #[stable(feature = "nonzero_bitor", since = "1.45.0")]
115             impl BitOr<$Ty> for $Int {
116                 type Output = $Ty;
117                 #[inline]
118                 fn bitor(self, rhs: $Ty) -> Self::Output {
119                     // SAFETY: since `rhs` is nonzero, the result of the
120                     // bitwise-or will be nonzero regardless of the value of
121                     // `self`.
122                     unsafe { $Ty::new_unchecked(self | rhs.get()) }
123                 }
124             }
125
126             #[stable(feature = "nonzero_bitor", since = "1.45.0")]
127             impl BitOrAssign for $Ty {
128                 #[inline]
129                 fn bitor_assign(&mut self, rhs: Self) {
130                     *self = *self | rhs;
131                 }
132             }
133
134             #[stable(feature = "nonzero_bitor", since = "1.45.0")]
135             impl BitOrAssign<$Int> for $Ty {
136                 #[inline]
137                 fn bitor_assign(&mut self, rhs: $Int) {
138                     *self = *self | rhs;
139                 }
140             }
141
142             impl_nonzero_fmt! {
143                 #[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
144             }
145         )+
146     }
147 }
148
149 nonzero_integers! {
150     #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU8(u8);
151     #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU16(u16);
152     #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU32(u32);
153     #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU64(u64);
154     #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU128(u128);
155     #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroUsize(usize);
156     #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI8(i8);
157     #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI16(i16);
158     #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI32(i32);
159     #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI64(i64);
160     #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI128(i128);
161     #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize);
162 }
163
164 macro_rules! from_str_radix_nzint_impl {
165     ($($t:ty)*) => {$(
166         #[stable(feature = "nonzero_parse", since = "1.35.0")]
167         impl FromStr for $t {
168             type Err = ParseIntError;
169             fn from_str(src: &str) -> Result<Self, Self::Err> {
170                 Self::new(from_str_radix(src, 10)?)
171                     .ok_or(ParseIntError {
172                         kind: IntErrorKind::Zero
173                     })
174             }
175         }
176     )*}
177 }
178
179 from_str_radix_nzint_impl! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize
180 NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize }
181
182 macro_rules! nonzero_leading_trailing_zeros {
183     ( $( $Ty: ident($Uint: ty) , $LeadingTestExpr:expr ;)+ ) => {
184         $(
185             impl $Ty {
186                 /// Returns the number of leading zeros in the binary representation of `self`.
187                 ///
188                 /// On many architectures, this function can perform better than `leading_zeros()` on the underlying integer type, as special handling of zero can be avoided.
189                 ///
190                 /// # Examples
191                 ///
192                 /// Basic usage:
193                 ///
194                 /// ```
195                 #[doc = concat!("let n = std::num::", stringify!($Ty), "::new(", stringify!($LeadingTestExpr), ").unwrap();")]
196                 ///
197                 /// assert_eq!(n.leading_zeros(), 0);
198                 /// ```
199                 #[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
200                 #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
201                 #[inline]
202                 pub const fn leading_zeros(self) -> u32 {
203                     // SAFETY: since `self` can not be zero it is safe to call ctlz_nonzero
204                     unsafe { intrinsics::ctlz_nonzero(self.0 as $Uint) as u32 }
205                 }
206
207                 /// Returns the number of trailing zeros in the binary representation
208                 /// of `self`.
209                 ///
210                 /// On many architectures, this function can perform better than `trailing_zeros()` on the underlying integer type, as special handling of zero can be avoided.
211                 ///
212                 /// # Examples
213                 ///
214                 /// Basic usage:
215                 ///
216                 /// ```
217                 #[doc = concat!("let n = std::num::", stringify!($Ty), "::new(0b0101000).unwrap();")]
218                 ///
219                 /// assert_eq!(n.trailing_zeros(), 3);
220                 /// ```
221                 #[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
222                 #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
223                 #[inline]
224                 pub const fn trailing_zeros(self) -> u32 {
225                     // SAFETY: since `self` can not be zero it is safe to call cttz_nonzero
226                     unsafe { intrinsics::cttz_nonzero(self.0 as $Uint) as u32 }
227                 }
228
229             }
230         )+
231     }
232 }
233
234 nonzero_leading_trailing_zeros! {
235     NonZeroU8(u8), u8::MAX;
236     NonZeroU16(u16), u16::MAX;
237     NonZeroU32(u32), u32::MAX;
238     NonZeroU64(u64), u64::MAX;
239     NonZeroU128(u128), u128::MAX;
240     NonZeroUsize(usize), usize::MAX;
241     NonZeroI8(u8), -1i8;
242     NonZeroI16(u16), -1i16;
243     NonZeroI32(u32), -1i32;
244     NonZeroI64(u64), -1i64;
245     NonZeroI128(u128), -1i128;
246     NonZeroIsize(usize), -1isize;
247 }
248
249 macro_rules! nonzero_integers_div {
250     ( $( $Ty: ident($Int: ty); )+ ) => {
251         $(
252             #[stable(feature = "nonzero_div", since = "1.51.0")]
253             impl Div<$Ty> for $Int {
254                 type Output = $Int;
255                 /// This operation rounds towards zero,
256                 /// truncating any fractional part of the exact result, and cannot panic.
257                 #[inline]
258                 fn div(self, other: $Ty) -> $Int {
259                     // SAFETY: div by zero is checked because `other` is a nonzero,
260                     // and MIN/-1 is checked because `self` is an unsigned int.
261                     unsafe { crate::intrinsics::unchecked_div(self, other.get()) }
262                 }
263             }
264
265             #[stable(feature = "nonzero_div", since = "1.51.0")]
266             impl Rem<$Ty> for $Int {
267                 type Output = $Int;
268                 /// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic.
269                 #[inline]
270                 fn rem(self, other: $Ty) -> $Int {
271                     // SAFETY: rem by zero is checked because `other` is a nonzero,
272                     // and MIN/-1 is checked because `self` is an unsigned int.
273                     unsafe { crate::intrinsics::unchecked_rem(self, other.get()) }
274                 }
275             }
276         )+
277     }
278 }
279
280 nonzero_integers_div! {
281     NonZeroU8(u8);
282     NonZeroU16(u16);
283     NonZeroU32(u32);
284     NonZeroU64(u64);
285     NonZeroU128(u128);
286     NonZeroUsize(usize);
287 }
288
289 // A bunch of methods for unsigned nonzero types only.
290 macro_rules! nonzero_unsigned_operations {
291     ( $( $Ty: ident($Int: ty); )+ ) => {
292         $(
293             impl $Ty {
294                 /// Add an unsigned integer to a non-zero value.
295                 /// Check for overflow and return [`None`] on overflow
296                 /// As a consequence, the result cannot wrap to zero.
297                 ///
298                 ///
299                 /// # Examples
300                 ///
301                 /// ```
302                 /// #![feature(nonzero_ops)]
303                 #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
304                 ///
305                 /// # fn main() { test().unwrap(); }
306                 /// # fn test() -> Option<()> {
307                 #[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")]
308                 #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
309                 #[doc = concat!("let max = ", stringify!($Ty), "::new(",
310                                 stringify!($Int), "::MAX)?;")]
311                 ///
312                 /// assert_eq!(Some(two), one.checked_add(1));
313                 /// assert_eq!(None, max.checked_add(1));
314                 /// # Some(())
315                 /// # }
316                 /// ```
317                 #[unstable(feature = "nonzero_ops", issue = "84186")]
318                 #[inline]
319                 pub const fn checked_add(self, other: $Int) -> Option<$Ty> {
320                     if let Some(result) = self.get().checked_add(other) {
321                         // SAFETY: $Int::checked_add returns None on overflow
322                         // so the result cannot be zero.
323                         Some(unsafe { $Ty::new_unchecked(result) })
324                     } else {
325                         None
326                     }
327                 }
328
329                 /// Add an unsigned integer to a non-zero value.
330                 #[doc = concat!("Return [`", stringify!($Int), "::MAX`] on overflow.")]
331                 ///
332                 /// # Examples
333                 ///
334                 /// ```
335                 /// #![feature(nonzero_ops)]
336                 #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
337                 ///
338                 /// # fn main() { test().unwrap(); }
339                 /// # fn test() -> Option<()> {
340                 #[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")]
341                 #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
342                 #[doc = concat!("let max = ", stringify!($Ty), "::new(",
343                                 stringify!($Int), "::MAX)?;")]
344                 ///
345                 /// assert_eq!(two, one.saturating_add(1));
346                 /// assert_eq!(max, max.saturating_add(1));
347                 /// # Some(())
348                 /// # }
349                 /// ```
350                 #[unstable(feature = "nonzero_ops", issue = "84186")]
351                 #[inline]
352                 pub const fn saturating_add(self, other: $Int) -> $Ty {
353                     // SAFETY: $Int::saturating_add returns $Int::MAX on overflow
354                     // so the result cannot be zero.
355                     unsafe { $Ty::new_unchecked(self.get().saturating_add(other)) }
356                 }
357
358                 /// Add an unsigned integer to a non-zero value,
359                 /// assuming overflow cannot occur.
360                 /// Overflow is unchecked, and it is undefined behaviour to overflow
361                 /// *even if the result would wrap to a non-zero value*.
362                 /// The behaviour is undefined as soon as
363                 #[doc = concat!("`self + rhs > ", stringify!($Int), "::MAX`.")]
364                 ///
365                 /// # Examples
366                 ///
367                 /// ```
368                 /// #![feature(nonzero_ops)]
369                 #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
370                 ///
371                 /// # fn main() { test().unwrap(); }
372                 /// # fn test() -> Option<()> {
373                 #[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")]
374                 #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
375                 ///
376                 /// assert_eq!(two, unsafe { one.unchecked_add(1) });
377                 /// # Some(())
378                 /// # }
379                 /// ```
380                 #[unstable(feature = "nonzero_ops", issue = "84186")]
381                 #[inline]
382                 pub unsafe fn unchecked_add(self, other: $Int) -> $Ty {
383                     // SAFETY: The caller ensures there is no overflow.
384                     unsafe { $Ty::new_unchecked(self.get().unchecked_add(other)) }
385                 }
386
387                 /// Returns the smallest power of two greater than or equal to n.
388                 /// Check for overflow and return [`None`]
389                 /// if the next power of two is greater than the type’s maximum value.
390                 /// As a consequence, the result cannot wrap to zero.
391                 ///
392                 /// # Examples
393                 ///
394                 /// ```
395                 /// #![feature(nonzero_ops)]
396                 #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
397                 ///
398                 /// # fn main() { test().unwrap(); }
399                 /// # fn test() -> Option<()> {
400                 #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
401                 #[doc = concat!("let three = ", stringify!($Ty), "::new(3)?;")]
402                 #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
403                 #[doc = concat!("let max = ", stringify!($Ty), "::new(",
404                                 stringify!($Int), "::MAX)?;")]
405                 ///
406                 /// assert_eq!(Some(two), two.checked_next_power_of_two() );
407                 /// assert_eq!(Some(four), three.checked_next_power_of_two() );
408                 /// assert_eq!(None, max.checked_next_power_of_two() );
409                 /// # Some(())
410                 /// # }
411                 /// ```
412                 #[unstable(feature = "nonzero_ops", issue = "84186")]
413                 #[inline]
414                 pub const fn checked_next_power_of_two(self) -> Option<$Ty> {
415                     if let Some(nz) = self.get().checked_next_power_of_two() {
416                         // SAFETY: The next power of two is positive
417                         // and overflow is checked.
418                         Some(unsafe { $Ty::new_unchecked(nz) })
419                     } else {
420                         None
421                     }
422                 }
423             }
424         )+
425     }
426 }
427
428 nonzero_unsigned_operations! {
429     NonZeroU8(u8);
430     NonZeroU16(u16);
431     NonZeroU32(u32);
432     NonZeroU64(u64);
433     NonZeroU128(u128);
434     NonZeroUsize(usize);
435 }
436
437 // A bunch of methods for signed nonzero types only.
438 macro_rules! nonzero_signed_operations {
439     ( $( $Ty: ident($Int: ty) -> $Uty: ident($Uint: ty); )+ ) => {
440         $(
441             impl $Ty {
442                 /// Computes the absolute value of self.
443                 #[doc = concat!("See [`", stringify!($Int), "::abs`]")]
444                 /// for documentation on overflow behaviour.
445                 ///
446                 /// # Example
447                 ///
448                 /// ```
449                 /// #![feature(nonzero_ops)]
450                 #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
451                 ///
452                 /// # fn main() { test().unwrap(); }
453                 /// # fn test() -> Option<()> {
454                 #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
455                 #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
456                 ///
457                 /// assert_eq!(pos, pos.abs());
458                 /// assert_eq!(pos, neg.abs());
459                 /// # Some(())
460                 /// # }
461                 /// ```
462                 #[unstable(feature = "nonzero_ops", issue = "84186")]
463                 #[inline]
464                 pub const fn abs(self) -> $Ty {
465                     // SAFETY: This cannot overflow to zero.
466                     unsafe { $Ty::new_unchecked(self.get().abs()) }
467                 }
468
469                 /// Checked absolute value.
470                 /// Check for overflow and returns [`None`] if
471                 #[doc = concat!("`self == ", stringify!($Int), "::MIN`.")]
472                 /// The result cannot be zero.
473                 ///
474                 /// # Example
475                 ///
476                 /// ```
477                 /// #![feature(nonzero_ops)]
478                 #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
479                 ///
480                 /// # fn main() { test().unwrap(); }
481                 /// # fn test() -> Option<()> {
482                 #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
483                 #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
484                 #[doc = concat!("let min = ", stringify!($Ty), "::new(",
485                                 stringify!($Int), "::MIN)?;")]
486                 ///
487                 /// assert_eq!(Some(pos), neg.checked_abs());
488                 /// assert_eq!(None, min.checked_abs());
489                 /// # Some(())
490                 /// # }
491                 /// ```
492                 #[unstable(feature = "nonzero_ops", issue = "84186")]
493                 #[inline]
494                 pub const fn checked_abs(self) -> Option<$Ty> {
495                     if let Some(nz) = self.get().checked_abs() {
496                         // SAFETY: absolute value of nonzero cannot yield zero values.
497                         Some(unsafe { $Ty::new_unchecked(nz) })
498                     } else {
499                         None
500                     }
501                 }
502
503                 /// Computes the absolute value of self,
504                 /// with overflow information, see
505                 #[doc = concat!("[`", stringify!($Int), "::overflowing_abs`].")]
506                 ///
507                 /// # Example
508                 ///
509                 /// ```
510                 /// #![feature(nonzero_ops)]
511                 #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
512                 ///
513                 /// # fn main() { test().unwrap(); }
514                 /// # fn test() -> Option<()> {
515                 #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
516                 #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
517                 #[doc = concat!("let min = ", stringify!($Ty), "::new(",
518                                 stringify!($Int), "::MIN)?;")]
519                 ///
520                 /// assert_eq!((pos, false), pos.overflowing_abs());
521                 /// assert_eq!((pos, false), neg.overflowing_abs());
522                 /// assert_eq!((min, true), min.overflowing_abs());
523                 /// # Some(())
524                 /// # }
525                 /// ```
526                 #[unstable(feature = "nonzero_ops", issue = "84186")]
527                 #[inline]
528                 pub const fn overflowing_abs(self) -> ($Ty, bool) {
529                     let (nz, flag) = self.get().overflowing_abs();
530                     (
531                         // SAFETY: absolute value of nonzero cannot yield zero values.
532                         unsafe { $Ty::new_unchecked(nz) },
533                         flag,
534                     )
535                 }
536
537                 /// Saturating absolute value, see
538                 #[doc = concat!("[`", stringify!($Int), "::saturating_abs`].")]
539                 ///
540                 /// # Example
541                 ///
542                 /// ```
543                 /// #![feature(nonzero_ops)]
544                 #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
545                 ///
546                 /// # fn main() { test().unwrap(); }
547                 /// # fn test() -> Option<()> {
548                 #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
549                 #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
550                 #[doc = concat!("let min = ", stringify!($Ty), "::new(",
551                                 stringify!($Int), "::MIN)?;")]
552                 #[doc = concat!("let min_plus = ", stringify!($Ty), "::new(",
553                                 stringify!($Int), "::MIN + 1)?;")]
554                 #[doc = concat!("let max = ", stringify!($Ty), "::new(",
555                                 stringify!($Int), "::MAX)?;")]
556                 ///
557                 /// assert_eq!(pos, pos.saturating_abs());
558                 /// assert_eq!(pos, neg.saturating_abs());
559                 /// assert_eq!(max, min.saturating_abs());
560                 /// assert_eq!(max, min_plus.saturating_abs());
561                 /// # Some(())
562                 /// # }
563                 /// ```
564                 #[unstable(feature = "nonzero_ops", issue = "84186")]
565                 #[inline]
566                 pub const fn saturating_abs(self) -> $Ty {
567                     // SAFETY: absolute value of nonzero cannot yield zero values.
568                     unsafe { $Ty::new_unchecked(self.get().saturating_abs()) }
569                 }
570
571                 /// Wrapping absolute value, see
572                 #[doc = concat!("[`", stringify!($Int), "::wrapping_abs`].")]
573                 ///
574                 /// # Example
575                 ///
576                 /// ```
577                 /// #![feature(nonzero_ops)]
578                 #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
579                 ///
580                 /// # fn main() { test().unwrap(); }
581                 /// # fn test() -> Option<()> {
582                 #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
583                 #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
584                 #[doc = concat!("let min = ", stringify!($Ty), "::new(",
585                                 stringify!($Int), "::MIN)?;")]
586                 #[doc = concat!("let max = ", stringify!($Ty), "::new(",
587                                 stringify!($Int), "::MAX)?;")]
588                 ///
589                 /// assert_eq!(pos, pos.wrapping_abs());
590                 /// assert_eq!(pos, neg.wrapping_abs());
591                 /// assert_eq!(min, min.wrapping_abs());
592                 /// # // FIXME: add once Neg is implemented?
593                 /// # // assert_eq!(max, (-max).wrapping_abs());
594                 /// # Some(())
595                 /// # }
596                 /// ```
597                 #[unstable(feature = "nonzero_ops", issue = "84186")]
598                 #[inline]
599                 pub const fn wrapping_abs(self) -> $Ty {
600                     // SAFETY: absolute value of nonzero cannot yield zero values.
601                     unsafe { $Ty::new_unchecked(self.get().wrapping_abs()) }
602                 }
603
604                 /// Computes the absolute value of self
605                 /// without any wrapping or panicking.
606                 ///
607                 /// # Example
608                 ///
609                 /// ```
610                 /// #![feature(nonzero_ops)]
611                 #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
612                 #[doc = concat!("# use std::num::", stringify!($Uty), ";")]
613                 ///
614                 /// # fn main() { test().unwrap(); }
615                 /// # fn test() -> Option<()> {
616                 #[doc = concat!("let u_pos = ", stringify!($Uty), "::new(1)?;")]
617                 #[doc = concat!("let i_pos = ", stringify!($Ty), "::new(1)?;")]
618                 #[doc = concat!("let i_neg = ", stringify!($Ty), "::new(-1)?;")]
619                 #[doc = concat!("let i_min = ", stringify!($Ty), "::new(",
620                                 stringify!($Int), "::MIN)?;")]
621                 #[doc = concat!("let u_max = ", stringify!($Uty), "::new(",
622                                 stringify!($Uint), "::MAX / 2 + 1)?;")]
623                 ///
624                 /// assert_eq!(u_pos, i_pos.unsigned_abs());
625                 /// assert_eq!(u_pos, i_neg.unsigned_abs());
626                 /// assert_eq!(u_max, i_min.unsigned_abs());
627                 /// # Some(())
628                 /// # }
629                 /// ```
630                 #[unstable(feature = "nonzero_ops", issue = "84186")]
631                 #[inline]
632                 pub const fn unsigned_abs(self) -> $Uty {
633                     // SAFETY: absolute value of nonzero cannot yield zero values.
634                     unsafe { $Uty::new_unchecked(self.get().unsigned_abs()) }
635                 }
636             }
637         )+
638     }
639 }
640
641 nonzero_signed_operations! {
642     NonZeroI8(i8) -> NonZeroU8(u8);
643     NonZeroI16(i16) -> NonZeroU16(u16);
644     NonZeroI32(i32) -> NonZeroU32(u32);
645     NonZeroI64(i64) -> NonZeroU64(u64);
646     NonZeroI128(i128) -> NonZeroU128(u128);
647     NonZeroIsize(isize) -> NonZeroUsize(usize);
648 }
649
650 // A bunch of methods for both signed and unsigned nonzero types.
651 macro_rules! nonzero_unsigned_signed_operations {
652     ( $( $signedness:ident $Ty: ident($Int: ty); )+ ) => {
653         $(
654             impl $Ty {
655                 /// Multiply two non-zero integers together.
656                 /// Check for overflow and return [`None`] on overflow.
657                 /// As a consequence, the result cannot wrap to zero.
658                 ///
659                 /// # Examples
660                 ///
661                 /// ```
662                 /// #![feature(nonzero_ops)]
663                 #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
664                 ///
665                 /// # fn main() { test().unwrap(); }
666                 /// # fn test() -> Option<()> {
667                 #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
668                 #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
669                 #[doc = concat!("let max = ", stringify!($Ty), "::new(",
670                                 stringify!($Int), "::MAX)?;")]
671                 ///
672                 /// assert_eq!(Some(four), two.checked_mul(two));
673                 /// assert_eq!(None, max.checked_mul(two));
674                 /// # Some(())
675                 /// # }
676                 /// ```
677                 #[unstable(feature = "nonzero_ops", issue = "84186")]
678                 #[inline]
679                 pub const fn checked_mul(self, other: $Ty) -> Option<$Ty> {
680                     if let Some(result) = self.get().checked_mul(other.get()) {
681                         // SAFETY: checked_mul returns None on overflow
682                         // and `other` is also non-null
683                         // so the result cannot be zero.
684                         Some(unsafe { $Ty::new_unchecked(result) })
685                     } else {
686                         None
687                     }
688                 }
689
690                 /// Multiply two non-zero integers together.
691                 #[doc = concat!("Return [`", stringify!($Int), "::MAX`] on overflow.")]
692                 ///
693                 /// # Examples
694                 ///
695                 /// ```
696                 /// #![feature(nonzero_ops)]
697                 #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
698                 ///
699                 /// # fn main() { test().unwrap(); }
700                 /// # fn test() -> Option<()> {
701                 #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
702                 #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
703                 #[doc = concat!("let max = ", stringify!($Ty), "::new(",
704                                 stringify!($Int), "::MAX)?;")]
705                 ///
706                 /// assert_eq!(four, two.saturating_mul(two));
707                 /// assert_eq!(max, four.saturating_mul(max));
708                 /// # Some(())
709                 /// # }
710                 /// ```
711                 #[unstable(feature = "nonzero_ops", issue = "84186")]
712                 #[inline]
713                 pub const fn saturating_mul(self, other: $Ty) -> $Ty {
714                     // SAFETY: saturating_mul returns u*::MAX on overflow
715                     // and `other` is also non-null
716                     // so the result cannot be zero.
717                     unsafe { $Ty::new_unchecked(self.get().saturating_mul(other.get())) }
718                 }
719
720                 /// Multiply two non-zero integers together,
721                 /// assuming overflow cannot occur.
722                 /// Overflow is unchecked, and it is undefined behaviour to overflow
723                 /// *even if the result would wrap to a non-zero value*.
724                 /// The behaviour is undefined as soon as
725                 #[doc = sign_dependent_expr!{
726                     $signedness ?
727                     if signed {
728                         concat!("`self * rhs > ", stringify!($Int), "::MAX`, ",
729                                 "or `self * rhs < ", stringify!($Int), "::MIN`.")
730                     }
731                     if unsigned {
732                         concat!("`self * rhs > ", stringify!($Int), "::MAX`.")
733                     }
734                 }]
735                 ///
736                 /// # Examples
737                 ///
738                 /// ```
739                 /// #![feature(nonzero_ops)]
740                 #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
741                 ///
742                 /// # fn main() { test().unwrap(); }
743                 /// # fn test() -> Option<()> {
744                 #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
745                 #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
746                 ///
747                 /// assert_eq!(four, unsafe { two.unchecked_mul(two) });
748                 /// # Some(())
749                 /// # }
750                 /// ```
751                 #[unstable(feature = "nonzero_ops", issue = "84186")]
752                 #[inline]
753                 pub unsafe fn unchecked_mul(self, other: $Ty) -> $Ty {
754                     // SAFETY: The caller ensures there is no overflow.
755                     unsafe { $Ty::new_unchecked(self.get().unchecked_mul(other.get())) }
756                 }
757
758                 /// Raise non-zero value to an integer power.
759                 /// Check for overflow and return [`None`] on overflow.
760                 /// As a consequence, the result cannot wrap to zero.
761                 ///
762                 /// # Examples
763                 ///
764                 /// ```
765                 /// #![feature(nonzero_ops)]
766                 #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
767                 ///
768                 /// # fn main() { test().unwrap(); }
769                 /// # fn test() -> Option<()> {
770                 #[doc = concat!("let three = ", stringify!($Ty), "::new(3)?;")]
771                 #[doc = concat!("let twenty_seven = ", stringify!($Ty), "::new(27)?;")]
772                 #[doc = concat!("let half_max = ", stringify!($Ty), "::new(",
773                                 stringify!($Int), "::MAX / 2)?;")]
774                 ///
775                 /// assert_eq!(Some(twenty_seven), three.checked_pow(3));
776                 /// assert_eq!(None, half_max.checked_pow(3));
777                 /// # Some(())
778                 /// # }
779                 /// ```
780                 #[unstable(feature = "nonzero_ops", issue = "84186")]
781                 #[inline]
782                 pub const fn checked_pow(self, other: u32) -> Option<$Ty> {
783                     if let Some(result) = self.get().checked_pow(other) {
784                         // SAFETY: checked_pow returns None on overflow
785                         // so the result cannot be zero.
786                         Some(unsafe { $Ty::new_unchecked(result) })
787                     } else {
788                         None
789                     }
790                 }
791
792                 /// Raise non-zero value to an integer power.
793                 #[doc = sign_dependent_expr!{
794                     $signedness ?
795                     if signed {
796                         concat!("Return [`", stringify!($Int), "::MIN`] ",
797                                     "or [`", stringify!($Int), "::MAX`] on overflow.")
798                     }
799                     if unsigned {
800                         concat!("Return [`", stringify!($Int), "::MAX`] on overflow.")
801                     }
802                 }]
803                 ///
804                 /// # Examples
805                 ///
806                 /// ```
807                 /// #![feature(nonzero_ops)]
808                 #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
809                 ///
810                 /// # fn main() { test().unwrap(); }
811                 /// # fn test() -> Option<()> {
812                 #[doc = concat!("let three = ", stringify!($Ty), "::new(3)?;")]
813                 #[doc = concat!("let twenty_seven = ", stringify!($Ty), "::new(27)?;")]
814                 #[doc = concat!("let max = ", stringify!($Ty), "::new(",
815                                 stringify!($Int), "::MAX)?;")]
816                 ///
817                 /// assert_eq!(twenty_seven, three.saturating_pow(3));
818                 /// assert_eq!(max, max.saturating_pow(3));
819                 /// # Some(())
820                 /// # }
821                 /// ```
822                 #[unstable(feature = "nonzero_ops", issue = "84186")]
823                 #[inline]
824                 pub const fn saturating_pow(self, other: u32) -> $Ty {
825                     // SAFETY: saturating_pow returns u*::MAX on overflow
826                     // so the result cannot be zero.
827                     unsafe { $Ty::new_unchecked(self.get().saturating_pow(other)) }
828                 }
829             }
830         )+
831     }
832 }
833
834 // Use this when the generated code should differ between signed and unsigned types.
835 macro_rules! sign_dependent_expr {
836     (signed ? if signed { $signed_case:expr } if unsigned { $unsigned_case:expr } ) => {
837         $signed_case
838     };
839     (unsigned ? if signed { $signed_case:expr } if unsigned { $unsigned_case:expr } ) => {
840         $unsigned_case
841     };
842 }
843
844 nonzero_unsigned_signed_operations! {
845     unsigned NonZeroU8(u8);
846     unsigned NonZeroU16(u16);
847     unsigned NonZeroU32(u32);
848     unsigned NonZeroU64(u64);
849     unsigned NonZeroU128(u128);
850     unsigned NonZeroUsize(usize);
851     signed NonZeroI8(i8);
852     signed NonZeroI16(i16);
853     signed NonZeroI32(i32);
854     signed NonZeroI64(i64);
855     signed NonZeroI128(i128);
856     signed NonZeroIsize(isize);
857 }
858
859 macro_rules! nonzero_unsigned_is_power_of_two {
860     ( $( $Ty: ident )+ ) => {
861         $(
862             impl $Ty {
863
864                 /// Returns `true` if and only if `self == (1 << k)` for some `k`.
865                 ///
866                 /// On many architectures, this function can perform better than `is_power_of_two()`
867                 /// on the underlying integer type, as special handling of zero can be avoided.
868                 ///
869                 /// # Examples
870                 ///
871                 /// Basic usage:
872                 ///
873                 /// ```
874                 /// #![feature(nonzero_is_power_of_two)]
875                 ///
876                 #[doc = concat!("let eight = std::num::", stringify!($Ty), "::new(8).unwrap();")]
877                 /// assert!(eight.is_power_of_two());
878                 #[doc = concat!("let ten = std::num::", stringify!($Ty), "::new(10).unwrap();")]
879                 /// assert!(!ten.is_power_of_two());
880                 /// ```
881                 #[unstable(feature = "nonzero_is_power_of_two", issue = "81106")]
882                 #[inline]
883                 pub const fn is_power_of_two(self) -> bool {
884                     // LLVM 11 normalizes `unchecked_sub(x, 1) & x == 0` to the implementation seen here.
885                     // On the basic x86-64 target, this saves 3 instructions for the zero check.
886                     // On x86_64 with BMI1, being nonzero lets it codegen to `BLSR`, which saves an instruction
887                     // compared to the `POPCNT` implementation on the underlying integer type.
888
889                     intrinsics::ctpop(self.get()) < 2
890                 }
891
892             }
893         )+
894     }
895 }
896
897 nonzero_unsigned_is_power_of_two! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize }