1 | //! Definitions of integer that is known not to equal zero. |
2 | |
3 | use super::{IntErrorKind, ParseIntError}; |
4 | use crate::clone::UseCloned; |
5 | use crate::cmp::Ordering; |
6 | use crate::hash::{Hash, Hasher}; |
7 | use crate::marker::{Freeze, StructuralPartialEq}; |
8 | use crate::ops::{BitOr, BitOrAssign, Div, DivAssign, Neg, Rem, RemAssign}; |
9 | use crate::panic::{RefUnwindSafe, UnwindSafe}; |
10 | use crate::str::FromStr; |
11 | use crate::{fmt, intrinsics, ptr, ub_checks}; |
12 | |
13 | /// A marker trait for primitive types which can be zero. |
14 | /// |
15 | /// This is an implementation detail for <code>[NonZero]\<T></code> which may disappear or be replaced at any time. |
16 | /// |
17 | /// # Safety |
18 | /// |
19 | /// Types implementing this trait must be primitives that are valid when zeroed. |
20 | /// |
21 | /// The associated `Self::NonZeroInner` type must have the same size+align as `Self`, |
22 | /// but with a niche and bit validity making it so the following `transmutes` are sound: |
23 | /// |
24 | /// - `Self::NonZeroInner` to `Option<Self::NonZeroInner>` |
25 | /// - `Option<Self::NonZeroInner>` to `Self` |
26 | /// |
27 | /// (And, consequently, `Self::NonZeroInner` to `Self`.) |
28 | #[unstable ( |
29 | feature = "nonzero_internals" , |
30 | reason = "implementation detail which may disappear or be replaced at any time" , |
31 | issue = "none" |
32 | )] |
33 | pub unsafe trait ZeroablePrimitive: Sized + Copy + private::Sealed { |
34 | #[doc (hidden)] |
35 | type NonZeroInner: Sized + Copy; |
36 | } |
37 | |
38 | macro_rules! impl_zeroable_primitive { |
39 | ($($NonZeroInner:ident ( $primitive:ty )),+ $(,)?) => { |
40 | mod private { |
41 | #[unstable( |
42 | feature = "nonzero_internals" , |
43 | reason = "implementation detail which may disappear or be replaced at any time" , |
44 | issue = "none" |
45 | )] |
46 | pub trait Sealed {} |
47 | } |
48 | |
49 | $( |
50 | #[unstable( |
51 | feature = "nonzero_internals" , |
52 | reason = "implementation detail which may disappear or be replaced at any time" , |
53 | issue = "none" |
54 | )] |
55 | impl private::Sealed for $primitive {} |
56 | |
57 | #[unstable( |
58 | feature = "nonzero_internals" , |
59 | reason = "implementation detail which may disappear or be replaced at any time" , |
60 | issue = "none" |
61 | )] |
62 | unsafe impl ZeroablePrimitive for $primitive { |
63 | type NonZeroInner = super::niche_types::$NonZeroInner; |
64 | } |
65 | )+ |
66 | }; |
67 | } |
68 | |
69 | impl_zeroable_primitive!( |
70 | NonZeroU8Inner(u8), |
71 | NonZeroU16Inner(u16), |
72 | NonZeroU32Inner(u32), |
73 | NonZeroU64Inner(u64), |
74 | NonZeroU128Inner(u128), |
75 | NonZeroUsizeInner(usize), |
76 | NonZeroI8Inner(i8), |
77 | NonZeroI16Inner(i16), |
78 | NonZeroI32Inner(i32), |
79 | NonZeroI64Inner(i64), |
80 | NonZeroI128Inner(i128), |
81 | NonZeroIsizeInner(isize), |
82 | ); |
83 | |
84 | /// A value that is known not to equal zero. |
85 | /// |
86 | /// This enables some memory layout optimization. |
87 | /// For example, `Option<NonZero<u32>>` is the same size as `u32`: |
88 | /// |
89 | /// ``` |
90 | /// use core::{num::NonZero}; |
91 | /// |
92 | /// assert_eq!(size_of::<Option<NonZero<u32>>>(), size_of::<u32>()); |
93 | /// ``` |
94 | /// |
95 | /// # Layout |
96 | /// |
97 | /// `NonZero<T>` is guaranteed to have the same layout and bit validity as `T` |
98 | /// with the exception that the all-zero bit pattern is invalid. |
99 | /// `Option<NonZero<T>>` is guaranteed to be compatible with `T`, including in |
100 | /// FFI. |
101 | /// |
102 | /// Thanks to the [null pointer optimization], `NonZero<T>` and |
103 | /// `Option<NonZero<T>>` are guaranteed to have the same size and alignment: |
104 | /// |
105 | /// ``` |
106 | /// use std::num::NonZero; |
107 | /// |
108 | /// assert_eq!(size_of::<NonZero<u32>>(), size_of::<Option<NonZero<u32>>>()); |
109 | /// assert_eq!(align_of::<NonZero<u32>>(), align_of::<Option<NonZero<u32>>>()); |
110 | /// ``` |
111 | /// |
112 | /// [null pointer optimization]: crate::option#representation |
113 | #[stable (feature = "generic_nonzero" , since = "1.79.0" )] |
114 | #[repr (transparent)] |
115 | #[rustc_nonnull_optimization_guaranteed ] |
116 | #[rustc_diagnostic_item = "NonZero" ] |
117 | pub struct NonZero<T: ZeroablePrimitive>(T::NonZeroInner); |
118 | |
119 | macro_rules! impl_nonzero_fmt { |
120 | ($(#[$Attribute:meta] $Trait:ident)*) => { |
121 | $( |
122 | #[$Attribute] |
123 | impl<T> fmt::$Trait for NonZero<T> |
124 | where |
125 | T: ZeroablePrimitive + fmt::$Trait, |
126 | { |
127 | #[inline] |
128 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
129 | self.get().fmt(f) |
130 | } |
131 | } |
132 | )* |
133 | }; |
134 | } |
135 | |
136 | impl_nonzero_fmt! { |
137 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
138 | Debug |
139 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
140 | Display |
141 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
142 | Binary |
143 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
144 | Octal |
145 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
146 | LowerHex |
147 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
148 | UpperHex |
149 | #[stable (feature = "nonzero_fmt_exp" , since = "1.84.0" )] |
150 | LowerExp |
151 | #[stable (feature = "nonzero_fmt_exp" , since = "1.84.0" )] |
152 | UpperExp |
153 | } |
154 | |
155 | macro_rules! impl_nonzero_auto_trait { |
156 | (unsafe $Trait:ident) => { |
157 | #[stable(feature = "nonzero" , since = "1.28.0" )] |
158 | unsafe impl<T> $Trait for NonZero<T> where T: ZeroablePrimitive + $Trait {} |
159 | }; |
160 | ($Trait:ident) => { |
161 | #[stable(feature = "nonzero" , since = "1.28.0" )] |
162 | impl<T> $Trait for NonZero<T> where T: ZeroablePrimitive + $Trait {} |
163 | }; |
164 | } |
165 | |
166 | // Implement auto-traits manually based on `T` to avoid docs exposing |
167 | // the `ZeroablePrimitive::NonZeroInner` implementation detail. |
168 | impl_nonzero_auto_trait!(unsafe Freeze); |
169 | impl_nonzero_auto_trait!(RefUnwindSafe); |
170 | impl_nonzero_auto_trait!(unsafe Send); |
171 | impl_nonzero_auto_trait!(unsafe Sync); |
172 | impl_nonzero_auto_trait!(Unpin); |
173 | impl_nonzero_auto_trait!(UnwindSafe); |
174 | |
175 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
176 | impl<T> Clone for NonZero<T> |
177 | where |
178 | T: ZeroablePrimitive, |
179 | { |
180 | #[inline ] |
181 | fn clone(&self) -> Self { |
182 | *self |
183 | } |
184 | } |
185 | |
186 | #[unstable (feature = "ergonomic_clones" , issue = "132290" )] |
187 | impl<T> UseCloned for NonZero<T> where T: ZeroablePrimitive {} |
188 | |
189 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
190 | impl<T> Copy for NonZero<T> where T: ZeroablePrimitive {} |
191 | |
192 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
193 | impl<T> PartialEq for NonZero<T> |
194 | where |
195 | T: ZeroablePrimitive + PartialEq, |
196 | { |
197 | #[inline ] |
198 | fn eq(&self, other: &Self) -> bool { |
199 | self.get() == other.get() |
200 | } |
201 | |
202 | #[inline ] |
203 | fn ne(&self, other: &Self) -> bool { |
204 | self.get() != other.get() |
205 | } |
206 | } |
207 | |
208 | #[unstable (feature = "structural_match" , issue = "31434" )] |
209 | impl<T> StructuralPartialEq for NonZero<T> where T: ZeroablePrimitive + StructuralPartialEq {} |
210 | |
211 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
212 | impl<T> Eq for NonZero<T> where T: ZeroablePrimitive + Eq {} |
213 | |
214 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
215 | impl<T> PartialOrd for NonZero<T> |
216 | where |
217 | T: ZeroablePrimitive + PartialOrd, |
218 | { |
219 | #[inline ] |
220 | fn partial_cmp(&self, other: &Self) -> Option<Ordering> { |
221 | self.get().partial_cmp(&other.get()) |
222 | } |
223 | |
224 | #[inline ] |
225 | fn lt(&self, other: &Self) -> bool { |
226 | self.get() < other.get() |
227 | } |
228 | |
229 | #[inline ] |
230 | fn le(&self, other: &Self) -> bool { |
231 | self.get() <= other.get() |
232 | } |
233 | |
234 | #[inline ] |
235 | fn gt(&self, other: &Self) -> bool { |
236 | self.get() > other.get() |
237 | } |
238 | |
239 | #[inline ] |
240 | fn ge(&self, other: &Self) -> bool { |
241 | self.get() >= other.get() |
242 | } |
243 | } |
244 | |
245 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
246 | impl<T> Ord for NonZero<T> |
247 | where |
248 | T: ZeroablePrimitive + Ord, |
249 | { |
250 | #[inline ] |
251 | fn cmp(&self, other: &Self) -> Ordering { |
252 | self.get().cmp(&other.get()) |
253 | } |
254 | |
255 | #[inline ] |
256 | fn max(self, other: Self) -> Self { |
257 | // SAFETY: The maximum of two non-zero values is still non-zero. |
258 | unsafe { Self::new_unchecked(self.get().max(other.get())) } |
259 | } |
260 | |
261 | #[inline ] |
262 | fn min(self, other: Self) -> Self { |
263 | // SAFETY: The minimum of two non-zero values is still non-zero. |
264 | unsafe { Self::new_unchecked(self.get().min(other.get())) } |
265 | } |
266 | |
267 | #[inline ] |
268 | fn clamp(self, min: Self, max: Self) -> Self { |
269 | // SAFETY: A non-zero value clamped between two non-zero values is still non-zero. |
270 | unsafe { Self::new_unchecked(self.get().clamp(min.get(), max.get())) } |
271 | } |
272 | } |
273 | |
274 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
275 | impl<T> Hash for NonZero<T> |
276 | where |
277 | T: ZeroablePrimitive + Hash, |
278 | { |
279 | #[inline ] |
280 | fn hash<H>(&self, state: &mut H) |
281 | where |
282 | H: Hasher, |
283 | { |
284 | self.get().hash(state) |
285 | } |
286 | } |
287 | |
288 | #[stable (feature = "from_nonzero" , since = "1.31.0" )] |
289 | impl<T> From<NonZero<T>> for T |
290 | where |
291 | T: ZeroablePrimitive, |
292 | { |
293 | #[inline ] |
294 | fn from(nonzero: NonZero<T>) -> Self { |
295 | // Call `get` method to keep range information. |
296 | nonzero.get() |
297 | } |
298 | } |
299 | |
300 | #[stable (feature = "nonzero_bitor" , since = "1.45.0" )] |
301 | impl<T> BitOr for NonZero<T> |
302 | where |
303 | T: ZeroablePrimitive + BitOr<Output = T>, |
304 | { |
305 | type Output = Self; |
306 | |
307 | #[inline ] |
308 | fn bitor(self, rhs: Self) -> Self::Output { |
309 | // SAFETY: Bitwise OR of two non-zero values is still non-zero. |
310 | unsafe { Self::new_unchecked(self.get() | rhs.get()) } |
311 | } |
312 | } |
313 | |
314 | #[stable (feature = "nonzero_bitor" , since = "1.45.0" )] |
315 | impl<T> BitOr<T> for NonZero<T> |
316 | where |
317 | T: ZeroablePrimitive + BitOr<Output = T>, |
318 | { |
319 | type Output = Self; |
320 | |
321 | #[inline ] |
322 | fn bitor(self, rhs: T) -> Self::Output { |
323 | // SAFETY: Bitwise OR of a non-zero value with anything is still non-zero. |
324 | unsafe { Self::new_unchecked(self.get() | rhs) } |
325 | } |
326 | } |
327 | |
328 | #[stable (feature = "nonzero_bitor" , since = "1.45.0" )] |
329 | impl<T> BitOr<NonZero<T>> for T |
330 | where |
331 | T: ZeroablePrimitive + BitOr<Output = T>, |
332 | { |
333 | type Output = NonZero<T>; |
334 | |
335 | #[inline ] |
336 | fn bitor(self, rhs: NonZero<T>) -> Self::Output { |
337 | // SAFETY: Bitwise OR of anything with a non-zero value is still non-zero. |
338 | unsafe { NonZero::new_unchecked(self | rhs.get()) } |
339 | } |
340 | } |
341 | |
342 | #[stable (feature = "nonzero_bitor" , since = "1.45.0" )] |
343 | impl<T> BitOrAssign for NonZero<T> |
344 | where |
345 | T: ZeroablePrimitive, |
346 | Self: BitOr<Output = Self>, |
347 | { |
348 | #[inline ] |
349 | fn bitor_assign(&mut self, rhs: Self) { |
350 | *self = *self | rhs; |
351 | } |
352 | } |
353 | |
354 | #[stable (feature = "nonzero_bitor" , since = "1.45.0" )] |
355 | impl<T> BitOrAssign<T> for NonZero<T> |
356 | where |
357 | T: ZeroablePrimitive, |
358 | Self: BitOr<T, Output = Self>, |
359 | { |
360 | #[inline ] |
361 | fn bitor_assign(&mut self, rhs: T) { |
362 | *self = *self | rhs; |
363 | } |
364 | } |
365 | |
366 | impl<T> NonZero<T> |
367 | where |
368 | T: ZeroablePrimitive, |
369 | { |
370 | /// Creates a non-zero if the given value is not zero. |
371 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
372 | #[rustc_const_stable (feature = "const_nonzero_int_methods" , since = "1.47.0" )] |
373 | #[must_use ] |
374 | #[inline ] |
375 | pub const fn new(n: T) -> Option<Self> { |
376 | // SAFETY: Memory layout optimization guarantees that `Option<NonZero<T>>` has |
377 | // the same layout and size as `T`, with `0` representing `None`. |
378 | unsafe { intrinsics::transmute_unchecked(n) } |
379 | } |
380 | |
381 | /// Creates a non-zero without checking whether the value is non-zero. |
382 | /// This results in undefined behavior if the value is zero. |
383 | /// |
384 | /// # Safety |
385 | /// |
386 | /// The value must not be zero. |
387 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
388 | #[rustc_const_stable (feature = "nonzero" , since = "1.28.0" )] |
389 | #[must_use ] |
390 | #[inline ] |
391 | pub const unsafe fn new_unchecked(n: T) -> Self { |
392 | match Self::new(n) { |
393 | Some(n) => n, |
394 | None => { |
395 | // SAFETY: The caller guarantees that `n` is non-zero, so this is unreachable. |
396 | unsafe { |
397 | ub_checks::assert_unsafe_precondition!( |
398 | check_language_ub, |
399 | "NonZero::new_unchecked requires the argument to be non-zero" , |
400 | () => false, |
401 | ); |
402 | intrinsics::unreachable() |
403 | } |
404 | } |
405 | } |
406 | } |
407 | |
408 | /// Converts a reference to a non-zero mutable reference |
409 | /// if the referenced value is not zero. |
410 | #[unstable (feature = "nonzero_from_mut" , issue = "106290" )] |
411 | #[must_use ] |
412 | #[inline ] |
413 | pub fn from_mut(n: &mut T) -> Option<&mut Self> { |
414 | // SAFETY: Memory layout optimization guarantees that `Option<NonZero<T>>` has |
415 | // the same layout and size as `T`, with `0` representing `None`. |
416 | let opt_n = unsafe { &mut *(ptr::from_mut(n).cast::<Option<Self>>()) }; |
417 | |
418 | opt_n.as_mut() |
419 | } |
420 | |
421 | /// Converts a mutable reference to a non-zero mutable reference |
422 | /// without checking whether the referenced value is non-zero. |
423 | /// This results in undefined behavior if the referenced value is zero. |
424 | /// |
425 | /// # Safety |
426 | /// |
427 | /// The referenced value must not be zero. |
428 | #[unstable (feature = "nonzero_from_mut" , issue = "106290" )] |
429 | #[must_use ] |
430 | #[inline ] |
431 | pub unsafe fn from_mut_unchecked(n: &mut T) -> &mut Self { |
432 | match Self::from_mut(n) { |
433 | Some(n) => n, |
434 | None => { |
435 | // SAFETY: The caller guarantees that `n` references a value that is non-zero, so this is unreachable. |
436 | unsafe { |
437 | ub_checks::assert_unsafe_precondition!( |
438 | check_library_ub, |
439 | "NonZero::from_mut_unchecked requires the argument to dereference as non-zero" , |
440 | () => false, |
441 | ); |
442 | intrinsics::unreachable() |
443 | } |
444 | } |
445 | } |
446 | } |
447 | |
448 | /// Returns the contained value as a primitive type. |
449 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
450 | #[rustc_const_stable (feature = "const_nonzero_get" , since = "1.34.0" )] |
451 | #[inline ] |
452 | pub const fn get(self) -> T { |
453 | // Rustc can set range metadata only if it loads `self` from |
454 | // memory somewhere. If the value of `self` was from by-value argument |
455 | // of some not-inlined function, LLVM don't have range metadata |
456 | // to understand that the value cannot be zero. |
457 | // |
458 | // Using the transmute `assume`s the range at runtime. |
459 | // |
460 | // Even once LLVM supports `!range` metadata for function arguments |
461 | // (see <https://github.com/llvm/llvm-project/issues/76628>), this can't |
462 | // be `.0` because MCP#807 bans field-projecting into `scalar_valid_range` |
463 | // types, and it arguably wouldn't want to be anyway because if this is |
464 | // MIR-inlined, there's no opportunity to put that argument metadata anywhere. |
465 | // |
466 | // The good answer here will eventually be pattern types, which will hopefully |
467 | // allow it to go back to `.0`, maybe with a cast of some sort. |
468 | // |
469 | // SAFETY: `ZeroablePrimitive` guarantees that the size and bit validity |
470 | // of `.0` is such that this transmute is sound. |
471 | unsafe { intrinsics::transmute_unchecked(self) } |
472 | } |
473 | } |
474 | |
475 | macro_rules! nonzero_integer { |
476 | ( |
477 | #[$stability:meta] |
478 | Self = $Ty:ident, |
479 | Primitive = $signedness:ident $Int:ident, |
480 | SignedPrimitive = $Sint:ty, |
481 | UnsignedPrimitive = $Uint:ty, |
482 | |
483 | // Used in doc comments. |
484 | rot = $rot:literal, |
485 | rot_op = $rot_op:literal, |
486 | rot_result = $rot_result:literal, |
487 | swap_op = $swap_op:literal, |
488 | swapped = $swapped:literal, |
489 | reversed = $reversed:literal, |
490 | leading_zeros_test = $leading_zeros_test:expr, |
491 | ) => { |
492 | #[doc = sign_dependent_expr!{ |
493 | $signedness ? |
494 | if signed { |
495 | concat!("An [`" , stringify!($Int), "`] that is known not to equal zero." ) |
496 | } |
497 | if unsigned { |
498 | concat!("A [`" , stringify!($Int), "`] that is known not to equal zero." ) |
499 | } |
500 | }] |
501 | /// |
502 | /// This enables some memory layout optimization. |
503 | #[doc = concat!("For example, `Option<" , stringify!($Ty), ">` is the same size as `" , stringify!($Int), "`:" )] |
504 | /// |
505 | /// ```rust |
506 | #[doc = concat!("assert_eq!(size_of::<Option<core::num::" , stringify!($Ty), ">>(), size_of::<" , stringify!($Int), ">());" )] |
507 | /// ``` |
508 | /// |
509 | /// # Layout |
510 | /// |
511 | #[doc = concat!("`" , stringify!($Ty), "` is guaranteed to have the same layout and bit validity as `" , stringify!($Int), "`" )] |
512 | /// with the exception that `0` is not a valid instance. |
513 | #[doc = concat!("`Option<" , stringify!($Ty), ">` is guaranteed to be compatible with `" , stringify!($Int), "`," )] |
514 | /// including in FFI. |
515 | /// |
516 | /// Thanks to the [null pointer optimization], |
517 | #[doc = concat!("`" , stringify!($Ty), "` and `Option<" , stringify!($Ty), ">`" )] |
518 | /// are guaranteed to have the same size and alignment: |
519 | /// |
520 | /// ``` |
521 | #[doc = concat!("use std::num::" , stringify!($Ty), ";" )] |
522 | /// |
523 | #[doc = concat!("assert_eq!(size_of::<" , stringify!($Ty), ">(), size_of::<Option<" , stringify!($Ty), ">>());" )] |
524 | #[doc = concat!("assert_eq!(align_of::<" , stringify!($Ty), ">(), align_of::<Option<" , stringify!($Ty), ">>());" )] |
525 | /// ``` |
526 | /// |
527 | /// [null pointer optimization]: crate::option#representation |
528 | #[$stability] |
529 | pub type $Ty = NonZero<$Int>; |
530 | |
531 | impl NonZero<$Int> { |
532 | /// The size of this non-zero integer type in bits. |
533 | /// |
534 | #[doc = concat!("This value is equal to [`" , stringify!($Int), "::BITS`]." )] |
535 | /// |
536 | /// # Examples |
537 | /// |
538 | /// ``` |
539 | /// # use std::num::NonZero; |
540 | /// # |
541 | #[doc = concat!("assert_eq!(NonZero::<" , stringify!($Int), ">::BITS, " , stringify!($Int), "::BITS);" )] |
542 | /// ``` |
543 | #[stable(feature = "nonzero_bits" , since = "1.67.0" )] |
544 | pub const BITS: u32 = <$Int>::BITS; |
545 | |
546 | /// Returns the number of leading zeros in the binary representation of `self`. |
547 | /// |
548 | /// On many architectures, this function can perform better than `leading_zeros()` on the underlying integer type, as special handling of zero can be avoided. |
549 | /// |
550 | /// # Examples |
551 | /// |
552 | /// Basic usage: |
553 | /// |
554 | /// ``` |
555 | /// # use std::num::NonZero; |
556 | /// # |
557 | /// # fn main() { test().unwrap(); } |
558 | /// # fn test() -> Option<()> { |
559 | #[doc = concat!("let n = NonZero::<" , stringify!($Int), ">::new(" , $leading_zeros_test, ")?;" )] |
560 | /// |
561 | /// assert_eq!(n.leading_zeros(), 0); |
562 | /// # Some(()) |
563 | /// # } |
564 | /// ``` |
565 | #[stable(feature = "nonzero_leading_trailing_zeros" , since = "1.53.0" )] |
566 | #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros" , since = "1.53.0" )] |
567 | #[must_use = "this returns the result of the operation, \ |
568 | without modifying the original" ] |
569 | #[inline] |
570 | pub const fn leading_zeros(self) -> u32 { |
571 | // SAFETY: since `self` cannot be zero, it is safe to call `ctlz_nonzero`. |
572 | unsafe { |
573 | intrinsics::ctlz_nonzero(self.get() as $Uint) |
574 | } |
575 | } |
576 | |
577 | /// Returns the number of trailing zeros in the binary representation |
578 | /// of `self`. |
579 | /// |
580 | /// On many architectures, this function can perform better than `trailing_zeros()` on the underlying integer type, as special handling of zero can be avoided. |
581 | /// |
582 | /// # Examples |
583 | /// |
584 | /// Basic usage: |
585 | /// |
586 | /// ``` |
587 | /// # use std::num::NonZero; |
588 | /// # |
589 | /// # fn main() { test().unwrap(); } |
590 | /// # fn test() -> Option<()> { |
591 | #[doc = concat!("let n = NonZero::<" , stringify!($Int), ">::new(0b0101000)?;" )] |
592 | /// |
593 | /// assert_eq!(n.trailing_zeros(), 3); |
594 | /// # Some(()) |
595 | /// # } |
596 | /// ``` |
597 | #[stable(feature = "nonzero_leading_trailing_zeros" , since = "1.53.0" )] |
598 | #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros" , since = "1.53.0" )] |
599 | #[must_use = "this returns the result of the operation, \ |
600 | without modifying the original" ] |
601 | #[inline] |
602 | pub const fn trailing_zeros(self) -> u32 { |
603 | // SAFETY: since `self` cannot be zero, it is safe to call `cttz_nonzero`. |
604 | unsafe { |
605 | intrinsics::cttz_nonzero(self.get() as $Uint) |
606 | } |
607 | } |
608 | |
609 | /// Returns `self` with only the most significant bit set. |
610 | /// |
611 | /// # Example |
612 | /// |
613 | /// Basic usage: |
614 | /// |
615 | /// ``` |
616 | /// #![feature(isolate_most_least_significant_one)] |
617 | /// |
618 | /// # use core::num::NonZero; |
619 | /// # fn main() { test().unwrap(); } |
620 | /// # fn test() -> Option<()> { |
621 | #[doc = concat!("let a = NonZero::<" , stringify!($Int), ">::new(0b_01100100)?;" )] |
622 | #[doc = concat!("let b = NonZero::<" , stringify!($Int), ">::new(0b_01000000)?;" )] |
623 | /// |
624 | /// assert_eq!(a.isolate_most_significant_one(), b); |
625 | /// # Some(()) |
626 | /// # } |
627 | /// ``` |
628 | #[unstable(feature = "isolate_most_least_significant_one" , issue = "136909" )] |
629 | #[must_use = "this returns the result of the operation, \ |
630 | without modifying the original" ] |
631 | #[inline(always)] |
632 | pub const fn isolate_most_significant_one(self) -> Self { |
633 | let n = self.get() & (((1 as $Int) << (<$Int>::BITS - 1)).wrapping_shr(self.leading_zeros())); |
634 | |
635 | // SAFETY: |
636 | // `self` is non-zero, so masking to preserve only the most |
637 | // significant set bit will result in a non-zero `n`. |
638 | unsafe { NonZero::new_unchecked(n) } |
639 | } |
640 | |
641 | /// Returns `self` with only the least significant bit set. |
642 | /// |
643 | /// # Example |
644 | /// |
645 | /// Basic usage: |
646 | /// |
647 | /// ``` |
648 | /// #![feature(isolate_most_least_significant_one)] |
649 | /// |
650 | /// # use core::num::NonZero; |
651 | /// # fn main() { test().unwrap(); } |
652 | /// # fn test() -> Option<()> { |
653 | #[doc = concat!("let a = NonZero::<" , stringify!($Int), ">::new(0b_01100100)?;" )] |
654 | #[doc = concat!("let b = NonZero::<" , stringify!($Int), ">::new(0b_00000100)?;" )] |
655 | /// |
656 | /// assert_eq!(a.isolate_least_significant_one(), b); |
657 | /// # Some(()) |
658 | /// # } |
659 | /// ``` |
660 | #[unstable(feature = "isolate_most_least_significant_one" , issue = "136909" )] |
661 | #[must_use = "this returns the result of the operation, \ |
662 | without modifying the original" ] |
663 | #[inline(always)] |
664 | pub const fn isolate_least_significant_one(self) -> Self { |
665 | let n = self.get(); |
666 | let n = n & n.wrapping_neg(); |
667 | |
668 | // SAFETY: `self` is non-zero, so `self` with only its least |
669 | // significant set bit will remain non-zero. |
670 | unsafe { NonZero::new_unchecked(n) } |
671 | } |
672 | |
673 | /// Returns the number of ones in the binary representation of `self`. |
674 | /// |
675 | /// # Examples |
676 | /// |
677 | /// Basic usage: |
678 | /// |
679 | /// ``` |
680 | /// # use std::num::NonZero; |
681 | /// # |
682 | /// # fn main() { test().unwrap(); } |
683 | /// # fn test() -> Option<()> { |
684 | #[doc = concat!("let a = NonZero::<" , stringify!($Int), ">::new(0b100_0000)?;" )] |
685 | #[doc = concat!("let b = NonZero::<" , stringify!($Int), ">::new(0b100_0011)?;" )] |
686 | /// |
687 | /// assert_eq!(a.count_ones(), NonZero::new(1)?); |
688 | /// assert_eq!(b.count_ones(), NonZero::new(3)?); |
689 | /// # Some(()) |
690 | /// # } |
691 | /// ``` |
692 | /// |
693 | #[stable(feature = "non_zero_count_ones" , since = "1.86.0" )] |
694 | #[rustc_const_stable(feature = "non_zero_count_ones" , since = "1.86.0" )] |
695 | #[doc(alias = "popcount" )] |
696 | #[doc(alias = "popcnt" )] |
697 | #[must_use = "this returns the result of the operation, \ |
698 | without modifying the original" ] |
699 | #[inline(always)] |
700 | pub const fn count_ones(self) -> NonZero<u32> { |
701 | // SAFETY: |
702 | // `self` is non-zero, which means it has at least one bit set, which means |
703 | // that the result of `count_ones` is non-zero. |
704 | unsafe { NonZero::new_unchecked(self.get().count_ones()) } |
705 | } |
706 | |
707 | /// Shifts the bits to the left by a specified amount, `n`, |
708 | /// wrapping the truncated bits to the end of the resulting integer. |
709 | /// |
710 | /// Please note this isn't the same operation as the `<<` shifting operator! |
711 | /// |
712 | /// # Examples |
713 | /// |
714 | /// Basic usage: |
715 | /// |
716 | /// ``` |
717 | /// #![feature(nonzero_bitwise)] |
718 | /// # use std::num::NonZero; |
719 | /// # |
720 | /// # fn main() { test().unwrap(); } |
721 | /// # fn test() -> Option<()> { |
722 | #[doc = concat!("let n = NonZero::new(" , $rot_op, stringify!($Int), ")?;" )] |
723 | #[doc = concat!("let m = NonZero::new(" , $rot_result, ")?;" )] |
724 | /// |
725 | #[doc = concat!("assert_eq!(n.rotate_left(" , $rot, "), m);" )] |
726 | /// # Some(()) |
727 | /// # } |
728 | /// ``` |
729 | #[unstable(feature = "nonzero_bitwise" , issue = "128281" )] |
730 | #[must_use = "this returns the result of the operation, \ |
731 | without modifying the original" ] |
732 | #[inline(always)] |
733 | pub const fn rotate_left(self, n: u32) -> Self { |
734 | let result = self.get().rotate_left(n); |
735 | // SAFETY: Rotating bits preserves the property int > 0. |
736 | unsafe { Self::new_unchecked(result) } |
737 | } |
738 | |
739 | /// Shifts the bits to the right by a specified amount, `n`, |
740 | /// wrapping the truncated bits to the beginning of the resulting |
741 | /// integer. |
742 | /// |
743 | /// Please note this isn't the same operation as the `>>` shifting operator! |
744 | /// |
745 | /// # Examples |
746 | /// |
747 | /// Basic usage: |
748 | /// |
749 | /// ``` |
750 | /// #![feature(nonzero_bitwise)] |
751 | /// # use std::num::NonZero; |
752 | /// # |
753 | /// # fn main() { test().unwrap(); } |
754 | /// # fn test() -> Option<()> { |
755 | #[doc = concat!("let n = NonZero::new(" , $rot_result, stringify!($Int), ")?;" )] |
756 | #[doc = concat!("let m = NonZero::new(" , $rot_op, ")?;" )] |
757 | /// |
758 | #[doc = concat!("assert_eq!(n.rotate_right(" , $rot, "), m);" )] |
759 | /// # Some(()) |
760 | /// # } |
761 | /// ``` |
762 | #[unstable(feature = "nonzero_bitwise" , issue = "128281" )] |
763 | #[must_use = "this returns the result of the operation, \ |
764 | without modifying the original" ] |
765 | #[inline(always)] |
766 | pub const fn rotate_right(self, n: u32) -> Self { |
767 | let result = self.get().rotate_right(n); |
768 | // SAFETY: Rotating bits preserves the property int > 0. |
769 | unsafe { Self::new_unchecked(result) } |
770 | } |
771 | |
772 | /// Reverses the byte order of the integer. |
773 | /// |
774 | /// # Examples |
775 | /// |
776 | /// Basic usage: |
777 | /// |
778 | /// ``` |
779 | /// #![feature(nonzero_bitwise)] |
780 | /// # use std::num::NonZero; |
781 | /// # |
782 | /// # fn main() { test().unwrap(); } |
783 | /// # fn test() -> Option<()> { |
784 | #[doc = concat!("let n = NonZero::new(" , $swap_op, stringify!($Int), ")?;" )] |
785 | /// let m = n.swap_bytes(); |
786 | /// |
787 | #[doc = concat!("assert_eq!(m, NonZero::new(" , $swapped, ")?);" )] |
788 | /// # Some(()) |
789 | /// # } |
790 | /// ``` |
791 | #[unstable(feature = "nonzero_bitwise" , issue = "128281" )] |
792 | #[must_use = "this returns the result of the operation, \ |
793 | without modifying the original" ] |
794 | #[inline(always)] |
795 | pub const fn swap_bytes(self) -> Self { |
796 | let result = self.get().swap_bytes(); |
797 | // SAFETY: Shuffling bytes preserves the property int > 0. |
798 | unsafe { Self::new_unchecked(result) } |
799 | } |
800 | |
801 | /// Reverses the order of bits in the integer. The least significant bit becomes the most significant bit, |
802 | /// second least-significant bit becomes second most-significant bit, etc. |
803 | /// |
804 | /// # Examples |
805 | /// |
806 | /// Basic usage: |
807 | /// |
808 | /// ``` |
809 | /// #![feature(nonzero_bitwise)] |
810 | /// # use std::num::NonZero; |
811 | /// # |
812 | /// # fn main() { test().unwrap(); } |
813 | /// # fn test() -> Option<()> { |
814 | #[doc = concat!("let n = NonZero::new(" , $swap_op, stringify!($Int), ")?;" )] |
815 | /// let m = n.reverse_bits(); |
816 | /// |
817 | #[doc = concat!("assert_eq!(m, NonZero::new(" , $reversed, ")?);" )] |
818 | /// # Some(()) |
819 | /// # } |
820 | /// ``` |
821 | #[unstable(feature = "nonzero_bitwise" , issue = "128281" )] |
822 | #[must_use = "this returns the result of the operation, \ |
823 | without modifying the original" ] |
824 | #[inline(always)] |
825 | pub const fn reverse_bits(self) -> Self { |
826 | let result = self.get().reverse_bits(); |
827 | // SAFETY: Reversing bits preserves the property int > 0. |
828 | unsafe { Self::new_unchecked(result) } |
829 | } |
830 | |
831 | /// Converts an integer from big endian to the target's endianness. |
832 | /// |
833 | /// On big endian this is a no-op. On little endian the bytes are |
834 | /// swapped. |
835 | /// |
836 | /// # Examples |
837 | /// |
838 | /// Basic usage: |
839 | /// |
840 | /// ``` |
841 | /// #![feature(nonzero_bitwise)] |
842 | /// # use std::num::NonZero; |
843 | #[doc = concat!("use std::num::" , stringify!($Ty), ";" )] |
844 | /// # |
845 | /// # fn main() { test().unwrap(); } |
846 | /// # fn test() -> Option<()> { |
847 | #[doc = concat!("let n = NonZero::new(0x1A" , stringify!($Int), ")?;" )] |
848 | /// |
849 | /// if cfg!(target_endian = "big") { |
850 | #[doc = concat!(" assert_eq!(" , stringify!($Ty), "::from_be(n), n)" )] |
851 | /// } else { |
852 | #[doc = concat!(" assert_eq!(" , stringify!($Ty), "::from_be(n), n.swap_bytes())" )] |
853 | /// } |
854 | /// # Some(()) |
855 | /// # } |
856 | /// ``` |
857 | #[unstable(feature = "nonzero_bitwise" , issue = "128281" )] |
858 | #[must_use] |
859 | #[inline(always)] |
860 | pub const fn from_be(x: Self) -> Self { |
861 | let result = $Int::from_be(x.get()); |
862 | // SAFETY: Shuffling bytes preserves the property int > 0. |
863 | unsafe { Self::new_unchecked(result) } |
864 | } |
865 | |
866 | /// Converts an integer from little endian to the target's endianness. |
867 | /// |
868 | /// On little endian this is a no-op. On big endian the bytes are |
869 | /// swapped. |
870 | /// |
871 | /// # Examples |
872 | /// |
873 | /// Basic usage: |
874 | /// |
875 | /// ``` |
876 | /// #![feature(nonzero_bitwise)] |
877 | /// # use std::num::NonZero; |
878 | #[doc = concat!("use std::num::" , stringify!($Ty), ";" )] |
879 | /// # |
880 | /// # fn main() { test().unwrap(); } |
881 | /// # fn test() -> Option<()> { |
882 | #[doc = concat!("let n = NonZero::new(0x1A" , stringify!($Int), ")?;" )] |
883 | /// |
884 | /// if cfg!(target_endian = "little") { |
885 | #[doc = concat!(" assert_eq!(" , stringify!($Ty), "::from_le(n), n)" )] |
886 | /// } else { |
887 | #[doc = concat!(" assert_eq!(" , stringify!($Ty), "::from_le(n), n.swap_bytes())" )] |
888 | /// } |
889 | /// # Some(()) |
890 | /// # } |
891 | /// ``` |
892 | #[unstable(feature = "nonzero_bitwise" , issue = "128281" )] |
893 | #[must_use] |
894 | #[inline(always)] |
895 | pub const fn from_le(x: Self) -> Self { |
896 | let result = $Int::from_le(x.get()); |
897 | // SAFETY: Shuffling bytes preserves the property int > 0. |
898 | unsafe { Self::new_unchecked(result) } |
899 | } |
900 | |
901 | /// Converts `self` to big endian from the target's endianness. |
902 | /// |
903 | /// On big endian this is a no-op. On little endian the bytes are |
904 | /// swapped. |
905 | /// |
906 | /// # Examples |
907 | /// |
908 | /// Basic usage: |
909 | /// |
910 | /// ``` |
911 | /// #![feature(nonzero_bitwise)] |
912 | /// # use std::num::NonZero; |
913 | /// # |
914 | /// # fn main() { test().unwrap(); } |
915 | /// # fn test() -> Option<()> { |
916 | #[doc = concat!("let n = NonZero::new(0x1A" , stringify!($Int), ")?;" )] |
917 | /// |
918 | /// if cfg!(target_endian = "big") { |
919 | /// assert_eq!(n.to_be(), n) |
920 | /// } else { |
921 | /// assert_eq!(n.to_be(), n.swap_bytes()) |
922 | /// } |
923 | /// # Some(()) |
924 | /// # } |
925 | /// ``` |
926 | #[unstable(feature = "nonzero_bitwise" , issue = "128281" )] |
927 | #[must_use = "this returns the result of the operation, \ |
928 | without modifying the original" ] |
929 | #[inline(always)] |
930 | pub const fn to_be(self) -> Self { |
931 | let result = self.get().to_be(); |
932 | // SAFETY: Shuffling bytes preserves the property int > 0. |
933 | unsafe { Self::new_unchecked(result) } |
934 | } |
935 | |
936 | /// Converts `self` to little endian from the target's endianness. |
937 | /// |
938 | /// On little endian this is a no-op. On big endian the bytes are |
939 | /// swapped. |
940 | /// |
941 | /// # Examples |
942 | /// |
943 | /// Basic usage: |
944 | /// |
945 | /// ``` |
946 | /// #![feature(nonzero_bitwise)] |
947 | /// # use std::num::NonZero; |
948 | /// # |
949 | /// # fn main() { test().unwrap(); } |
950 | /// # fn test() -> Option<()> { |
951 | #[doc = concat!("let n = NonZero::new(0x1A" , stringify!($Int), ")?;" )] |
952 | /// |
953 | /// if cfg!(target_endian = "little") { |
954 | /// assert_eq!(n.to_le(), n) |
955 | /// } else { |
956 | /// assert_eq!(n.to_le(), n.swap_bytes()) |
957 | /// } |
958 | /// # Some(()) |
959 | /// # } |
960 | /// ``` |
961 | #[unstable(feature = "nonzero_bitwise" , issue = "128281" )] |
962 | #[must_use = "this returns the result of the operation, \ |
963 | without modifying the original" ] |
964 | #[inline(always)] |
965 | pub const fn to_le(self) -> Self { |
966 | let result = self.get().to_le(); |
967 | // SAFETY: Shuffling bytes preserves the property int > 0. |
968 | unsafe { Self::new_unchecked(result) } |
969 | } |
970 | |
971 | nonzero_integer_signedness_dependent_methods! { |
972 | Primitive = $signedness $Int, |
973 | SignedPrimitive = $Sint, |
974 | UnsignedPrimitive = $Uint, |
975 | } |
976 | |
977 | /// Multiplies two non-zero integers together. |
978 | /// Checks for overflow and returns [`None`] on overflow. |
979 | /// As a consequence, the result cannot wrap to zero. |
980 | /// |
981 | /// # Examples |
982 | /// |
983 | /// ``` |
984 | /// # use std::num::NonZero; |
985 | /// # |
986 | /// # fn main() { test().unwrap(); } |
987 | /// # fn test() -> Option<()> { |
988 | #[doc = concat!("let two = NonZero::new(2" , stringify!($Int), ")?;" )] |
989 | #[doc = concat!("let four = NonZero::new(4" , stringify!($Int), ")?;" )] |
990 | #[doc = concat!("let max = NonZero::new(" , stringify!($Int), "::MAX)?;" )] |
991 | /// |
992 | /// assert_eq!(Some(four), two.checked_mul(two)); |
993 | /// assert_eq!(None, max.checked_mul(two)); |
994 | /// # Some(()) |
995 | /// # } |
996 | /// ``` |
997 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
998 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
999 | #[must_use = "this returns the result of the operation, \ |
1000 | without modifying the original" ] |
1001 | #[inline] |
1002 | pub const fn checked_mul(self, other: Self) -> Option<Self> { |
1003 | if let Some(result) = self.get().checked_mul(other.get()) { |
1004 | // SAFETY: |
1005 | // - `checked_mul` returns `None` on overflow |
1006 | // - `self` and `other` are non-zero |
1007 | // - the only way to get zero from a multiplication without overflow is for one |
1008 | // of the sides to be zero |
1009 | // |
1010 | // So the result cannot be zero. |
1011 | Some(unsafe { Self::new_unchecked(result) }) |
1012 | } else { |
1013 | None |
1014 | } |
1015 | } |
1016 | |
1017 | /// Multiplies two non-zero integers together. |
1018 | #[doc = concat!("Return [`NonZero::<" , stringify!($Int), ">::MAX`] on overflow." )] |
1019 | /// |
1020 | /// # Examples |
1021 | /// |
1022 | /// ``` |
1023 | /// # use std::num::NonZero; |
1024 | /// # |
1025 | /// # fn main() { test().unwrap(); } |
1026 | /// # fn test() -> Option<()> { |
1027 | #[doc = concat!("let two = NonZero::new(2" , stringify!($Int), ")?;" )] |
1028 | #[doc = concat!("let four = NonZero::new(4" , stringify!($Int), ")?;" )] |
1029 | #[doc = concat!("let max = NonZero::new(" , stringify!($Int), "::MAX)?;" )] |
1030 | /// |
1031 | /// assert_eq!(four, two.saturating_mul(two)); |
1032 | /// assert_eq!(max, four.saturating_mul(max)); |
1033 | /// # Some(()) |
1034 | /// # } |
1035 | /// ``` |
1036 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
1037 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
1038 | #[must_use = "this returns the result of the operation, \ |
1039 | without modifying the original" ] |
1040 | #[inline] |
1041 | pub const fn saturating_mul(self, other: Self) -> Self { |
1042 | // SAFETY: |
1043 | // - `saturating_mul` returns `u*::MAX`/`i*::MAX`/`i*::MIN` on overflow/underflow, |
1044 | // all of which are non-zero |
1045 | // - `self` and `other` are non-zero |
1046 | // - the only way to get zero from a multiplication without overflow is for one |
1047 | // of the sides to be zero |
1048 | // |
1049 | // So the result cannot be zero. |
1050 | unsafe { Self::new_unchecked(self.get().saturating_mul(other.get())) } |
1051 | } |
1052 | |
1053 | /// Multiplies two non-zero integers together, |
1054 | /// assuming overflow cannot occur. |
1055 | /// Overflow is unchecked, and it is undefined behavior to overflow |
1056 | /// *even if the result would wrap to a non-zero value*. |
1057 | /// The behavior is undefined as soon as |
1058 | #[doc = sign_dependent_expr!{ |
1059 | $signedness ? |
1060 | if signed { |
1061 | concat!("`self * rhs > " , stringify!($Int), "::MAX`, " , |
1062 | "or `self * rhs < " , stringify!($Int), "::MIN`." ) |
1063 | } |
1064 | if unsigned { |
1065 | concat!("`self * rhs > " , stringify!($Int), "::MAX`." ) |
1066 | } |
1067 | }] |
1068 | /// |
1069 | /// # Examples |
1070 | /// |
1071 | /// ``` |
1072 | /// #![feature(nonzero_ops)] |
1073 | /// |
1074 | /// # use std::num::NonZero; |
1075 | /// # |
1076 | /// # fn main() { test().unwrap(); } |
1077 | /// # fn test() -> Option<()> { |
1078 | #[doc = concat!("let two = NonZero::new(2" , stringify!($Int), ")?;" )] |
1079 | #[doc = concat!("let four = NonZero::new(4" , stringify!($Int), ")?;" )] |
1080 | /// |
1081 | /// assert_eq!(four, unsafe { two.unchecked_mul(two) }); |
1082 | /// # Some(()) |
1083 | /// # } |
1084 | /// ``` |
1085 | #[unstable(feature = "nonzero_ops" , issue = "84186" )] |
1086 | #[must_use = "this returns the result of the operation, \ |
1087 | without modifying the original" ] |
1088 | #[inline] |
1089 | pub const unsafe fn unchecked_mul(self, other: Self) -> Self { |
1090 | // SAFETY: The caller ensures there is no overflow. |
1091 | unsafe { Self::new_unchecked(self.get().unchecked_mul(other.get())) } |
1092 | } |
1093 | |
1094 | /// Raises non-zero value to an integer power. |
1095 | /// Checks for overflow and returns [`None`] on overflow. |
1096 | /// As a consequence, the result cannot wrap to zero. |
1097 | /// |
1098 | /// # Examples |
1099 | /// |
1100 | /// ``` |
1101 | /// # use std::num::NonZero; |
1102 | /// # |
1103 | /// # fn main() { test().unwrap(); } |
1104 | /// # fn test() -> Option<()> { |
1105 | #[doc = concat!("let three = NonZero::new(3" , stringify!($Int), ")?;" )] |
1106 | #[doc = concat!("let twenty_seven = NonZero::new(27" , stringify!($Int), ")?;" )] |
1107 | #[doc = concat!("let half_max = NonZero::new(" , stringify!($Int), "::MAX / 2)?;" )] |
1108 | /// |
1109 | /// assert_eq!(Some(twenty_seven), three.checked_pow(3)); |
1110 | /// assert_eq!(None, half_max.checked_pow(3)); |
1111 | /// # Some(()) |
1112 | /// # } |
1113 | /// ``` |
1114 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
1115 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
1116 | #[must_use = "this returns the result of the operation, \ |
1117 | without modifying the original" ] |
1118 | #[inline] |
1119 | pub const fn checked_pow(self, other: u32) -> Option<Self> { |
1120 | if let Some(result) = self.get().checked_pow(other) { |
1121 | // SAFETY: |
1122 | // - `checked_pow` returns `None` on overflow/underflow |
1123 | // - `self` is non-zero |
1124 | // - the only way to get zero from an exponentiation without overflow is |
1125 | // for base to be zero |
1126 | // |
1127 | // So the result cannot be zero. |
1128 | Some(unsafe { Self::new_unchecked(result) }) |
1129 | } else { |
1130 | None |
1131 | } |
1132 | } |
1133 | |
1134 | /// Raise non-zero value to an integer power. |
1135 | #[doc = sign_dependent_expr!{ |
1136 | $signedness ? |
1137 | if signed { |
1138 | concat!("Return [`NonZero::<" , stringify!($Int), ">::MIN`] " , |
1139 | "or [`NonZero::<" , stringify!($Int), ">::MAX`] on overflow." ) |
1140 | } |
1141 | if unsigned { |
1142 | concat!("Return [`NonZero::<" , stringify!($Int), ">::MAX`] on overflow." ) |
1143 | } |
1144 | }] |
1145 | /// |
1146 | /// # Examples |
1147 | /// |
1148 | /// ``` |
1149 | /// # use std::num::NonZero; |
1150 | /// # |
1151 | /// # fn main() { test().unwrap(); } |
1152 | /// # fn test() -> Option<()> { |
1153 | #[doc = concat!("let three = NonZero::new(3" , stringify!($Int), ")?;" )] |
1154 | #[doc = concat!("let twenty_seven = NonZero::new(27" , stringify!($Int), ")?;" )] |
1155 | #[doc = concat!("let max = NonZero::new(" , stringify!($Int), "::MAX)?;" )] |
1156 | /// |
1157 | /// assert_eq!(twenty_seven, three.saturating_pow(3)); |
1158 | /// assert_eq!(max, max.saturating_pow(3)); |
1159 | /// # Some(()) |
1160 | /// # } |
1161 | /// ``` |
1162 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
1163 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
1164 | #[must_use = "this returns the result of the operation, \ |
1165 | without modifying the original" ] |
1166 | #[inline] |
1167 | pub const fn saturating_pow(self, other: u32) -> Self { |
1168 | // SAFETY: |
1169 | // - `saturating_pow` returns `u*::MAX`/`i*::MAX`/`i*::MIN` on overflow/underflow, |
1170 | // all of which are non-zero |
1171 | // - `self` is non-zero |
1172 | // - the only way to get zero from an exponentiation without overflow is |
1173 | // for base to be zero |
1174 | // |
1175 | // So the result cannot be zero. |
1176 | unsafe { Self::new_unchecked(self.get().saturating_pow(other)) } |
1177 | } |
1178 | } |
1179 | |
1180 | #[stable(feature = "nonzero_parse" , since = "1.35.0" )] |
1181 | impl FromStr for NonZero<$Int> { |
1182 | type Err = ParseIntError; |
1183 | fn from_str(src: &str) -> Result<Self, Self::Err> { |
1184 | Self::new(<$Int>::from_str_radix(src, 10)?) |
1185 | .ok_or(ParseIntError { |
1186 | kind: IntErrorKind::Zero |
1187 | }) |
1188 | } |
1189 | } |
1190 | |
1191 | nonzero_integer_signedness_dependent_impls!($signedness $Int); |
1192 | }; |
1193 | |
1194 | ( |
1195 | Self = $Ty:ident, |
1196 | Primitive = unsigned $Int:ident, |
1197 | SignedPrimitive = $Sint:ident, |
1198 | rot = $rot:literal, |
1199 | rot_op = $rot_op:literal, |
1200 | rot_result = $rot_result:literal, |
1201 | swap_op = $swap_op:literal, |
1202 | swapped = $swapped:literal, |
1203 | reversed = $reversed:literal, |
1204 | $(,)? |
1205 | ) => { |
1206 | nonzero_integer! { |
1207 | #[stable(feature = "nonzero" , since = "1.28.0" )] |
1208 | Self = $Ty, |
1209 | Primitive = unsigned $Int, |
1210 | SignedPrimitive = $Sint, |
1211 | UnsignedPrimitive = $Int, |
1212 | rot = $rot, |
1213 | rot_op = $rot_op, |
1214 | rot_result = $rot_result, |
1215 | swap_op = $swap_op, |
1216 | swapped = $swapped, |
1217 | reversed = $reversed, |
1218 | leading_zeros_test = concat!(stringify!($Int), "::MAX" ), |
1219 | } |
1220 | }; |
1221 | |
1222 | ( |
1223 | Self = $Ty:ident, |
1224 | Primitive = signed $Int:ident, |
1225 | UnsignedPrimitive = $Uint:ident, |
1226 | rot = $rot:literal, |
1227 | rot_op = $rot_op:literal, |
1228 | rot_result = $rot_result:literal, |
1229 | swap_op = $swap_op:literal, |
1230 | swapped = $swapped:literal, |
1231 | reversed = $reversed:literal, |
1232 | ) => { |
1233 | nonzero_integer! { |
1234 | #[stable(feature = "signed_nonzero" , since = "1.34.0" )] |
1235 | Self = $Ty, |
1236 | Primitive = signed $Int, |
1237 | SignedPrimitive = $Int, |
1238 | UnsignedPrimitive = $Uint, |
1239 | rot = $rot, |
1240 | rot_op = $rot_op, |
1241 | rot_result = $rot_result, |
1242 | swap_op = $swap_op, |
1243 | swapped = $swapped, |
1244 | reversed = $reversed, |
1245 | leading_zeros_test = concat!("-1" , stringify!($Int)), |
1246 | } |
1247 | }; |
1248 | } |
1249 | |
1250 | macro_rules! nonzero_integer_signedness_dependent_impls { |
1251 | // Impls for unsigned nonzero types only. |
1252 | (unsigned $Int:ty) => { |
1253 | #[stable(feature = "nonzero_div" , since = "1.51.0" )] |
1254 | impl Div<NonZero<$Int>> for $Int { |
1255 | type Output = $Int; |
1256 | |
1257 | /// Same as `self / other.get()`, but because `other` is a `NonZero<_>`, |
1258 | /// there's never a runtime check for division-by-zero. |
1259 | /// |
1260 | /// This operation rounds towards zero, truncating any fractional |
1261 | /// part of the exact result, and cannot panic. |
1262 | #[doc(alias = "unchecked_div" )] |
1263 | #[inline] |
1264 | fn div(self, other: NonZero<$Int>) -> $Int { |
1265 | // SAFETY: Division by zero is checked because `other` is non-zero, |
1266 | // and MIN/-1 is checked because `self` is an unsigned int. |
1267 | unsafe { intrinsics::unchecked_div(self, other.get()) } |
1268 | } |
1269 | } |
1270 | |
1271 | #[stable(feature = "nonzero_div_assign" , since = "1.79.0" )] |
1272 | impl DivAssign<NonZero<$Int>> for $Int { |
1273 | /// Same as `self /= other.get()`, but because `other` is a `NonZero<_>`, |
1274 | /// there's never a runtime check for division-by-zero. |
1275 | /// |
1276 | /// This operation rounds towards zero, truncating any fractional |
1277 | /// part of the exact result, and cannot panic. |
1278 | #[inline] |
1279 | fn div_assign(&mut self, other: NonZero<$Int>) { |
1280 | *self = *self / other; |
1281 | } |
1282 | } |
1283 | |
1284 | #[stable(feature = "nonzero_div" , since = "1.51.0" )] |
1285 | impl Rem<NonZero<$Int>> for $Int { |
1286 | type Output = $Int; |
1287 | |
1288 | /// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic. |
1289 | #[inline] |
1290 | fn rem(self, other: NonZero<$Int>) -> $Int { |
1291 | // SAFETY: Remainder by zero is checked because `other` is non-zero, |
1292 | // and MIN/-1 is checked because `self` is an unsigned int. |
1293 | unsafe { intrinsics::unchecked_rem(self, other.get()) } |
1294 | } |
1295 | } |
1296 | |
1297 | #[stable(feature = "nonzero_div_assign" , since = "1.79.0" )] |
1298 | impl RemAssign<NonZero<$Int>> for $Int { |
1299 | /// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic. |
1300 | #[inline] |
1301 | fn rem_assign(&mut self, other: NonZero<$Int>) { |
1302 | *self = *self % other; |
1303 | } |
1304 | } |
1305 | |
1306 | impl NonZero<$Int> { |
1307 | /// Calculates the quotient of `self` and `rhs`, rounding the result towards positive infinity. |
1308 | /// |
1309 | /// The result is guaranteed to be non-zero. |
1310 | /// |
1311 | /// # Examples |
1312 | /// |
1313 | /// ``` |
1314 | /// # #![feature(unsigned_nonzero_div_ceil)] |
1315 | /// # use std::num::NonZero; |
1316 | #[doc = concat!("let one = NonZero::new(1" , stringify!($Int), ").unwrap();" )] |
1317 | #[doc = concat!("let max = NonZero::new(" , stringify!($Int), "::MAX).unwrap();" )] |
1318 | /// assert_eq!(one.div_ceil(max), one); |
1319 | /// |
1320 | #[doc = concat!("let two = NonZero::new(2" , stringify!($Int), ").unwrap();" )] |
1321 | #[doc = concat!("let three = NonZero::new(3" , stringify!($Int), ").unwrap();" )] |
1322 | /// assert_eq!(three.div_ceil(two), two); |
1323 | /// ``` |
1324 | #[unstable(feature = "unsigned_nonzero_div_ceil" , issue = "132968" )] |
1325 | #[must_use = "this returns the result of the operation, \ |
1326 | without modifying the original" ] |
1327 | #[inline] |
1328 | pub const fn div_ceil(self, rhs: Self) -> Self { |
1329 | let v = self.get().div_ceil(rhs.get()); |
1330 | // SAFETY: ceiled division of two positive integers can never be zero. |
1331 | unsafe { Self::new_unchecked(v) } |
1332 | } |
1333 | } |
1334 | }; |
1335 | // Impls for signed nonzero types only. |
1336 | (signed $Int:ty) => { |
1337 | #[stable(feature = "signed_nonzero_neg" , since = "1.71.0" )] |
1338 | impl Neg for NonZero<$Int> { |
1339 | type Output = Self; |
1340 | |
1341 | #[inline] |
1342 | fn neg(self) -> Self { |
1343 | // SAFETY: negation of nonzero cannot yield zero values. |
1344 | unsafe { Self::new_unchecked(self.get().neg()) } |
1345 | } |
1346 | } |
1347 | |
1348 | forward_ref_unop! { impl Neg, neg for NonZero<$Int>, |
1349 | #[stable(feature = "signed_nonzero_neg" , since = "1.71.0" )] } |
1350 | }; |
1351 | } |
1352 | |
1353 | #[rustfmt::skip] // https://github.com/rust-lang/rustfmt/issues/5974 |
1354 | macro_rules! nonzero_integer_signedness_dependent_methods { |
1355 | // Associated items for unsigned nonzero types only. |
1356 | ( |
1357 | Primitive = unsigned $Int:ident, |
1358 | SignedPrimitive = $Sint:ty, |
1359 | UnsignedPrimitive = $Uint:ty, |
1360 | ) => { |
1361 | /// The smallest value that can be represented by this non-zero |
1362 | /// integer type, 1. |
1363 | /// |
1364 | /// # Examples |
1365 | /// |
1366 | /// ``` |
1367 | /// # use std::num::NonZero; |
1368 | /// # |
1369 | #[doc = concat!("assert_eq!(NonZero::<" , stringify!($Int), ">::MIN.get(), 1" , stringify!($Int), ");" )] |
1370 | /// ``` |
1371 | #[stable(feature = "nonzero_min_max" , since = "1.70.0" )] |
1372 | pub const MIN: Self = Self::new(1).unwrap(); |
1373 | |
1374 | /// The largest value that can be represented by this non-zero |
1375 | /// integer type, |
1376 | #[doc = concat!("equal to [`" , stringify!($Int), "::MAX`]." )] |
1377 | /// |
1378 | /// # Examples |
1379 | /// |
1380 | /// ``` |
1381 | /// # use std::num::NonZero; |
1382 | /// # |
1383 | #[doc = concat!("assert_eq!(NonZero::<" , stringify!($Int), ">::MAX.get(), " , stringify!($Int), "::MAX);" )] |
1384 | /// ``` |
1385 | #[stable(feature = "nonzero_min_max" , since = "1.70.0" )] |
1386 | pub const MAX: Self = Self::new(<$Int>::MAX).unwrap(); |
1387 | |
1388 | /// Adds an unsigned integer to a non-zero value. |
1389 | /// Checks for overflow and returns [`None`] on overflow. |
1390 | /// As a consequence, the result cannot wrap to zero. |
1391 | /// |
1392 | /// |
1393 | /// # Examples |
1394 | /// |
1395 | /// ``` |
1396 | /// # use std::num::NonZero; |
1397 | /// # |
1398 | /// # fn main() { test().unwrap(); } |
1399 | /// # fn test() -> Option<()> { |
1400 | #[doc = concat!("let one = NonZero::new(1" , stringify!($Int), ")?;" )] |
1401 | #[doc = concat!("let two = NonZero::new(2" , stringify!($Int), ")?;" )] |
1402 | #[doc = concat!("let max = NonZero::new(" , stringify!($Int), "::MAX)?;" )] |
1403 | /// |
1404 | /// assert_eq!(Some(two), one.checked_add(1)); |
1405 | /// assert_eq!(None, max.checked_add(1)); |
1406 | /// # Some(()) |
1407 | /// # } |
1408 | /// ``` |
1409 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
1410 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
1411 | #[must_use = "this returns the result of the operation, \ |
1412 | without modifying the original" ] |
1413 | #[inline] |
1414 | pub const fn checked_add(self, other: $Int) -> Option<Self> { |
1415 | if let Some(result) = self.get().checked_add(other) { |
1416 | // SAFETY: |
1417 | // - `checked_add` returns `None` on overflow |
1418 | // - `self` is non-zero |
1419 | // - the only way to get zero from an addition without overflow is for both |
1420 | // sides to be zero |
1421 | // |
1422 | // So the result cannot be zero. |
1423 | Some(unsafe { Self::new_unchecked(result) }) |
1424 | } else { |
1425 | None |
1426 | } |
1427 | } |
1428 | |
1429 | /// Adds an unsigned integer to a non-zero value. |
1430 | #[doc = concat!("Return [`NonZero::<" , stringify!($Int), ">::MAX`] on overflow." )] |
1431 | /// |
1432 | /// # Examples |
1433 | /// |
1434 | /// ``` |
1435 | /// # use std::num::NonZero; |
1436 | /// # |
1437 | /// # fn main() { test().unwrap(); } |
1438 | /// # fn test() -> Option<()> { |
1439 | #[doc = concat!("let one = NonZero::new(1" , stringify!($Int), ")?;" )] |
1440 | #[doc = concat!("let two = NonZero::new(2" , stringify!($Int), ")?;" )] |
1441 | #[doc = concat!("let max = NonZero::new(" , stringify!($Int), "::MAX)?;" )] |
1442 | /// |
1443 | /// assert_eq!(two, one.saturating_add(1)); |
1444 | /// assert_eq!(max, max.saturating_add(1)); |
1445 | /// # Some(()) |
1446 | /// # } |
1447 | /// ``` |
1448 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
1449 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
1450 | #[must_use = "this returns the result of the operation, \ |
1451 | without modifying the original" ] |
1452 | #[inline] |
1453 | pub const fn saturating_add(self, other: $Int) -> Self { |
1454 | // SAFETY: |
1455 | // - `saturating_add` returns `u*::MAX` on overflow, which is non-zero |
1456 | // - `self` is non-zero |
1457 | // - the only way to get zero from an addition without overflow is for both |
1458 | // sides to be zero |
1459 | // |
1460 | // So the result cannot be zero. |
1461 | unsafe { Self::new_unchecked(self.get().saturating_add(other)) } |
1462 | } |
1463 | |
1464 | /// Adds an unsigned integer to a non-zero value, |
1465 | /// assuming overflow cannot occur. |
1466 | /// Overflow is unchecked, and it is undefined behavior to overflow |
1467 | /// *even if the result would wrap to a non-zero value*. |
1468 | /// The behavior is undefined as soon as |
1469 | #[doc = concat!("`self + rhs > " , stringify!($Int), "::MAX`." )] |
1470 | /// |
1471 | /// # Examples |
1472 | /// |
1473 | /// ``` |
1474 | /// #![feature(nonzero_ops)] |
1475 | /// |
1476 | /// # use std::num::NonZero; |
1477 | /// # |
1478 | /// # fn main() { test().unwrap(); } |
1479 | /// # fn test() -> Option<()> { |
1480 | #[doc = concat!("let one = NonZero::new(1" , stringify!($Int), ")?;" )] |
1481 | #[doc = concat!("let two = NonZero::new(2" , stringify!($Int), ")?;" )] |
1482 | /// |
1483 | /// assert_eq!(two, unsafe { one.unchecked_add(1) }); |
1484 | /// # Some(()) |
1485 | /// # } |
1486 | /// ``` |
1487 | #[unstable(feature = "nonzero_ops" , issue = "84186" )] |
1488 | #[must_use = "this returns the result of the operation, \ |
1489 | without modifying the original" ] |
1490 | #[inline] |
1491 | pub const unsafe fn unchecked_add(self, other: $Int) -> Self { |
1492 | // SAFETY: The caller ensures there is no overflow. |
1493 | unsafe { Self::new_unchecked(self.get().unchecked_add(other)) } |
1494 | } |
1495 | |
1496 | /// Returns the smallest power of two greater than or equal to `self`. |
1497 | /// Checks for overflow and returns [`None`] |
1498 | /// if the next power of two is greater than the type’s maximum value. |
1499 | /// As a consequence, the result cannot wrap to zero. |
1500 | /// |
1501 | /// # Examples |
1502 | /// |
1503 | /// ``` |
1504 | /// # use std::num::NonZero; |
1505 | /// # |
1506 | /// # fn main() { test().unwrap(); } |
1507 | /// # fn test() -> Option<()> { |
1508 | #[doc = concat!("let two = NonZero::new(2" , stringify!($Int), ")?;" )] |
1509 | #[doc = concat!("let three = NonZero::new(3" , stringify!($Int), ")?;" )] |
1510 | #[doc = concat!("let four = NonZero::new(4" , stringify!($Int), ")?;" )] |
1511 | #[doc = concat!("let max = NonZero::new(" , stringify!($Int), "::MAX)?;" )] |
1512 | /// |
1513 | /// assert_eq!(Some(two), two.checked_next_power_of_two() ); |
1514 | /// assert_eq!(Some(four), three.checked_next_power_of_two() ); |
1515 | /// assert_eq!(None, max.checked_next_power_of_two() ); |
1516 | /// # Some(()) |
1517 | /// # } |
1518 | /// ``` |
1519 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
1520 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
1521 | #[must_use = "this returns the result of the operation, \ |
1522 | without modifying the original" ] |
1523 | #[inline] |
1524 | pub const fn checked_next_power_of_two(self) -> Option<Self> { |
1525 | if let Some(nz) = self.get().checked_next_power_of_two() { |
1526 | // SAFETY: The next power of two is positive |
1527 | // and overflow is checked. |
1528 | Some(unsafe { Self::new_unchecked(nz) }) |
1529 | } else { |
1530 | None |
1531 | } |
1532 | } |
1533 | |
1534 | /// Returns the base 2 logarithm of the number, rounded down. |
1535 | /// |
1536 | /// This is the same operation as |
1537 | #[doc = concat!("[`" , stringify!($Int), "::ilog2`]," )] |
1538 | /// except that it has no failure cases to worry about |
1539 | /// since this value can never be zero. |
1540 | /// |
1541 | /// # Examples |
1542 | /// |
1543 | /// ``` |
1544 | /// # use std::num::NonZero; |
1545 | /// # |
1546 | /// # fn main() { test().unwrap(); } |
1547 | /// # fn test() -> Option<()> { |
1548 | #[doc = concat!("assert_eq!(NonZero::new(7" , stringify!($Int), ")?.ilog2(), 2);" )] |
1549 | #[doc = concat!("assert_eq!(NonZero::new(8" , stringify!($Int), ")?.ilog2(), 3);" )] |
1550 | #[doc = concat!("assert_eq!(NonZero::new(9" , stringify!($Int), ")?.ilog2(), 3);" )] |
1551 | /// # Some(()) |
1552 | /// # } |
1553 | /// ``` |
1554 | #[stable(feature = "int_log" , since = "1.67.0" )] |
1555 | #[rustc_const_stable(feature = "int_log" , since = "1.67.0" )] |
1556 | #[must_use = "this returns the result of the operation, \ |
1557 | without modifying the original" ] |
1558 | #[inline] |
1559 | pub const fn ilog2(self) -> u32 { |
1560 | Self::BITS - 1 - self.leading_zeros() |
1561 | } |
1562 | |
1563 | /// Returns the base 10 logarithm of the number, rounded down. |
1564 | /// |
1565 | /// This is the same operation as |
1566 | #[doc = concat!("[`" , stringify!($Int), "::ilog10`]," )] |
1567 | /// except that it has no failure cases to worry about |
1568 | /// since this value can never be zero. |
1569 | /// |
1570 | /// # Examples |
1571 | /// |
1572 | /// ``` |
1573 | /// # use std::num::NonZero; |
1574 | /// # |
1575 | /// # fn main() { test().unwrap(); } |
1576 | /// # fn test() -> Option<()> { |
1577 | #[doc = concat!("assert_eq!(NonZero::new(99" , stringify!($Int), ")?.ilog10(), 1);" )] |
1578 | #[doc = concat!("assert_eq!(NonZero::new(100" , stringify!($Int), ")?.ilog10(), 2);" )] |
1579 | #[doc = concat!("assert_eq!(NonZero::new(101" , stringify!($Int), ")?.ilog10(), 2);" )] |
1580 | /// # Some(()) |
1581 | /// # } |
1582 | /// ``` |
1583 | #[stable(feature = "int_log" , since = "1.67.0" )] |
1584 | #[rustc_const_stable(feature = "int_log" , since = "1.67.0" )] |
1585 | #[must_use = "this returns the result of the operation, \ |
1586 | without modifying the original" ] |
1587 | #[inline] |
1588 | pub const fn ilog10(self) -> u32 { |
1589 | super::int_log10::$Int(self.get()) |
1590 | } |
1591 | |
1592 | /// Calculates the middle point of `self` and `rhs`. |
1593 | /// |
1594 | /// `midpoint(a, b)` is `(a + b) >> 1` as if it were performed in a |
1595 | /// sufficiently-large signed integral type. This implies that the result is |
1596 | /// always rounded towards negative infinity and that no overflow will ever occur. |
1597 | /// |
1598 | /// # Examples |
1599 | /// |
1600 | /// ``` |
1601 | /// # use std::num::NonZero; |
1602 | /// # |
1603 | /// # fn main() { test().unwrap(); } |
1604 | /// # fn test() -> Option<()> { |
1605 | #[doc = concat!("let one = NonZero::new(1" , stringify!($Int), ")?;" )] |
1606 | #[doc = concat!("let two = NonZero::new(2" , stringify!($Int), ")?;" )] |
1607 | #[doc = concat!("let four = NonZero::new(4" , stringify!($Int), ")?;" )] |
1608 | /// |
1609 | /// assert_eq!(one.midpoint(four), two); |
1610 | /// assert_eq!(four.midpoint(one), two); |
1611 | /// # Some(()) |
1612 | /// # } |
1613 | /// ``` |
1614 | #[stable(feature = "num_midpoint" , since = "1.85.0" )] |
1615 | #[rustc_const_stable(feature = "num_midpoint" , since = "1.85.0" )] |
1616 | #[must_use = "this returns the result of the operation, \ |
1617 | without modifying the original" ] |
1618 | #[inline] |
1619 | pub const fn midpoint(self, rhs: Self) -> Self { |
1620 | // SAFETY: The only way to get `0` with midpoint is to have two opposite or |
1621 | // near opposite numbers: (-5, 5), (0, 1), (0, 0) which is impossible because |
1622 | // of the unsignedness of this number and also because `Self` is guaranteed to |
1623 | // never being 0. |
1624 | unsafe { Self::new_unchecked(self.get().midpoint(rhs.get())) } |
1625 | } |
1626 | |
1627 | /// Returns `true` if and only if `self == (1 << k)` for some `k`. |
1628 | /// |
1629 | /// On many architectures, this function can perform better than `is_power_of_two()` |
1630 | /// on the underlying integer type, as special handling of zero can be avoided. |
1631 | /// |
1632 | /// # Examples |
1633 | /// |
1634 | /// Basic usage: |
1635 | /// |
1636 | /// ``` |
1637 | /// # use std::num::NonZero; |
1638 | /// # |
1639 | /// # fn main() { test().unwrap(); } |
1640 | /// # fn test() -> Option<()> { |
1641 | #[doc = concat!("let eight = NonZero::new(8" , stringify!($Int), ")?;" )] |
1642 | /// assert!(eight.is_power_of_two()); |
1643 | #[doc = concat!("let ten = NonZero::new(10" , stringify!($Int), ")?;" )] |
1644 | /// assert!(!ten.is_power_of_two()); |
1645 | /// # Some(()) |
1646 | /// # } |
1647 | /// ``` |
1648 | #[must_use] |
1649 | #[stable(feature = "nonzero_is_power_of_two" , since = "1.59.0" )] |
1650 | #[rustc_const_stable(feature = "nonzero_is_power_of_two" , since = "1.59.0" )] |
1651 | #[inline] |
1652 | pub const fn is_power_of_two(self) -> bool { |
1653 | // LLVM 11 normalizes `unchecked_sub(x, 1) & x == 0` to the implementation seen here. |
1654 | // On the basic x86-64 target, this saves 3 instructions for the zero check. |
1655 | // On x86_64 with BMI1, being nonzero lets it codegen to `BLSR`, which saves an instruction |
1656 | // compared to the `POPCNT` implementation on the underlying integer type. |
1657 | |
1658 | intrinsics::ctpop(self.get()) < 2 |
1659 | } |
1660 | |
1661 | /// Returns the square root of the number, rounded down. |
1662 | /// |
1663 | /// # Examples |
1664 | /// |
1665 | /// Basic usage: |
1666 | /// ``` |
1667 | /// # use std::num::NonZero; |
1668 | /// # |
1669 | /// # fn main() { test().unwrap(); } |
1670 | /// # fn test() -> Option<()> { |
1671 | #[doc = concat!("let ten = NonZero::new(10" , stringify!($Int), ")?;" )] |
1672 | #[doc = concat!("let three = NonZero::new(3" , stringify!($Int), ")?;" )] |
1673 | /// |
1674 | /// assert_eq!(ten.isqrt(), three); |
1675 | /// # Some(()) |
1676 | /// # } |
1677 | /// ``` |
1678 | #[stable(feature = "isqrt" , since = "1.84.0" )] |
1679 | #[rustc_const_stable(feature = "isqrt" , since = "1.84.0" )] |
1680 | #[must_use = "this returns the result of the operation, \ |
1681 | without modifying the original" ] |
1682 | #[inline] |
1683 | pub const fn isqrt(self) -> Self { |
1684 | let result = self.get().isqrt(); |
1685 | |
1686 | // SAFETY: Integer square root is a monotonically nondecreasing |
1687 | // function, which means that increasing the input will never cause |
1688 | // the output to decrease. Thus, since the input for nonzero |
1689 | // unsigned integers has a lower bound of 1, the lower bound of the |
1690 | // results will be sqrt(1), which is 1, so a result can't be zero. |
1691 | unsafe { Self::new_unchecked(result) } |
1692 | } |
1693 | |
1694 | /// Returns the bit pattern of `self` reinterpreted as a signed integer of the same size. |
1695 | /// |
1696 | /// # Examples |
1697 | /// |
1698 | /// Basic usage: |
1699 | /// |
1700 | /// ``` |
1701 | /// # use std::num::NonZero; |
1702 | /// |
1703 | #[doc = concat!("let n = NonZero::<" , stringify!($Int), ">::MAX;" )] |
1704 | /// |
1705 | #[doc = concat!("assert_eq!(n.cast_signed(), NonZero::new(-1" , stringify!($Sint), ").unwrap());" )] |
1706 | /// ``` |
1707 | #[stable(feature = "integer_sign_cast" , since = "1.87.0" )] |
1708 | #[rustc_const_stable(feature = "integer_sign_cast" , since = "1.87.0" )] |
1709 | #[must_use = "this returns the result of the operation, \ |
1710 | without modifying the original" ] |
1711 | #[inline(always)] |
1712 | pub const fn cast_signed(self) -> NonZero<$Sint> { |
1713 | // SAFETY: `self.get()` can't be zero |
1714 | unsafe { NonZero::new_unchecked(self.get().cast_signed()) } |
1715 | } |
1716 | }; |
1717 | |
1718 | // Associated items for signed nonzero types only. |
1719 | ( |
1720 | Primitive = signed $Int:ident, |
1721 | SignedPrimitive = $Sint:ty, |
1722 | UnsignedPrimitive = $Uint:ty, |
1723 | ) => { |
1724 | /// The smallest value that can be represented by this non-zero |
1725 | /// integer type, |
1726 | #[doc = concat!("equal to [`" , stringify!($Int), "::MIN`]." )] |
1727 | /// |
1728 | /// Note: While most integer types are defined for every whole |
1729 | /// number between `MIN` and `MAX`, signed non-zero integers are |
1730 | /// a special case. They have a "gap" at 0. |
1731 | /// |
1732 | /// # Examples |
1733 | /// |
1734 | /// ``` |
1735 | /// # use std::num::NonZero; |
1736 | /// # |
1737 | #[doc = concat!("assert_eq!(NonZero::<" , stringify!($Int), ">::MIN.get(), " , stringify!($Int), "::MIN);" )] |
1738 | /// ``` |
1739 | #[stable(feature = "nonzero_min_max" , since = "1.70.0" )] |
1740 | pub const MIN: Self = Self::new(<$Int>::MIN).unwrap(); |
1741 | |
1742 | /// The largest value that can be represented by this non-zero |
1743 | /// integer type, |
1744 | #[doc = concat!("equal to [`" , stringify!($Int), "::MAX`]." )] |
1745 | /// |
1746 | /// Note: While most integer types are defined for every whole |
1747 | /// number between `MIN` and `MAX`, signed non-zero integers are |
1748 | /// a special case. They have a "gap" at 0. |
1749 | /// |
1750 | /// # Examples |
1751 | /// |
1752 | /// ``` |
1753 | /// # use std::num::NonZero; |
1754 | /// # |
1755 | #[doc = concat!("assert_eq!(NonZero::<" , stringify!($Int), ">::MAX.get(), " , stringify!($Int), "::MAX);" )] |
1756 | /// ``` |
1757 | #[stable(feature = "nonzero_min_max" , since = "1.70.0" )] |
1758 | pub const MAX: Self = Self::new(<$Int>::MAX).unwrap(); |
1759 | |
1760 | /// Computes the absolute value of self. |
1761 | #[doc = concat!("See [`" , stringify!($Int), "::abs`]" )] |
1762 | /// for documentation on overflow behavior. |
1763 | /// |
1764 | /// # Example |
1765 | /// |
1766 | /// ``` |
1767 | /// # use std::num::NonZero; |
1768 | /// # |
1769 | /// # fn main() { test().unwrap(); } |
1770 | /// # fn test() -> Option<()> { |
1771 | #[doc = concat!("let pos = NonZero::new(1" , stringify!($Int), ")?;" )] |
1772 | #[doc = concat!("let neg = NonZero::new(-1" , stringify!($Int), ")?;" )] |
1773 | /// |
1774 | /// assert_eq!(pos, pos.abs()); |
1775 | /// assert_eq!(pos, neg.abs()); |
1776 | /// # Some(()) |
1777 | /// # } |
1778 | /// ``` |
1779 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
1780 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
1781 | #[must_use = "this returns the result of the operation, \ |
1782 | without modifying the original" ] |
1783 | #[inline] |
1784 | pub const fn abs(self) -> Self { |
1785 | // SAFETY: This cannot overflow to zero. |
1786 | unsafe { Self::new_unchecked(self.get().abs()) } |
1787 | } |
1788 | |
1789 | /// Checked absolute value. |
1790 | /// Checks for overflow and returns [`None`] if |
1791 | #[doc = concat!("`self == NonZero::<" , stringify!($Int), ">::MIN`." )] |
1792 | /// The result cannot be zero. |
1793 | /// |
1794 | /// # Example |
1795 | /// |
1796 | /// ``` |
1797 | /// # use std::num::NonZero; |
1798 | /// # |
1799 | /// # fn main() { test().unwrap(); } |
1800 | /// # fn test() -> Option<()> { |
1801 | #[doc = concat!("let pos = NonZero::new(1" , stringify!($Int), ")?;" )] |
1802 | #[doc = concat!("let neg = NonZero::new(-1" , stringify!($Int), ")?;" )] |
1803 | #[doc = concat!("let min = NonZero::new(" , stringify!($Int), "::MIN)?;" )] |
1804 | /// |
1805 | /// assert_eq!(Some(pos), neg.checked_abs()); |
1806 | /// assert_eq!(None, min.checked_abs()); |
1807 | /// # Some(()) |
1808 | /// # } |
1809 | /// ``` |
1810 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
1811 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
1812 | #[must_use = "this returns the result of the operation, \ |
1813 | without modifying the original" ] |
1814 | #[inline] |
1815 | pub const fn checked_abs(self) -> Option<Self> { |
1816 | if let Some(nz) = self.get().checked_abs() { |
1817 | // SAFETY: absolute value of nonzero cannot yield zero values. |
1818 | Some(unsafe { Self::new_unchecked(nz) }) |
1819 | } else { |
1820 | None |
1821 | } |
1822 | } |
1823 | |
1824 | /// Computes the absolute value of self, |
1825 | /// with overflow information, see |
1826 | #[doc = concat!("[`" , stringify!($Int), "::overflowing_abs`]." )] |
1827 | /// |
1828 | /// # Example |
1829 | /// |
1830 | /// ``` |
1831 | /// # use std::num::NonZero; |
1832 | /// # |
1833 | /// # fn main() { test().unwrap(); } |
1834 | /// # fn test() -> Option<()> { |
1835 | #[doc = concat!("let pos = NonZero::new(1" , stringify!($Int), ")?;" )] |
1836 | #[doc = concat!("let neg = NonZero::new(-1" , stringify!($Int), ")?;" )] |
1837 | #[doc = concat!("let min = NonZero::new(" , stringify!($Int), "::MIN)?;" )] |
1838 | /// |
1839 | /// assert_eq!((pos, false), pos.overflowing_abs()); |
1840 | /// assert_eq!((pos, false), neg.overflowing_abs()); |
1841 | /// assert_eq!((min, true), min.overflowing_abs()); |
1842 | /// # Some(()) |
1843 | /// # } |
1844 | /// ``` |
1845 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
1846 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
1847 | #[must_use = "this returns the result of the operation, \ |
1848 | without modifying the original" ] |
1849 | #[inline] |
1850 | pub const fn overflowing_abs(self) -> (Self, bool) { |
1851 | let (nz, flag) = self.get().overflowing_abs(); |
1852 | ( |
1853 | // SAFETY: absolute value of nonzero cannot yield zero values. |
1854 | unsafe { Self::new_unchecked(nz) }, |
1855 | flag, |
1856 | ) |
1857 | } |
1858 | |
1859 | /// Saturating absolute value, see |
1860 | #[doc = concat!("[`" , stringify!($Int), "::saturating_abs`]." )] |
1861 | /// |
1862 | /// # Example |
1863 | /// |
1864 | /// ``` |
1865 | /// # use std::num::NonZero; |
1866 | /// # |
1867 | /// # fn main() { test().unwrap(); } |
1868 | /// # fn test() -> Option<()> { |
1869 | #[doc = concat!("let pos = NonZero::new(1" , stringify!($Int), ")?;" )] |
1870 | #[doc = concat!("let neg = NonZero::new(-1" , stringify!($Int), ")?;" )] |
1871 | #[doc = concat!("let min = NonZero::new(" , stringify!($Int), "::MIN)?;" )] |
1872 | #[doc = concat!("let min_plus = NonZero::new(" , stringify!($Int), "::MIN + 1)?;" )] |
1873 | #[doc = concat!("let max = NonZero::new(" , stringify!($Int), "::MAX)?;" )] |
1874 | /// |
1875 | /// assert_eq!(pos, pos.saturating_abs()); |
1876 | /// assert_eq!(pos, neg.saturating_abs()); |
1877 | /// assert_eq!(max, min.saturating_abs()); |
1878 | /// assert_eq!(max, min_plus.saturating_abs()); |
1879 | /// # Some(()) |
1880 | /// # } |
1881 | /// ``` |
1882 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
1883 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
1884 | #[must_use = "this returns the result of the operation, \ |
1885 | without modifying the original" ] |
1886 | #[inline] |
1887 | pub const fn saturating_abs(self) -> Self { |
1888 | // SAFETY: absolute value of nonzero cannot yield zero values. |
1889 | unsafe { Self::new_unchecked(self.get().saturating_abs()) } |
1890 | } |
1891 | |
1892 | /// Wrapping absolute value, see |
1893 | #[doc = concat!("[`" , stringify!($Int), "::wrapping_abs`]." )] |
1894 | /// |
1895 | /// # Example |
1896 | /// |
1897 | /// ``` |
1898 | /// # use std::num::NonZero; |
1899 | /// # |
1900 | /// # fn main() { test().unwrap(); } |
1901 | /// # fn test() -> Option<()> { |
1902 | #[doc = concat!("let pos = NonZero::new(1" , stringify!($Int), ")?;" )] |
1903 | #[doc = concat!("let neg = NonZero::new(-1" , stringify!($Int), ")?;" )] |
1904 | #[doc = concat!("let min = NonZero::new(" , stringify!($Int), "::MIN)?;" )] |
1905 | #[doc = concat!("# let max = NonZero::new(" , stringify!($Int), "::MAX)?;" )] |
1906 | /// |
1907 | /// assert_eq!(pos, pos.wrapping_abs()); |
1908 | /// assert_eq!(pos, neg.wrapping_abs()); |
1909 | /// assert_eq!(min, min.wrapping_abs()); |
1910 | /// assert_eq!(max, (-max).wrapping_abs()); |
1911 | /// # Some(()) |
1912 | /// # } |
1913 | /// ``` |
1914 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
1915 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
1916 | #[must_use = "this returns the result of the operation, \ |
1917 | without modifying the original" ] |
1918 | #[inline] |
1919 | pub const fn wrapping_abs(self) -> Self { |
1920 | // SAFETY: absolute value of nonzero cannot yield zero values. |
1921 | unsafe { Self::new_unchecked(self.get().wrapping_abs()) } |
1922 | } |
1923 | |
1924 | /// Computes the absolute value of self |
1925 | /// without any wrapping or panicking. |
1926 | /// |
1927 | /// # Example |
1928 | /// |
1929 | /// ``` |
1930 | /// # use std::num::NonZero; |
1931 | /// # |
1932 | /// # fn main() { test().unwrap(); } |
1933 | /// # fn test() -> Option<()> { |
1934 | #[doc = concat!("let u_pos = NonZero::new(1" , stringify!($Uint), ")?;" )] |
1935 | #[doc = concat!("let i_pos = NonZero::new(1" , stringify!($Int), ")?;" )] |
1936 | #[doc = concat!("let i_neg = NonZero::new(-1" , stringify!($Int), ")?;" )] |
1937 | #[doc = concat!("let i_min = NonZero::new(" , stringify!($Int), "::MIN)?;" )] |
1938 | #[doc = concat!("let u_max = NonZero::new(" , stringify!($Uint), "::MAX / 2 + 1)?;" )] |
1939 | /// |
1940 | /// assert_eq!(u_pos, i_pos.unsigned_abs()); |
1941 | /// assert_eq!(u_pos, i_neg.unsigned_abs()); |
1942 | /// assert_eq!(u_max, i_min.unsigned_abs()); |
1943 | /// # Some(()) |
1944 | /// # } |
1945 | /// ``` |
1946 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
1947 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
1948 | #[must_use = "this returns the result of the operation, \ |
1949 | without modifying the original" ] |
1950 | #[inline] |
1951 | pub const fn unsigned_abs(self) -> NonZero<$Uint> { |
1952 | // SAFETY: absolute value of nonzero cannot yield zero values. |
1953 | unsafe { NonZero::new_unchecked(self.get().unsigned_abs()) } |
1954 | } |
1955 | |
1956 | /// Returns `true` if `self` is positive and `false` if the |
1957 | /// number is negative. |
1958 | /// |
1959 | /// # Example |
1960 | /// |
1961 | /// ``` |
1962 | /// # use std::num::NonZero; |
1963 | /// # |
1964 | /// # fn main() { test().unwrap(); } |
1965 | /// # fn test() -> Option<()> { |
1966 | #[doc = concat!("let pos_five = NonZero::new(5" , stringify!($Int), ")?;" )] |
1967 | #[doc = concat!("let neg_five = NonZero::new(-5" , stringify!($Int), ")?;" )] |
1968 | /// |
1969 | /// assert!(pos_five.is_positive()); |
1970 | /// assert!(!neg_five.is_positive()); |
1971 | /// # Some(()) |
1972 | /// # } |
1973 | /// ``` |
1974 | #[must_use] |
1975 | #[inline] |
1976 | #[stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
1977 | #[rustc_const_stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
1978 | pub const fn is_positive(self) -> bool { |
1979 | self.get().is_positive() |
1980 | } |
1981 | |
1982 | /// Returns `true` if `self` is negative and `false` if the |
1983 | /// number is positive. |
1984 | /// |
1985 | /// # Example |
1986 | /// |
1987 | /// ``` |
1988 | /// # use std::num::NonZero; |
1989 | /// # |
1990 | /// # fn main() { test().unwrap(); } |
1991 | /// # fn test() -> Option<()> { |
1992 | #[doc = concat!("let pos_five = NonZero::new(5" , stringify!($Int), ")?;" )] |
1993 | #[doc = concat!("let neg_five = NonZero::new(-5" , stringify!($Int), ")?;" )] |
1994 | /// |
1995 | /// assert!(neg_five.is_negative()); |
1996 | /// assert!(!pos_five.is_negative()); |
1997 | /// # Some(()) |
1998 | /// # } |
1999 | /// ``` |
2000 | #[must_use] |
2001 | #[inline] |
2002 | #[stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
2003 | #[rustc_const_stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
2004 | pub const fn is_negative(self) -> bool { |
2005 | self.get().is_negative() |
2006 | } |
2007 | |
2008 | /// Checked negation. Computes `-self`, |
2009 | #[doc = concat!("returning `None` if `self == NonZero::<" , stringify!($Int), ">::MIN`." )] |
2010 | /// |
2011 | /// # Example |
2012 | /// |
2013 | /// ``` |
2014 | /// # use std::num::NonZero; |
2015 | /// # |
2016 | /// # fn main() { test().unwrap(); } |
2017 | /// # fn test() -> Option<()> { |
2018 | #[doc = concat!("let pos_five = NonZero::new(5" , stringify!($Int), ")?;" )] |
2019 | #[doc = concat!("let neg_five = NonZero::new(-5" , stringify!($Int), ")?;" )] |
2020 | #[doc = concat!("let min = NonZero::new(" , stringify!($Int), "::MIN)?;" )] |
2021 | /// |
2022 | /// assert_eq!(pos_five.checked_neg(), Some(neg_five)); |
2023 | /// assert_eq!(min.checked_neg(), None); |
2024 | /// # Some(()) |
2025 | /// # } |
2026 | /// ``` |
2027 | #[inline] |
2028 | #[stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
2029 | #[rustc_const_stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
2030 | pub const fn checked_neg(self) -> Option<Self> { |
2031 | if let Some(result) = self.get().checked_neg() { |
2032 | // SAFETY: negation of nonzero cannot yield zero values. |
2033 | return Some(unsafe { Self::new_unchecked(result) }); |
2034 | } |
2035 | None |
2036 | } |
2037 | |
2038 | /// Negates self, overflowing if this is equal to the minimum value. |
2039 | /// |
2040 | #[doc = concat!("See [`" , stringify!($Int), "::overflowing_neg`]" )] |
2041 | /// for documentation on overflow behavior. |
2042 | /// |
2043 | /// # Example |
2044 | /// |
2045 | /// ``` |
2046 | /// # use std::num::NonZero; |
2047 | /// # |
2048 | /// # fn main() { test().unwrap(); } |
2049 | /// # fn test() -> Option<()> { |
2050 | #[doc = concat!("let pos_five = NonZero::new(5" , stringify!($Int), ")?;" )] |
2051 | #[doc = concat!("let neg_five = NonZero::new(-5" , stringify!($Int), ")?;" )] |
2052 | #[doc = concat!("let min = NonZero::new(" , stringify!($Int), "::MIN)?;" )] |
2053 | /// |
2054 | /// assert_eq!(pos_five.overflowing_neg(), (neg_five, false)); |
2055 | /// assert_eq!(min.overflowing_neg(), (min, true)); |
2056 | /// # Some(()) |
2057 | /// # } |
2058 | /// ``` |
2059 | #[inline] |
2060 | #[stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
2061 | #[rustc_const_stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
2062 | pub const fn overflowing_neg(self) -> (Self, bool) { |
2063 | let (result, overflow) = self.get().overflowing_neg(); |
2064 | // SAFETY: negation of nonzero cannot yield zero values. |
2065 | ((unsafe { Self::new_unchecked(result) }), overflow) |
2066 | } |
2067 | |
2068 | /// Saturating negation. Computes `-self`, |
2069 | #[doc = concat!("returning [`NonZero::<" , stringify!($Int), ">::MAX`]" )] |
2070 | #[doc = concat!("if `self == NonZero::<" , stringify!($Int), ">::MIN`" )] |
2071 | /// instead of overflowing. |
2072 | /// |
2073 | /// # Example |
2074 | /// |
2075 | /// ``` |
2076 | /// # use std::num::NonZero; |
2077 | /// # |
2078 | /// # fn main() { test().unwrap(); } |
2079 | /// # fn test() -> Option<()> { |
2080 | #[doc = concat!("let pos_five = NonZero::new(5" , stringify!($Int), ")?;" )] |
2081 | #[doc = concat!("let neg_five = NonZero::new(-5" , stringify!($Int), ")?;" )] |
2082 | #[doc = concat!("let min = NonZero::new(" , stringify!($Int), "::MIN)?;" )] |
2083 | #[doc = concat!("let min_plus_one = NonZero::new(" , stringify!($Int), "::MIN + 1)?;" )] |
2084 | #[doc = concat!("let max = NonZero::new(" , stringify!($Int), "::MAX)?;" )] |
2085 | /// |
2086 | /// assert_eq!(pos_five.saturating_neg(), neg_five); |
2087 | /// assert_eq!(min.saturating_neg(), max); |
2088 | /// assert_eq!(max.saturating_neg(), min_plus_one); |
2089 | /// # Some(()) |
2090 | /// # } |
2091 | /// ``` |
2092 | #[inline] |
2093 | #[stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
2094 | #[rustc_const_stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
2095 | pub const fn saturating_neg(self) -> Self { |
2096 | if let Some(result) = self.checked_neg() { |
2097 | return result; |
2098 | } |
2099 | Self::MAX |
2100 | } |
2101 | |
2102 | /// Wrapping (modular) negation. Computes `-self`, wrapping around at the boundary |
2103 | /// of the type. |
2104 | /// |
2105 | #[doc = concat!("See [`" , stringify!($Int), "::wrapping_neg`]" )] |
2106 | /// for documentation on overflow behavior. |
2107 | /// |
2108 | /// # Example |
2109 | /// |
2110 | /// ``` |
2111 | /// # use std::num::NonZero; |
2112 | /// # |
2113 | /// # fn main() { test().unwrap(); } |
2114 | /// # fn test() -> Option<()> { |
2115 | #[doc = concat!("let pos_five = NonZero::new(5" , stringify!($Int), ")?;" )] |
2116 | #[doc = concat!("let neg_five = NonZero::new(-5" , stringify!($Int), ")?;" )] |
2117 | #[doc = concat!("let min = NonZero::new(" , stringify!($Int), "::MIN)?;" )] |
2118 | /// |
2119 | /// assert_eq!(pos_five.wrapping_neg(), neg_five); |
2120 | /// assert_eq!(min.wrapping_neg(), min); |
2121 | /// # Some(()) |
2122 | /// # } |
2123 | /// ``` |
2124 | #[inline] |
2125 | #[stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
2126 | #[rustc_const_stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
2127 | pub const fn wrapping_neg(self) -> Self { |
2128 | let result = self.get().wrapping_neg(); |
2129 | // SAFETY: negation of nonzero cannot yield zero values. |
2130 | unsafe { Self::new_unchecked(result) } |
2131 | } |
2132 | |
2133 | /// Returns the bit pattern of `self` reinterpreted as an unsigned integer of the same size. |
2134 | /// |
2135 | /// # Examples |
2136 | /// |
2137 | /// Basic usage: |
2138 | /// |
2139 | /// ``` |
2140 | /// # use std::num::NonZero; |
2141 | /// |
2142 | #[doc = concat!("let n = NonZero::new(-1" , stringify!($Int), ").unwrap();" )] |
2143 | /// |
2144 | #[doc = concat!("assert_eq!(n.cast_unsigned(), NonZero::<" , stringify!($Uint), ">::MAX);" )] |
2145 | /// ``` |
2146 | #[stable(feature = "integer_sign_cast" , since = "1.87.0" )] |
2147 | #[rustc_const_stable(feature = "integer_sign_cast" , since = "1.87.0" )] |
2148 | #[must_use = "this returns the result of the operation, \ |
2149 | without modifying the original" ] |
2150 | #[inline(always)] |
2151 | pub const fn cast_unsigned(self) -> NonZero<$Uint> { |
2152 | // SAFETY: `self.get()` can't be zero |
2153 | unsafe { NonZero::new_unchecked(self.get().cast_unsigned()) } |
2154 | } |
2155 | |
2156 | }; |
2157 | } |
2158 | |
2159 | nonzero_integer! { |
2160 | Self = NonZeroU8, |
2161 | Primitive = unsigned u8, |
2162 | SignedPrimitive = i8, |
2163 | rot = 2, |
2164 | rot_op = "0x82" , |
2165 | rot_result = "0xa" , |
2166 | swap_op = "0x12" , |
2167 | swapped = "0x12" , |
2168 | reversed = "0x48" , |
2169 | } |
2170 | |
2171 | nonzero_integer! { |
2172 | Self = NonZeroU16, |
2173 | Primitive = unsigned u16, |
2174 | SignedPrimitive = i16, |
2175 | rot = 4, |
2176 | rot_op = "0xa003" , |
2177 | rot_result = "0x3a" , |
2178 | swap_op = "0x1234" , |
2179 | swapped = "0x3412" , |
2180 | reversed = "0x2c48" , |
2181 | } |
2182 | |
2183 | nonzero_integer! { |
2184 | Self = NonZeroU32, |
2185 | Primitive = unsigned u32, |
2186 | SignedPrimitive = i32, |
2187 | rot = 8, |
2188 | rot_op = "0x10000b3" , |
2189 | rot_result = "0xb301" , |
2190 | swap_op = "0x12345678" , |
2191 | swapped = "0x78563412" , |
2192 | reversed = "0x1e6a2c48" , |
2193 | } |
2194 | |
2195 | nonzero_integer! { |
2196 | Self = NonZeroU64, |
2197 | Primitive = unsigned u64, |
2198 | SignedPrimitive = i64, |
2199 | rot = 12, |
2200 | rot_op = "0xaa00000000006e1" , |
2201 | rot_result = "0x6e10aa" , |
2202 | swap_op = "0x1234567890123456" , |
2203 | swapped = "0x5634129078563412" , |
2204 | reversed = "0x6a2c48091e6a2c48" , |
2205 | } |
2206 | |
2207 | nonzero_integer! { |
2208 | Self = NonZeroU128, |
2209 | Primitive = unsigned u128, |
2210 | SignedPrimitive = i128, |
2211 | rot = 16, |
2212 | rot_op = "0x13f40000000000000000000000004f76" , |
2213 | rot_result = "0x4f7613f4" , |
2214 | swap_op = "0x12345678901234567890123456789012" , |
2215 | swapped = "0x12907856341290785634129078563412" , |
2216 | reversed = "0x48091e6a2c48091e6a2c48091e6a2c48" , |
2217 | } |
2218 | |
2219 | #[cfg (target_pointer_width = "16" )] |
2220 | nonzero_integer! { |
2221 | Self = NonZeroUsize, |
2222 | Primitive = unsigned usize, |
2223 | SignedPrimitive = isize, |
2224 | rot = 4, |
2225 | rot_op = "0xa003" , |
2226 | rot_result = "0x3a" , |
2227 | swap_op = "0x1234" , |
2228 | swapped = "0x3412" , |
2229 | reversed = "0x2c48" , |
2230 | } |
2231 | |
2232 | #[cfg (target_pointer_width = "32" )] |
2233 | nonzero_integer! { |
2234 | Self = NonZeroUsize, |
2235 | Primitive = unsigned usize, |
2236 | SignedPrimitive = isize, |
2237 | rot = 8, |
2238 | rot_op = "0x10000b3" , |
2239 | rot_result = "0xb301" , |
2240 | swap_op = "0x12345678" , |
2241 | swapped = "0x78563412" , |
2242 | reversed = "0x1e6a2c48" , |
2243 | } |
2244 | |
2245 | #[cfg (target_pointer_width = "64" )] |
2246 | nonzero_integer! { |
2247 | Self = NonZeroUsize, |
2248 | Primitive = unsigned usize, |
2249 | SignedPrimitive = isize, |
2250 | rot = 12, |
2251 | rot_op = "0xaa00000000006e1" , |
2252 | rot_result = "0x6e10aa" , |
2253 | swap_op = "0x1234567890123456" , |
2254 | swapped = "0x5634129078563412" , |
2255 | reversed = "0x6a2c48091e6a2c48" , |
2256 | } |
2257 | |
2258 | nonzero_integer! { |
2259 | Self = NonZeroI8, |
2260 | Primitive = signed i8, |
2261 | UnsignedPrimitive = u8, |
2262 | rot = 2, |
2263 | rot_op = "-0x7e" , |
2264 | rot_result = "0xa" , |
2265 | swap_op = "0x12" , |
2266 | swapped = "0x12" , |
2267 | reversed = "0x48" , |
2268 | } |
2269 | |
2270 | nonzero_integer! { |
2271 | Self = NonZeroI16, |
2272 | Primitive = signed i16, |
2273 | UnsignedPrimitive = u16, |
2274 | rot = 4, |
2275 | rot_op = "-0x5ffd" , |
2276 | rot_result = "0x3a" , |
2277 | swap_op = "0x1234" , |
2278 | swapped = "0x3412" , |
2279 | reversed = "0x2c48" , |
2280 | } |
2281 | |
2282 | nonzero_integer! { |
2283 | Self = NonZeroI32, |
2284 | Primitive = signed i32, |
2285 | UnsignedPrimitive = u32, |
2286 | rot = 8, |
2287 | rot_op = "0x10000b3" , |
2288 | rot_result = "0xb301" , |
2289 | swap_op = "0x12345678" , |
2290 | swapped = "0x78563412" , |
2291 | reversed = "0x1e6a2c48" , |
2292 | } |
2293 | |
2294 | nonzero_integer! { |
2295 | Self = NonZeroI64, |
2296 | Primitive = signed i64, |
2297 | UnsignedPrimitive = u64, |
2298 | rot = 12, |
2299 | rot_op = "0xaa00000000006e1" , |
2300 | rot_result = "0x6e10aa" , |
2301 | swap_op = "0x1234567890123456" , |
2302 | swapped = "0x5634129078563412" , |
2303 | reversed = "0x6a2c48091e6a2c48" , |
2304 | } |
2305 | |
2306 | nonzero_integer! { |
2307 | Self = NonZeroI128, |
2308 | Primitive = signed i128, |
2309 | UnsignedPrimitive = u128, |
2310 | rot = 16, |
2311 | rot_op = "0x13f40000000000000000000000004f76" , |
2312 | rot_result = "0x4f7613f4" , |
2313 | swap_op = "0x12345678901234567890123456789012" , |
2314 | swapped = "0x12907856341290785634129078563412" , |
2315 | reversed = "0x48091e6a2c48091e6a2c48091e6a2c48" , |
2316 | } |
2317 | |
2318 | #[cfg (target_pointer_width = "16" )] |
2319 | nonzero_integer! { |
2320 | Self = NonZeroIsize, |
2321 | Primitive = signed isize, |
2322 | UnsignedPrimitive = usize, |
2323 | rot = 4, |
2324 | rot_op = "-0x5ffd" , |
2325 | rot_result = "0x3a" , |
2326 | swap_op = "0x1234" , |
2327 | swapped = "0x3412" , |
2328 | reversed = "0x2c48" , |
2329 | } |
2330 | |
2331 | #[cfg (target_pointer_width = "32" )] |
2332 | nonzero_integer! { |
2333 | Self = NonZeroIsize, |
2334 | Primitive = signed isize, |
2335 | UnsignedPrimitive = usize, |
2336 | rot = 8, |
2337 | rot_op = "0x10000b3" , |
2338 | rot_result = "0xb301" , |
2339 | swap_op = "0x12345678" , |
2340 | swapped = "0x78563412" , |
2341 | reversed = "0x1e6a2c48" , |
2342 | } |
2343 | |
2344 | #[cfg (target_pointer_width = "64" )] |
2345 | nonzero_integer! { |
2346 | Self = NonZeroIsize, |
2347 | Primitive = signed isize, |
2348 | UnsignedPrimitive = usize, |
2349 | rot = 12, |
2350 | rot_op = "0xaa00000000006e1" , |
2351 | rot_result = "0x6e10aa" , |
2352 | swap_op = "0x1234567890123456" , |
2353 | swapped = "0x5634129078563412" , |
2354 | reversed = "0x6a2c48091e6a2c48" , |
2355 | } |
2356 | |