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