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