1 | //! Definitions of integer that is known not to equal zero. |
2 | |
3 | use crate::cmp::Ordering; |
4 | use crate::fmt; |
5 | use crate::hash::{Hash, Hasher}; |
6 | use crate::intrinsics; |
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::ptr; |
11 | use crate::str::FromStr; |
12 | use crate::ub_checks; |
13 | |
14 | use super::{IntErrorKind, ParseIntError}; |
15 | |
16 | /// A marker trait for primitive types which can be zero. |
17 | /// |
18 | /// This is an implementation detail for <code>[NonZero]\<T></code> which may disappear or be replaced at any time. |
19 | /// |
20 | /// # Safety |
21 | /// |
22 | /// Types implementing this trait must be primitives that are valid when zeroed. |
23 | /// |
24 | /// The associated `Self::NonZeroInner` type must have the same size+align as `Self`, |
25 | /// but with a niche and bit validity making it so the following `transmutes` are sound: |
26 | /// |
27 | /// - `Self::NonZeroInner` to `Option<Self::NonZeroInner>` |
28 | /// - `Option<Self::NonZeroInner>` to `Self` |
29 | /// |
30 | /// (And, consequently, `Self::NonZeroInner` to `Self`.) |
31 | #[unstable ( |
32 | feature = "nonzero_internals" , |
33 | reason = "implementation detail which may disappear or be replaced at any time" , |
34 | issue = "none" |
35 | )] |
36 | #[const_trait ] |
37 | pub unsafe trait ZeroablePrimitive: Sized + Copy + private::Sealed { |
38 | #[doc (hidden)] |
39 | type NonZeroInner: Sized + Copy; |
40 | } |
41 | |
42 | macro_rules! impl_zeroable_primitive { |
43 | ($($NonZeroInner:ident ( $primitive:ty )),+ $(,)?) => { |
44 | mod private { |
45 | #[unstable( |
46 | feature = "nonzero_internals" , |
47 | reason = "implementation detail which may disappear or be replaced at any time" , |
48 | issue = "none" |
49 | )] |
50 | #[const_trait] |
51 | pub trait Sealed {} |
52 | |
53 | $( |
54 | #[derive(Debug, Clone, Copy, PartialEq)] |
55 | #[repr(transparent)] |
56 | #[rustc_layout_scalar_valid_range_start(1)] |
57 | #[rustc_nonnull_optimization_guaranteed] |
58 | #[unstable( |
59 | feature = "nonzero_internals" , |
60 | reason = "implementation detail which may disappear or be replaced at any time" , |
61 | issue = "none" |
62 | )] |
63 | pub struct $NonZeroInner($primitive); |
64 | )+ |
65 | } |
66 | |
67 | $( |
68 | #[unstable( |
69 | feature = "nonzero_internals" , |
70 | reason = "implementation detail which may disappear or be replaced at any time" , |
71 | issue = "none" |
72 | )] |
73 | impl const private::Sealed for $primitive {} |
74 | |
75 | #[unstable( |
76 | feature = "nonzero_internals" , |
77 | reason = "implementation detail which may disappear or be replaced at any time" , |
78 | issue = "none" |
79 | )] |
80 | unsafe impl const ZeroablePrimitive for $primitive { |
81 | type NonZeroInner = private::$NonZeroInner; |
82 | } |
83 | )+ |
84 | }; |
85 | } |
86 | |
87 | impl_zeroable_primitive!( |
88 | NonZeroU8Inner(u8), |
89 | NonZeroU16Inner(u16), |
90 | NonZeroU32Inner(u32), |
91 | NonZeroU64Inner(u64), |
92 | NonZeroU128Inner(u128), |
93 | NonZeroUsizeInner(usize), |
94 | NonZeroI8Inner(i8), |
95 | NonZeroI16Inner(i16), |
96 | NonZeroI32Inner(i32), |
97 | NonZeroI64Inner(i64), |
98 | NonZeroI128Inner(i128), |
99 | NonZeroIsizeInner(isize), |
100 | ); |
101 | |
102 | /// A value that is known not to equal zero. |
103 | /// |
104 | /// This enables some memory layout optimization. |
105 | /// For example, `Option<NonZero<u32>>` is the same size as `u32`: |
106 | /// |
107 | /// ``` |
108 | /// use core::{mem::size_of, num::NonZero}; |
109 | /// |
110 | /// assert_eq!(size_of::<Option<NonZero<u32>>>(), size_of::<u32>()); |
111 | /// ``` |
112 | #[stable (feature = "generic_nonzero" , since = "CURRENT_RUSTC_VERSION" )] |
113 | #[repr (transparent)] |
114 | #[rustc_nonnull_optimization_guaranteed ] |
115 | #[rustc_diagnostic_item = "NonZero" ] |
116 | pub struct NonZero<T: ZeroablePrimitive>(T::NonZeroInner); |
117 | |
118 | macro_rules! impl_nonzero_fmt { |
119 | ($Trait:ident) => { |
120 | #[stable(feature = "nonzero" , since = "1.28.0" )] |
121 | impl<T> fmt::$Trait for NonZero<T> |
122 | where |
123 | T: ZeroablePrimitive + fmt::$Trait, |
124 | { |
125 | #[inline] |
126 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
127 | self.get().fmt(f) |
128 | } |
129 | } |
130 | }; |
131 | } |
132 | |
133 | impl_nonzero_fmt!(Debug); |
134 | impl_nonzero_fmt!(Display); |
135 | impl_nonzero_fmt!(Binary); |
136 | impl_nonzero_fmt!(Octal); |
137 | impl_nonzero_fmt!(LowerHex); |
138 | impl_nonzero_fmt!(UpperHex); |
139 | |
140 | macro_rules! impl_nonzero_auto_trait { |
141 | (unsafe $Trait:ident) => { |
142 | #[stable(feature = "nonzero" , since = "1.28.0" )] |
143 | unsafe impl<T> $Trait for NonZero<T> where T: ZeroablePrimitive + $Trait {} |
144 | }; |
145 | ($Trait:ident) => { |
146 | #[stable(feature = "nonzero" , since = "1.28.0" )] |
147 | impl<T> $Trait for NonZero<T> where T: ZeroablePrimitive + $Trait {} |
148 | }; |
149 | } |
150 | |
151 | // Implement auto-traits manually based on `T` to avoid docs exposing |
152 | // the `ZeroablePrimitive::NonZeroInner` implementation detail. |
153 | impl_nonzero_auto_trait!(unsafe Freeze); |
154 | impl_nonzero_auto_trait!(RefUnwindSafe); |
155 | impl_nonzero_auto_trait!(unsafe Send); |
156 | impl_nonzero_auto_trait!(unsafe Sync); |
157 | impl_nonzero_auto_trait!(Unpin); |
158 | impl_nonzero_auto_trait!(UnwindSafe); |
159 | |
160 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
161 | impl<T> Clone for NonZero<T> |
162 | where |
163 | T: ZeroablePrimitive, |
164 | { |
165 | #[inline ] |
166 | fn clone(&self) -> Self { |
167 | Self(self.0) |
168 | } |
169 | } |
170 | |
171 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
172 | impl<T> Copy for NonZero<T> where T: ZeroablePrimitive {} |
173 | |
174 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
175 | impl<T> PartialEq for NonZero<T> |
176 | where |
177 | T: ZeroablePrimitive + PartialEq, |
178 | { |
179 | #[inline ] |
180 | fn eq(&self, other: &Self) -> bool { |
181 | self.get() == other.get() |
182 | } |
183 | |
184 | #[inline ] |
185 | fn ne(&self, other: &Self) -> bool { |
186 | self.get() != other.get() |
187 | } |
188 | } |
189 | |
190 | #[unstable (feature = "structural_match" , issue = "31434" )] |
191 | impl<T> StructuralPartialEq for NonZero<T> where T: ZeroablePrimitive + StructuralPartialEq {} |
192 | |
193 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
194 | impl<T> Eq for NonZero<T> where T: ZeroablePrimitive + Eq {} |
195 | |
196 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
197 | impl<T> PartialOrd for NonZero<T> |
198 | where |
199 | T: ZeroablePrimitive + PartialOrd, |
200 | { |
201 | #[inline ] |
202 | fn partial_cmp(&self, other: &Self) -> Option<Ordering> { |
203 | self.get().partial_cmp(&other.get()) |
204 | } |
205 | |
206 | #[inline ] |
207 | fn lt(&self, other: &Self) -> bool { |
208 | self.get() < other.get() |
209 | } |
210 | |
211 | #[inline ] |
212 | fn le(&self, other: &Self) -> bool { |
213 | self.get() <= other.get() |
214 | } |
215 | |
216 | #[inline ] |
217 | fn gt(&self, other: &Self) -> bool { |
218 | self.get() > other.get() |
219 | } |
220 | |
221 | #[inline ] |
222 | fn ge(&self, other: &Self) -> bool { |
223 | self.get() >= other.get() |
224 | } |
225 | } |
226 | |
227 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
228 | impl<T> Ord for NonZero<T> |
229 | where |
230 | T: ZeroablePrimitive + Ord, |
231 | { |
232 | #[inline ] |
233 | fn cmp(&self, other: &Self) -> Ordering { |
234 | self.get().cmp(&other.get()) |
235 | } |
236 | |
237 | #[inline ] |
238 | fn max(self, other: Self) -> Self { |
239 | // SAFETY: The maximum of two non-zero values is still non-zero. |
240 | unsafe { Self::new_unchecked(self.get().max(other.get())) } |
241 | } |
242 | |
243 | #[inline ] |
244 | fn min(self, other: Self) -> Self { |
245 | // SAFETY: The minimum of two non-zero values is still non-zero. |
246 | unsafe { Self::new_unchecked(self.get().min(other.get())) } |
247 | } |
248 | |
249 | #[inline ] |
250 | fn clamp(self, min: Self, max: Self) -> Self { |
251 | // SAFETY: A non-zero value clamped between two non-zero values is still non-zero. |
252 | unsafe { Self::new_unchecked(self.get().clamp(min:min.get(), max:max.get())) } |
253 | } |
254 | } |
255 | |
256 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
257 | impl<T> Hash for NonZero<T> |
258 | where |
259 | T: ZeroablePrimitive + Hash, |
260 | { |
261 | #[inline ] |
262 | fn hash<H>(&self, state: &mut H) |
263 | where |
264 | H: Hasher, |
265 | { |
266 | self.get().hash(state) |
267 | } |
268 | } |
269 | |
270 | #[stable (feature = "from_nonzero" , since = "1.31.0" )] |
271 | impl<T> From<NonZero<T>> for T |
272 | where |
273 | T: ZeroablePrimitive, |
274 | { |
275 | #[inline ] |
276 | fn from(nonzero: NonZero<T>) -> Self { |
277 | // Call `get` method to keep range information. |
278 | nonzero.get() |
279 | } |
280 | } |
281 | |
282 | #[stable (feature = "nonzero_bitor" , since = "1.45.0" )] |
283 | impl<T> BitOr for NonZero<T> |
284 | where |
285 | T: ZeroablePrimitive + BitOr<Output = T>, |
286 | { |
287 | type Output = Self; |
288 | |
289 | #[inline ] |
290 | fn bitor(self, rhs: Self) -> Self::Output { |
291 | // SAFETY: Bitwise OR of two non-zero values is still non-zero. |
292 | unsafe { Self::new_unchecked(self.get() | rhs.get()) } |
293 | } |
294 | } |
295 | |
296 | #[stable (feature = "nonzero_bitor" , since = "1.45.0" )] |
297 | impl<T> BitOr<T> for NonZero<T> |
298 | where |
299 | T: ZeroablePrimitive + BitOr<Output = T>, |
300 | { |
301 | type Output = Self; |
302 | |
303 | #[inline ] |
304 | fn bitor(self, rhs: T) -> Self::Output { |
305 | // SAFETY: Bitwise OR of a non-zero value with anything is still non-zero. |
306 | unsafe { Self::new_unchecked(self.get() | rhs) } |
307 | } |
308 | } |
309 | |
310 | #[stable (feature = "nonzero_bitor" , since = "1.45.0" )] |
311 | impl<T> BitOr<NonZero<T>> for T |
312 | where |
313 | T: ZeroablePrimitive + BitOr<Output = T>, |
314 | { |
315 | type Output = NonZero<T>; |
316 | |
317 | #[inline ] |
318 | fn bitor(self, rhs: NonZero<T>) -> Self::Output { |
319 | // SAFETY: Bitwise OR of anything with a non-zero value is still non-zero. |
320 | unsafe { NonZero::new_unchecked(self | rhs.get()) } |
321 | } |
322 | } |
323 | |
324 | #[stable (feature = "nonzero_bitor" , since = "1.45.0" )] |
325 | impl<T> BitOrAssign for NonZero<T> |
326 | where |
327 | T: ZeroablePrimitive, |
328 | Self: BitOr<Output = Self>, |
329 | { |
330 | #[inline ] |
331 | fn bitor_assign(&mut self, rhs: Self) { |
332 | *self = *self | rhs; |
333 | } |
334 | } |
335 | |
336 | #[stable (feature = "nonzero_bitor" , since = "1.45.0" )] |
337 | impl<T> BitOrAssign<T> for NonZero<T> |
338 | where |
339 | T: ZeroablePrimitive, |
340 | Self: BitOr<T, Output = Self>, |
341 | { |
342 | #[inline ] |
343 | fn bitor_assign(&mut self, rhs: T) { |
344 | *self = *self | rhs; |
345 | } |
346 | } |
347 | |
348 | impl<T> NonZero<T> |
349 | where |
350 | T: ZeroablePrimitive, |
351 | { |
352 | /// Creates a non-zero if the given value is not zero. |
353 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
354 | #[rustc_const_stable (feature = "const_nonzero_int_methods" , since = "1.47.0" )] |
355 | #[must_use ] |
356 | #[inline ] |
357 | pub const fn new(n: T) -> Option<Self> { |
358 | // SAFETY: Memory layout optimization guarantees that `Option<NonZero<T>>` has |
359 | // the same layout and size as `T`, with `0` representing `None`. |
360 | unsafe { intrinsics::transmute_unchecked(n) } |
361 | } |
362 | |
363 | /// Creates a non-zero without checking whether the value is non-zero. |
364 | /// This results in undefined behaviour if the value is zero. |
365 | /// |
366 | /// # Safety |
367 | /// |
368 | /// The value must not be zero. |
369 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
370 | #[rustc_const_stable (feature = "nonzero" , since = "1.28.0" )] |
371 | #[must_use ] |
372 | #[inline ] |
373 | pub const unsafe fn new_unchecked(n: T) -> Self { |
374 | match Self::new(n) { |
375 | Some(n) => n, |
376 | None => { |
377 | // SAFETY: The caller guarantees that `n` is non-zero, so this is unreachable. |
378 | unsafe { |
379 | ub_checks::assert_unsafe_precondition!( |
380 | check_language_ub, |
381 | "NonZero::new_unchecked requires the argument to be non-zero" , |
382 | () => false, |
383 | ); |
384 | intrinsics::unreachable() |
385 | } |
386 | } |
387 | } |
388 | } |
389 | |
390 | /// Converts a reference to a non-zero mutable reference |
391 | /// if the referenced value is not zero. |
392 | #[unstable (feature = "nonzero_from_mut" , issue = "106290" )] |
393 | #[must_use ] |
394 | #[inline ] |
395 | pub fn from_mut(n: &mut T) -> Option<&mut Self> { |
396 | // SAFETY: Memory layout optimization guarantees that `Option<NonZero<T>>` has |
397 | // the same layout and size as `T`, with `0` representing `None`. |
398 | let opt_n = unsafe { &mut *(ptr::from_mut(n).cast::<Option<Self>>()) }; |
399 | |
400 | opt_n.as_mut() |
401 | } |
402 | |
403 | /// Converts a mutable reference to a non-zero mutable reference |
404 | /// without checking whether the referenced value is non-zero. |
405 | /// This results in undefined behavior if the referenced value is zero. |
406 | /// |
407 | /// # Safety |
408 | /// |
409 | /// The referenced value must not be zero. |
410 | #[unstable (feature = "nonzero_from_mut" , issue = "106290" )] |
411 | #[must_use ] |
412 | #[inline ] |
413 | pub unsafe fn from_mut_unchecked(n: &mut T) -> &mut Self { |
414 | match Self::from_mut(n) { |
415 | Some(n) => n, |
416 | None => { |
417 | // SAFETY: The caller guarantees that `n` references a value that is non-zero, so this is unreachable. |
418 | unsafe { |
419 | ub_checks::assert_unsafe_precondition!( |
420 | check_library_ub, |
421 | "NonZero::from_mut_unchecked requires the argument to dereference as non-zero" , |
422 | () => false, |
423 | ); |
424 | intrinsics::unreachable() |
425 | } |
426 | } |
427 | } |
428 | } |
429 | |
430 | /// Returns the contained value as a primitive type. |
431 | #[stable (feature = "nonzero" , since = "1.28.0" )] |
432 | #[rustc_const_stable (feature = "const_nonzero_get" , since = "1.34.0" )] |
433 | #[inline ] |
434 | pub const fn get(self) -> T { |
435 | // FIXME: This can be changed to simply `self.0` once LLVM supports `!range` metadata |
436 | // for function arguments: https://github.com/llvm/llvm-project/issues/76628 |
437 | // |
438 | // Rustc can set range metadata only if it loads `self` from |
439 | // memory somewhere. If the value of `self` was from by-value argument |
440 | // of some not-inlined function, LLVM don't have range metadata |
441 | // to understand that the value cannot be zero. |
442 | // |
443 | // For now, using the transmute `assume`s the range at runtime. |
444 | // |
445 | // SAFETY: `ZeroablePrimitive` guarantees that the size and bit validity |
446 | // of `.0` is such that this transmute is sound. |
447 | unsafe { intrinsics::transmute_unchecked(self) } |
448 | } |
449 | } |
450 | |
451 | macro_rules! nonzero_integer { |
452 | ( |
453 | #[$stability:meta] |
454 | Self = $Ty:ident, |
455 | Primitive = $signedness:ident $Int:ident, |
456 | $(UnsignedNonZero = $UnsignedNonZero:ident,)? |
457 | UnsignedPrimitive = $UnsignedPrimitive:ty, |
458 | |
459 | // Used in doc comments. |
460 | leading_zeros_test = $leading_zeros_test:expr, |
461 | ) => { |
462 | /// An integer that is known not to equal zero. |
463 | /// |
464 | /// This enables some memory layout optimization. |
465 | #[doc = concat!("For example, `Option<" , stringify!($Ty), ">` is the same size as `" , stringify!($Int), "`:" )] |
466 | /// |
467 | /// ```rust |
468 | /// use std::mem::size_of; |
469 | #[doc = concat!("assert_eq!(size_of::<Option<core::num::" , stringify!($Ty), ">>(), size_of::<" , stringify!($Int), ">());" )] |
470 | /// ``` |
471 | /// |
472 | /// # Layout |
473 | /// |
474 | #[doc = concat!("`" , stringify!($Ty), "` is guaranteed to have the same layout and bit validity as `" , stringify!($Int), "`" )] |
475 | /// with the exception that `0` is not a valid instance. |
476 | #[doc = concat!("`Option<" , stringify!($Ty), ">` is guaranteed to be compatible with `" , stringify!($Int), "`," )] |
477 | /// including in FFI. |
478 | /// |
479 | /// Thanks to the [null pointer optimization], |
480 | #[doc = concat!("`" , stringify!($Ty), "` and `Option<" , stringify!($Ty), ">`" )] |
481 | /// are guaranteed to have the same size and alignment: |
482 | /// |
483 | /// ``` |
484 | /// # use std::mem::{size_of, align_of}; |
485 | #[doc = concat!("use std::num::" , stringify!($Ty), ";" )] |
486 | /// |
487 | #[doc = concat!("assert_eq!(size_of::<" , stringify!($Ty), ">(), size_of::<Option<" , stringify!($Ty), ">>());" )] |
488 | #[doc = concat!("assert_eq!(align_of::<" , stringify!($Ty), ">(), align_of::<Option<" , stringify!($Ty), ">>());" )] |
489 | /// ``` |
490 | /// |
491 | /// [null pointer optimization]: crate::option#representation |
492 | #[$stability] |
493 | pub type $Ty = NonZero<$Int>; |
494 | |
495 | impl $Ty { |
496 | /// The size of this non-zero integer type in bits. |
497 | /// |
498 | #[doc = concat!("This value is equal to [`" , stringify!($Int), "::BITS`]." )] |
499 | /// |
500 | /// # Examples |
501 | /// |
502 | /// ``` |
503 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
504 | /// |
505 | #[doc = concat!("assert_eq!(" , stringify!($Ty), "::BITS, " , stringify!($Int), "::BITS);" )] |
506 | /// ``` |
507 | #[stable(feature = "nonzero_bits" , since = "1.67.0" )] |
508 | pub const BITS: u32 = <$Int>::BITS; |
509 | |
510 | /// Returns the number of leading zeros in the binary representation of `self`. |
511 | /// |
512 | /// On many architectures, this function can perform better than `leading_zeros()` on the underlying integer type, as special handling of zero can be avoided. |
513 | /// |
514 | /// # Examples |
515 | /// |
516 | /// Basic usage: |
517 | /// |
518 | /// ``` |
519 | #[doc = concat!("let n = std::num::" , stringify!($Ty), "::new(" , $leading_zeros_test, ").unwrap();" )] |
520 | /// |
521 | /// assert_eq!(n.leading_zeros(), 0); |
522 | /// ``` |
523 | #[stable(feature = "nonzero_leading_trailing_zeros" , since = "1.53.0" )] |
524 | #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros" , since = "1.53.0" )] |
525 | #[must_use = "this returns the result of the operation, \ |
526 | without modifying the original" ] |
527 | #[inline] |
528 | pub const fn leading_zeros(self) -> u32 { |
529 | // SAFETY: since `self` cannot be zero, it is safe to call `ctlz_nonzero`. |
530 | unsafe { |
531 | #[cfg(not(bootstrap))] |
532 | return intrinsics::ctlz_nonzero(self.get() as $UnsignedPrimitive); |
533 | #[cfg(bootstrap)] |
534 | return intrinsics::ctlz_nonzero(self.get() as $UnsignedPrimitive) as u32; |
535 | } |
536 | } |
537 | |
538 | /// Returns the number of trailing zeros in the binary representation |
539 | /// of `self`. |
540 | /// |
541 | /// On many architectures, this function can perform better than `trailing_zeros()` on the underlying integer type, as special handling of zero can be avoided. |
542 | /// |
543 | /// # Examples |
544 | /// |
545 | /// Basic usage: |
546 | /// |
547 | /// ``` |
548 | #[doc = concat!("let n = std::num::" , stringify!($Ty), "::new(0b0101000).unwrap();" )] |
549 | /// |
550 | /// assert_eq!(n.trailing_zeros(), 3); |
551 | /// ``` |
552 | #[stable(feature = "nonzero_leading_trailing_zeros" , since = "1.53.0" )] |
553 | #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros" , since = "1.53.0" )] |
554 | #[must_use = "this returns the result of the operation, \ |
555 | without modifying the original" ] |
556 | #[inline] |
557 | pub const fn trailing_zeros(self) -> u32 { |
558 | // SAFETY: since `self` cannot be zero, it is safe to call `cttz_nonzero`. |
559 | unsafe { |
560 | #[cfg(not(bootstrap))] |
561 | return intrinsics::cttz_nonzero(self.get() as $UnsignedPrimitive); |
562 | #[cfg(bootstrap)] |
563 | return intrinsics::cttz_nonzero(self.get() as $UnsignedPrimitive) as u32; |
564 | } |
565 | } |
566 | |
567 | /// Returns the number of ones in the binary representation of `self`. |
568 | /// |
569 | /// # Examples |
570 | /// |
571 | /// Basic usage: |
572 | /// |
573 | /// ``` |
574 | /// #![feature(non_zero_count_ones)] |
575 | /// |
576 | /// # fn main() { test().unwrap(); } |
577 | /// # fn test() -> Option<()> { |
578 | /// # use std::num::*; |
579 | /// # |
580 | #[doc = concat!("let a = NonZero::<" , stringify!($Int), ">::new(0b100_0000)?;" )] |
581 | #[doc = concat!("let b = NonZero::<" , stringify!($Int), ">::new(0b100_0011)?;" )] |
582 | /// |
583 | /// assert_eq!(a.count_ones(), NonZero::new(1)?); |
584 | /// assert_eq!(b.count_ones(), NonZero::new(3)?); |
585 | /// # Some(()) |
586 | /// # } |
587 | /// ``` |
588 | /// |
589 | #[unstable(feature = "non_zero_count_ones" , issue = "120287" )] |
590 | #[rustc_const_unstable(feature = "non_zero_count_ones" , issue = "120287" )] |
591 | #[doc(alias = "popcount" )] |
592 | #[doc(alias = "popcnt" )] |
593 | #[must_use = "this returns the result of the operation, \ |
594 | without modifying the original" ] |
595 | #[inline(always)] |
596 | pub const fn count_ones(self) -> NonZero<u32> { |
597 | // SAFETY: |
598 | // `self` is non-zero, which means it has at least one bit set, which means |
599 | // that the result of `count_ones` is non-zero. |
600 | unsafe { NonZero::new_unchecked(self.get().count_ones()) } |
601 | } |
602 | |
603 | nonzero_integer_signedness_dependent_methods! { |
604 | Self = $Ty, |
605 | Primitive = $signedness $Int, |
606 | $(UnsignedNonZero = $UnsignedNonZero,)? |
607 | UnsignedPrimitive = $UnsignedPrimitive, |
608 | } |
609 | |
610 | /// Multiplies two non-zero integers together. |
611 | /// Checks for overflow and returns [`None`] on overflow. |
612 | /// As a consequence, the result cannot wrap to zero. |
613 | /// |
614 | /// # Examples |
615 | /// |
616 | /// ``` |
617 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
618 | /// # fn main() { test().unwrap(); } |
619 | /// # fn test() -> Option<()> { |
620 | #[doc = concat!("let two = " , stringify!($Ty), "::new(2)?;" )] |
621 | #[doc = concat!("let four = " , stringify!($Ty), "::new(4)?;" )] |
622 | #[doc = concat!("let max = " , stringify!($Ty), "::new(" , |
623 | stringify!($Int), "::MAX)?;" )] |
624 | /// |
625 | /// assert_eq!(Some(four), two.checked_mul(two)); |
626 | /// assert_eq!(None, max.checked_mul(two)); |
627 | /// # Some(()) |
628 | /// # } |
629 | /// ``` |
630 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
631 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
632 | #[must_use = "this returns the result of the operation, \ |
633 | without modifying the original" ] |
634 | #[inline] |
635 | pub const fn checked_mul(self, other: Self) -> Option<Self> { |
636 | if let Some(result) = self.get().checked_mul(other.get()) { |
637 | // SAFETY: |
638 | // - `checked_mul` returns `None` on overflow |
639 | // - `self` and `other` are non-zero |
640 | // - the only way to get zero from a multiplication without overflow is for one |
641 | // of the sides to be zero |
642 | // |
643 | // So the result cannot be zero. |
644 | Some(unsafe { Self::new_unchecked(result) }) |
645 | } else { |
646 | None |
647 | } |
648 | } |
649 | |
650 | /// Multiplies two non-zero integers together. |
651 | #[doc = concat!("Return [`" , stringify!($Ty), "::MAX`] on overflow." )] |
652 | /// |
653 | /// # Examples |
654 | /// |
655 | /// ``` |
656 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
657 | /// # fn main() { test().unwrap(); } |
658 | /// # fn test() -> Option<()> { |
659 | #[doc = concat!("let two = " , stringify!($Ty), "::new(2)?;" )] |
660 | #[doc = concat!("let four = " , stringify!($Ty), "::new(4)?;" )] |
661 | #[doc = concat!("let max = " , stringify!($Ty), "::new(" , |
662 | stringify!($Int), "::MAX)?;" )] |
663 | /// |
664 | /// assert_eq!(four, two.saturating_mul(two)); |
665 | /// assert_eq!(max, four.saturating_mul(max)); |
666 | /// # Some(()) |
667 | /// # } |
668 | /// ``` |
669 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
670 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
671 | #[must_use = "this returns the result of the operation, \ |
672 | without modifying the original" ] |
673 | #[inline] |
674 | pub const fn saturating_mul(self, other: Self) -> Self { |
675 | // SAFETY: |
676 | // - `saturating_mul` returns `u*::MAX`/`i*::MAX`/`i*::MIN` on overflow/underflow, |
677 | // all of which are non-zero |
678 | // - `self` and `other` are non-zero |
679 | // - the only way to get zero from a multiplication without overflow is for one |
680 | // of the sides to be zero |
681 | // |
682 | // So the result cannot be zero. |
683 | unsafe { Self::new_unchecked(self.get().saturating_mul(other.get())) } |
684 | } |
685 | |
686 | /// Multiplies two non-zero integers together, |
687 | /// assuming overflow cannot occur. |
688 | /// Overflow is unchecked, and it is undefined behaviour to overflow |
689 | /// *even if the result would wrap to a non-zero value*. |
690 | /// The behaviour is undefined as soon as |
691 | #[doc = sign_dependent_expr!{ |
692 | $signedness ? |
693 | if signed { |
694 | concat!("`self * rhs > " , stringify!($Int), "::MAX`, " , |
695 | "or `self * rhs < " , stringify!($Int), "::MIN`." ) |
696 | } |
697 | if unsigned { |
698 | concat!("`self * rhs > " , stringify!($Int), "::MAX`." ) |
699 | } |
700 | }] |
701 | /// |
702 | /// # Examples |
703 | /// |
704 | /// ``` |
705 | /// #![feature(nonzero_ops)] |
706 | /// |
707 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
708 | /// # fn main() { test().unwrap(); } |
709 | /// # fn test() -> Option<()> { |
710 | #[doc = concat!("let two = " , stringify!($Ty), "::new(2)?;" )] |
711 | #[doc = concat!("let four = " , stringify!($Ty), "::new(4)?;" )] |
712 | /// |
713 | /// assert_eq!(four, unsafe { two.unchecked_mul(two) }); |
714 | /// # Some(()) |
715 | /// # } |
716 | /// ``` |
717 | #[unstable(feature = "nonzero_ops" , issue = "84186" )] |
718 | #[must_use = "this returns the result of the operation, \ |
719 | without modifying the original" ] |
720 | #[inline] |
721 | pub const unsafe fn unchecked_mul(self, other: Self) -> Self { |
722 | // SAFETY: The caller ensures there is no overflow. |
723 | unsafe { Self::new_unchecked(self.get().unchecked_mul(other.get())) } |
724 | } |
725 | |
726 | /// Raises non-zero value to an integer power. |
727 | /// Checks for overflow and returns [`None`] on overflow. |
728 | /// As a consequence, the result cannot wrap to zero. |
729 | /// |
730 | /// # Examples |
731 | /// |
732 | /// ``` |
733 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
734 | /// # fn main() { test().unwrap(); } |
735 | /// # fn test() -> Option<()> { |
736 | #[doc = concat!("let three = " , stringify!($Ty), "::new(3)?;" )] |
737 | #[doc = concat!("let twenty_seven = " , stringify!($Ty), "::new(27)?;" )] |
738 | #[doc = concat!("let half_max = " , stringify!($Ty), "::new(" , |
739 | stringify!($Int), "::MAX / 2)?;" )] |
740 | /// |
741 | /// assert_eq!(Some(twenty_seven), three.checked_pow(3)); |
742 | /// assert_eq!(None, half_max.checked_pow(3)); |
743 | /// # Some(()) |
744 | /// # } |
745 | /// ``` |
746 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
747 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
748 | #[must_use = "this returns the result of the operation, \ |
749 | without modifying the original" ] |
750 | #[inline] |
751 | pub const fn checked_pow(self, other: u32) -> Option<Self> { |
752 | if let Some(result) = self.get().checked_pow(other) { |
753 | // SAFETY: |
754 | // - `checked_pow` returns `None` on overflow/underflow |
755 | // - `self` is non-zero |
756 | // - the only way to get zero from an exponentiation without overflow is |
757 | // for base to be zero |
758 | // |
759 | // So the result cannot be zero. |
760 | Some(unsafe { Self::new_unchecked(result) }) |
761 | } else { |
762 | None |
763 | } |
764 | } |
765 | |
766 | /// Raise non-zero value to an integer power. |
767 | #[doc = sign_dependent_expr!{ |
768 | $signedness ? |
769 | if signed { |
770 | concat!("Return [`" , stringify!($Ty), "::MIN`] " , |
771 | "or [`" , stringify!($Ty), "::MAX`] on overflow." ) |
772 | } |
773 | if unsigned { |
774 | concat!("Return [`" , stringify!($Ty), "::MAX`] on overflow." ) |
775 | } |
776 | }] |
777 | /// |
778 | /// # Examples |
779 | /// |
780 | /// ``` |
781 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
782 | /// # fn main() { test().unwrap(); } |
783 | /// # fn test() -> Option<()> { |
784 | #[doc = concat!("let three = " , stringify!($Ty), "::new(3)?;" )] |
785 | #[doc = concat!("let twenty_seven = " , stringify!($Ty), "::new(27)?;" )] |
786 | #[doc = concat!("let max = " , stringify!($Ty), "::new(" , |
787 | stringify!($Int), "::MAX)?;" )] |
788 | /// |
789 | /// assert_eq!(twenty_seven, three.saturating_pow(3)); |
790 | /// assert_eq!(max, max.saturating_pow(3)); |
791 | /// # Some(()) |
792 | /// # } |
793 | /// ``` |
794 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
795 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
796 | #[must_use = "this returns the result of the operation, \ |
797 | without modifying the original" ] |
798 | #[inline] |
799 | pub const fn saturating_pow(self, other: u32) -> Self { |
800 | // SAFETY: |
801 | // - `saturating_pow` returns `u*::MAX`/`i*::MAX`/`i*::MIN` on overflow/underflow, |
802 | // all of which are non-zero |
803 | // - `self` is non-zero |
804 | // - the only way to get zero from an exponentiation without overflow is |
805 | // for base to be zero |
806 | // |
807 | // So the result cannot be zero. |
808 | unsafe { Self::new_unchecked(self.get().saturating_pow(other)) } |
809 | } |
810 | } |
811 | |
812 | #[stable(feature = "nonzero_parse" , since = "1.35.0" )] |
813 | impl FromStr for $Ty { |
814 | type Err = ParseIntError; |
815 | fn from_str(src: &str) -> Result<Self, Self::Err> { |
816 | Self::new(<$Int>::from_str_radix(src, 10)?) |
817 | .ok_or(ParseIntError { |
818 | kind: IntErrorKind::Zero |
819 | }) |
820 | } |
821 | } |
822 | |
823 | nonzero_integer_signedness_dependent_impls!($Ty $signedness $Int); |
824 | }; |
825 | |
826 | (Self = $Ty:ident, Primitive = unsigned $Int:ident $(,)?) => { |
827 | nonzero_integer! { |
828 | #[stable(feature = "nonzero" , since = "1.28.0" )] |
829 | Self = $Ty, |
830 | Primitive = unsigned $Int, |
831 | UnsignedPrimitive = $Int, |
832 | leading_zeros_test = concat!(stringify!($Int), "::MAX" ), |
833 | } |
834 | }; |
835 | |
836 | (Self = $Ty:ident, Primitive = signed $Int:ident, $($rest:tt)*) => { |
837 | nonzero_integer! { |
838 | #[stable(feature = "signed_nonzero" , since = "1.34.0" )] |
839 | Self = $Ty, |
840 | Primitive = signed $Int, |
841 | $($rest)* |
842 | leading_zeros_test = concat!("-1" , stringify!($Int)), |
843 | } |
844 | }; |
845 | } |
846 | |
847 | macro_rules! nonzero_integer_signedness_dependent_impls { |
848 | // Impls for unsigned nonzero types only. |
849 | ($Ty:ident unsigned $Int:ty) => { |
850 | #[stable(feature = "nonzero_div" , since = "1.51.0" )] |
851 | impl Div<$Ty> for $Int { |
852 | type Output = $Int; |
853 | |
854 | /// This operation rounds towards zero, |
855 | /// truncating any fractional part of the exact result, and cannot panic. |
856 | #[inline] |
857 | fn div(self, other: $Ty) -> $Int { |
858 | // SAFETY: div by zero is checked because `other` is a nonzero, |
859 | // and MIN/-1 is checked because `self` is an unsigned int. |
860 | unsafe { intrinsics::unchecked_div(self, other.get()) } |
861 | } |
862 | } |
863 | |
864 | #[stable(feature = "nonzero_div_assign" , since = "CURRENT_RUSTC_VERSION" )] |
865 | impl DivAssign<$Ty> for $Int { |
866 | /// This operation rounds towards zero, |
867 | /// truncating any fractional part of the exact result, and cannot panic. |
868 | #[inline] |
869 | fn div_assign(&mut self, other: $Ty) { |
870 | *self = *self / other; |
871 | } |
872 | } |
873 | |
874 | #[stable(feature = "nonzero_div" , since = "1.51.0" )] |
875 | impl Rem<$Ty> for $Int { |
876 | type Output = $Int; |
877 | |
878 | /// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic. |
879 | #[inline] |
880 | fn rem(self, other: $Ty) -> $Int { |
881 | // SAFETY: rem by zero is checked because `other` is a nonzero, |
882 | // and MIN/-1 is checked because `self` is an unsigned int. |
883 | unsafe { intrinsics::unchecked_rem(self, other.get()) } |
884 | } |
885 | } |
886 | |
887 | #[stable(feature = "nonzero_div_assign" , since = "CURRENT_RUSTC_VERSION" )] |
888 | impl RemAssign<$Ty> for $Int { |
889 | /// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic. |
890 | #[inline] |
891 | fn rem_assign(&mut self, other: $Ty) { |
892 | *self = *self % other; |
893 | } |
894 | } |
895 | }; |
896 | |
897 | // Impls for signed nonzero types only. |
898 | ($Ty:ident signed $Int:ty) => { |
899 | #[stable(feature = "signed_nonzero_neg" , since = "1.71.0" )] |
900 | impl Neg for $Ty { |
901 | type Output = Self; |
902 | |
903 | #[inline] |
904 | fn neg(self) -> Self { |
905 | // SAFETY: negation of nonzero cannot yield zero values. |
906 | unsafe { Self::new_unchecked(self.get().neg()) } |
907 | } |
908 | } |
909 | |
910 | forward_ref_unop! { impl Neg, neg for $Ty, |
911 | #[stable(feature = "signed_nonzero_neg" , since = "1.71.0" )] } |
912 | }; |
913 | } |
914 | |
915 | #[rustfmt::skip] // https://github.com/rust-lang/rustfmt/issues/5974 |
916 | macro_rules! nonzero_integer_signedness_dependent_methods { |
917 | // Associated items for unsigned nonzero types only. |
918 | ( |
919 | Self = $Ty:ident, |
920 | Primitive = unsigned $Int:ident, |
921 | UnsignedPrimitive = $Uint:ty, |
922 | ) => { |
923 | /// The smallest value that can be represented by this non-zero |
924 | /// integer type, 1. |
925 | /// |
926 | /// # Examples |
927 | /// |
928 | /// ``` |
929 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
930 | #[doc = concat!("assert_eq!(" , stringify!($Ty), "::MIN.get(), 1" , stringify!($Int), ");" )] |
931 | /// ``` |
932 | #[stable(feature = "nonzero_min_max" , since = "1.70.0" )] |
933 | pub const MIN: Self = Self::new(1).unwrap(); |
934 | |
935 | /// The largest value that can be represented by this non-zero |
936 | /// integer type, |
937 | #[doc = concat!("equal to [`" , stringify!($Int), "::MAX`]." )] |
938 | /// |
939 | /// # Examples |
940 | /// |
941 | /// ``` |
942 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
943 | #[doc = concat!("assert_eq!(" , stringify!($Ty), "::MAX.get(), " , stringify!($Int), "::MAX);" )] |
944 | /// ``` |
945 | #[stable(feature = "nonzero_min_max" , since = "1.70.0" )] |
946 | pub const MAX: Self = Self::new(<$Int>::MAX).unwrap(); |
947 | |
948 | /// Adds an unsigned integer to a non-zero value. |
949 | /// Checks for overflow and returns [`None`] on overflow. |
950 | /// As a consequence, the result cannot wrap to zero. |
951 | /// |
952 | /// |
953 | /// # Examples |
954 | /// |
955 | /// ``` |
956 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
957 | /// # fn main() { test().unwrap(); } |
958 | /// # fn test() -> Option<()> { |
959 | #[doc = concat!("let one = " , stringify!($Ty), "::new(1)?;" )] |
960 | #[doc = concat!("let two = " , stringify!($Ty), "::new(2)?;" )] |
961 | #[doc = concat!("let max = " , stringify!($Ty), "::new(" , |
962 | stringify!($Int), "::MAX)?;" )] |
963 | /// |
964 | /// assert_eq!(Some(two), one.checked_add(1)); |
965 | /// assert_eq!(None, max.checked_add(1)); |
966 | /// # Some(()) |
967 | /// # } |
968 | /// ``` |
969 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
970 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
971 | #[must_use = "this returns the result of the operation, \ |
972 | without modifying the original" ] |
973 | #[inline] |
974 | pub const fn checked_add(self, other: $Int) -> Option<Self> { |
975 | if let Some(result) = self.get().checked_add(other) { |
976 | // SAFETY: |
977 | // - `checked_add` returns `None` on overflow |
978 | // - `self` is non-zero |
979 | // - the only way to get zero from an addition without overflow is for both |
980 | // sides to be zero |
981 | // |
982 | // So the result cannot be zero. |
983 | Some(unsafe { Self::new_unchecked(result) }) |
984 | } else { |
985 | None |
986 | } |
987 | } |
988 | |
989 | /// Adds an unsigned integer to a non-zero value. |
990 | #[doc = concat!("Return [`" , stringify!($Ty), "::MAX`] on overflow." )] |
991 | /// |
992 | /// # Examples |
993 | /// |
994 | /// ``` |
995 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
996 | /// # fn main() { test().unwrap(); } |
997 | /// # fn test() -> Option<()> { |
998 | #[doc = concat!("let one = " , stringify!($Ty), "::new(1)?;" )] |
999 | #[doc = concat!("let two = " , stringify!($Ty), "::new(2)?;" )] |
1000 | #[doc = concat!("let max = " , stringify!($Ty), "::new(" , |
1001 | stringify!($Int), "::MAX)?;" )] |
1002 | /// |
1003 | /// assert_eq!(two, one.saturating_add(1)); |
1004 | /// assert_eq!(max, max.saturating_add(1)); |
1005 | /// # Some(()) |
1006 | /// # } |
1007 | /// ``` |
1008 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
1009 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
1010 | #[must_use = "this returns the result of the operation, \ |
1011 | without modifying the original" ] |
1012 | #[inline] |
1013 | pub const fn saturating_add(self, other: $Int) -> Self { |
1014 | // SAFETY: |
1015 | // - `saturating_add` returns `u*::MAX` on overflow, which is non-zero |
1016 | // - `self` is non-zero |
1017 | // - the only way to get zero from an addition without overflow is for both |
1018 | // sides to be zero |
1019 | // |
1020 | // So the result cannot be zero. |
1021 | unsafe { Self::new_unchecked(self.get().saturating_add(other)) } |
1022 | } |
1023 | |
1024 | /// Adds an unsigned integer to a non-zero value, |
1025 | /// assuming overflow cannot occur. |
1026 | /// Overflow is unchecked, and it is undefined behaviour to overflow |
1027 | /// *even if the result would wrap to a non-zero value*. |
1028 | /// The behaviour is undefined as soon as |
1029 | #[doc = concat!("`self + rhs > " , stringify!($Int), "::MAX`." )] |
1030 | /// |
1031 | /// # Examples |
1032 | /// |
1033 | /// ``` |
1034 | /// #![feature(nonzero_ops)] |
1035 | /// |
1036 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
1037 | /// # fn main() { test().unwrap(); } |
1038 | /// # fn test() -> Option<()> { |
1039 | #[doc = concat!("let one = " , stringify!($Ty), "::new(1)?;" )] |
1040 | #[doc = concat!("let two = " , stringify!($Ty), "::new(2)?;" )] |
1041 | /// |
1042 | /// assert_eq!(two, unsafe { one.unchecked_add(1) }); |
1043 | /// # Some(()) |
1044 | /// # } |
1045 | /// ``` |
1046 | #[unstable(feature = "nonzero_ops" , issue = "84186" )] |
1047 | #[must_use = "this returns the result of the operation, \ |
1048 | without modifying the original" ] |
1049 | #[inline] |
1050 | pub const unsafe fn unchecked_add(self, other: $Int) -> Self { |
1051 | // SAFETY: The caller ensures there is no overflow. |
1052 | unsafe { Self::new_unchecked(self.get().unchecked_add(other)) } |
1053 | } |
1054 | |
1055 | /// Returns the smallest power of two greater than or equal to n. |
1056 | /// Checks for overflow and returns [`None`] |
1057 | /// if the next power of two is greater than the type’s maximum value. |
1058 | /// As a consequence, the result cannot wrap to zero. |
1059 | /// |
1060 | /// # Examples |
1061 | /// |
1062 | /// ``` |
1063 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
1064 | /// # fn main() { test().unwrap(); } |
1065 | /// # fn test() -> Option<()> { |
1066 | #[doc = concat!("let two = " , stringify!($Ty), "::new(2)?;" )] |
1067 | #[doc = concat!("let three = " , stringify!($Ty), "::new(3)?;" )] |
1068 | #[doc = concat!("let four = " , stringify!($Ty), "::new(4)?;" )] |
1069 | #[doc = concat!("let max = " , stringify!($Ty), "::new(" , |
1070 | stringify!($Int), "::MAX)?;" )] |
1071 | /// |
1072 | /// assert_eq!(Some(two), two.checked_next_power_of_two() ); |
1073 | /// assert_eq!(Some(four), three.checked_next_power_of_two() ); |
1074 | /// assert_eq!(None, max.checked_next_power_of_two() ); |
1075 | /// # Some(()) |
1076 | /// # } |
1077 | /// ``` |
1078 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
1079 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
1080 | #[must_use = "this returns the result of the operation, \ |
1081 | without modifying the original" ] |
1082 | #[inline] |
1083 | pub const fn checked_next_power_of_two(self) -> Option<Self> { |
1084 | if let Some(nz) = self.get().checked_next_power_of_two() { |
1085 | // SAFETY: The next power of two is positive |
1086 | // and overflow is checked. |
1087 | Some(unsafe { Self::new_unchecked(nz) }) |
1088 | } else { |
1089 | None |
1090 | } |
1091 | } |
1092 | |
1093 | /// Returns the base 2 logarithm of the number, rounded down. |
1094 | /// |
1095 | /// This is the same operation as |
1096 | #[doc = concat!("[`" , stringify!($Int), "::ilog2`]," )] |
1097 | /// except that it has no failure cases to worry about |
1098 | /// since this value can never be zero. |
1099 | /// |
1100 | /// # Examples |
1101 | /// |
1102 | /// ``` |
1103 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
1104 | #[doc = concat!("assert_eq!(" , stringify!($Ty), "::new(7).unwrap().ilog2(), 2);" )] |
1105 | #[doc = concat!("assert_eq!(" , stringify!($Ty), "::new(8).unwrap().ilog2(), 3);" )] |
1106 | #[doc = concat!("assert_eq!(" , stringify!($Ty), "::new(9).unwrap().ilog2(), 3);" )] |
1107 | /// ``` |
1108 | #[stable(feature = "int_log" , since = "1.67.0" )] |
1109 | #[rustc_const_stable(feature = "int_log" , since = "1.67.0" )] |
1110 | #[must_use = "this returns the result of the operation, \ |
1111 | without modifying the original" ] |
1112 | #[inline] |
1113 | pub const fn ilog2(self) -> u32 { |
1114 | Self::BITS - 1 - self.leading_zeros() |
1115 | } |
1116 | |
1117 | /// Returns the base 10 logarithm of the number, rounded down. |
1118 | /// |
1119 | /// This is the same operation as |
1120 | #[doc = concat!("[`" , stringify!($Int), "::ilog10`]," )] |
1121 | /// except that it has no failure cases to worry about |
1122 | /// since this value can never be zero. |
1123 | /// |
1124 | /// # Examples |
1125 | /// |
1126 | /// ``` |
1127 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
1128 | #[doc = concat!("assert_eq!(" , stringify!($Ty), "::new(99).unwrap().ilog10(), 1);" )] |
1129 | #[doc = concat!("assert_eq!(" , stringify!($Ty), "::new(100).unwrap().ilog10(), 2);" )] |
1130 | #[doc = concat!("assert_eq!(" , stringify!($Ty), "::new(101).unwrap().ilog10(), 2);" )] |
1131 | /// ``` |
1132 | #[stable(feature = "int_log" , since = "1.67.0" )] |
1133 | #[rustc_const_stable(feature = "int_log" , since = "1.67.0" )] |
1134 | #[must_use = "this returns the result of the operation, \ |
1135 | without modifying the original" ] |
1136 | #[inline] |
1137 | pub const fn ilog10(self) -> u32 { |
1138 | super::int_log10::$Int(self.get()) |
1139 | } |
1140 | |
1141 | /// Calculates the middle point of `self` and `rhs`. |
1142 | /// |
1143 | /// `midpoint(a, b)` is `(a + b) >> 1` as if it were performed in a |
1144 | /// sufficiently-large signed integral type. This implies that the result is |
1145 | /// always rounded towards negative infinity and that no overflow will ever occur. |
1146 | /// |
1147 | /// # Examples |
1148 | /// |
1149 | /// ``` |
1150 | /// #![feature(num_midpoint)] |
1151 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
1152 | /// |
1153 | /// # fn main() { test().unwrap(); } |
1154 | /// # fn test() -> Option<()> { |
1155 | #[doc = concat!("let one = " , stringify!($Ty), "::new(1)?;" )] |
1156 | #[doc = concat!("let two = " , stringify!($Ty), "::new(2)?;" )] |
1157 | #[doc = concat!("let four = " , stringify!($Ty), "::new(4)?;" )] |
1158 | /// |
1159 | /// assert_eq!(one.midpoint(four), two); |
1160 | /// assert_eq!(four.midpoint(one), two); |
1161 | /// # Some(()) |
1162 | /// # } |
1163 | /// ``` |
1164 | #[unstable(feature = "num_midpoint" , issue = "110840" )] |
1165 | #[rustc_const_unstable(feature = "const_num_midpoint" , issue = "110840" )] |
1166 | #[rustc_allow_const_fn_unstable(const_num_midpoint)] |
1167 | #[must_use = "this returns the result of the operation, \ |
1168 | without modifying the original" ] |
1169 | #[inline] |
1170 | pub const fn midpoint(self, rhs: Self) -> Self { |
1171 | // SAFETY: The only way to get `0` with midpoint is to have two opposite or |
1172 | // near opposite numbers: (-5, 5), (0, 1), (0, 0) which is impossible because |
1173 | // of the unsignedness of this number and also because `Self` is guaranteed to |
1174 | // never being 0. |
1175 | unsafe { Self::new_unchecked(self.get().midpoint(rhs.get())) } |
1176 | } |
1177 | |
1178 | /// Returns `true` if and only if `self == (1 << k)` for some `k`. |
1179 | /// |
1180 | /// On many architectures, this function can perform better than `is_power_of_two()` |
1181 | /// on the underlying integer type, as special handling of zero can be avoided. |
1182 | /// |
1183 | /// # Examples |
1184 | /// |
1185 | /// Basic usage: |
1186 | /// |
1187 | /// ``` |
1188 | #[doc = concat!("let eight = std::num::" , stringify!($Ty), "::new(8).unwrap();" )] |
1189 | /// assert!(eight.is_power_of_two()); |
1190 | #[doc = concat!("let ten = std::num::" , stringify!($Ty), "::new(10).unwrap();" )] |
1191 | /// assert!(!ten.is_power_of_two()); |
1192 | /// ``` |
1193 | #[must_use] |
1194 | #[stable(feature = "nonzero_is_power_of_two" , since = "1.59.0" )] |
1195 | #[rustc_const_stable(feature = "nonzero_is_power_of_two" , since = "1.59.0" )] |
1196 | #[inline] |
1197 | pub const fn is_power_of_two(self) -> bool { |
1198 | // LLVM 11 normalizes `unchecked_sub(x, 1) & x == 0` to the implementation seen here. |
1199 | // On the basic x86-64 target, this saves 3 instructions for the zero check. |
1200 | // On x86_64 with BMI1, being nonzero lets it codegen to `BLSR`, which saves an instruction |
1201 | // compared to the `POPCNT` implementation on the underlying integer type. |
1202 | |
1203 | intrinsics::ctpop(self.get()) < 2 |
1204 | } |
1205 | }; |
1206 | |
1207 | // Associated items for signed nonzero types only. |
1208 | ( |
1209 | Self = $Ty:ident, |
1210 | Primitive = signed $Int:ident, |
1211 | UnsignedNonZero = $Uty:ident, |
1212 | UnsignedPrimitive = $Uint:ty, |
1213 | ) => { |
1214 | /// The smallest value that can be represented by this non-zero |
1215 | /// integer type, |
1216 | #[doc = concat!("equal to [`" , stringify!($Int), "::MIN`]." )] |
1217 | /// |
1218 | /// Note: While most integer types are defined for every whole |
1219 | /// number between `MIN` and `MAX`, signed non-zero integers are |
1220 | /// a special case. They have a "gap" at 0. |
1221 | /// |
1222 | /// # Examples |
1223 | /// |
1224 | /// ``` |
1225 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
1226 | #[doc = concat!("assert_eq!(" , stringify!($Ty), "::MIN.get(), " , stringify!($Int), "::MIN);" )] |
1227 | /// ``` |
1228 | #[stable(feature = "nonzero_min_max" , since = "1.70.0" )] |
1229 | pub const MIN: Self = Self::new(<$Int>::MIN).unwrap(); |
1230 | |
1231 | /// The largest value that can be represented by this non-zero |
1232 | /// integer type, |
1233 | #[doc = concat!("equal to [`" , stringify!($Int), "::MAX`]." )] |
1234 | /// |
1235 | /// Note: While most integer types are defined for every whole |
1236 | /// number between `MIN` and `MAX`, signed non-zero integers are |
1237 | /// a special case. They have a "gap" at 0. |
1238 | /// |
1239 | /// # Examples |
1240 | /// |
1241 | /// ``` |
1242 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
1243 | #[doc = concat!("assert_eq!(" , stringify!($Ty), "::MAX.get(), " , stringify!($Int), "::MAX);" )] |
1244 | /// ``` |
1245 | #[stable(feature = "nonzero_min_max" , since = "1.70.0" )] |
1246 | pub const MAX: Self = Self::new(<$Int>::MAX).unwrap(); |
1247 | |
1248 | /// Computes the absolute value of self. |
1249 | #[doc = concat!("See [`" , stringify!($Int), "::abs`]" )] |
1250 | /// for documentation on overflow behaviour. |
1251 | /// |
1252 | /// # Example |
1253 | /// |
1254 | /// ``` |
1255 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
1256 | /// # fn main() { test().unwrap(); } |
1257 | /// # fn test() -> Option<()> { |
1258 | #[doc = concat!("let pos = " , stringify!($Ty), "::new(1)?;" )] |
1259 | #[doc = concat!("let neg = " , stringify!($Ty), "::new(-1)?;" )] |
1260 | /// |
1261 | /// assert_eq!(pos, pos.abs()); |
1262 | /// assert_eq!(pos, neg.abs()); |
1263 | /// # Some(()) |
1264 | /// # } |
1265 | /// ``` |
1266 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
1267 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
1268 | #[must_use = "this returns the result of the operation, \ |
1269 | without modifying the original" ] |
1270 | #[inline] |
1271 | pub const fn abs(self) -> Self { |
1272 | // SAFETY: This cannot overflow to zero. |
1273 | unsafe { Self::new_unchecked(self.get().abs()) } |
1274 | } |
1275 | |
1276 | /// Checked absolute value. |
1277 | /// Checks for overflow and returns [`None`] if |
1278 | #[doc = concat!("`self == " , stringify!($Ty), "::MIN`." )] |
1279 | /// The result cannot be zero. |
1280 | /// |
1281 | /// # Example |
1282 | /// |
1283 | /// ``` |
1284 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
1285 | /// # fn main() { test().unwrap(); } |
1286 | /// # fn test() -> Option<()> { |
1287 | #[doc = concat!("let pos = " , stringify!($Ty), "::new(1)?;" )] |
1288 | #[doc = concat!("let neg = " , stringify!($Ty), "::new(-1)?;" )] |
1289 | #[doc = concat!("let min = " , stringify!($Ty), "::new(" , |
1290 | stringify!($Int), "::MIN)?;" )] |
1291 | /// |
1292 | /// assert_eq!(Some(pos), neg.checked_abs()); |
1293 | /// assert_eq!(None, min.checked_abs()); |
1294 | /// # Some(()) |
1295 | /// # } |
1296 | /// ``` |
1297 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
1298 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
1299 | #[must_use = "this returns the result of the operation, \ |
1300 | without modifying the original" ] |
1301 | #[inline] |
1302 | pub const fn checked_abs(self) -> Option<Self> { |
1303 | if let Some(nz) = self.get().checked_abs() { |
1304 | // SAFETY: absolute value of nonzero cannot yield zero values. |
1305 | Some(unsafe { Self::new_unchecked(nz) }) |
1306 | } else { |
1307 | None |
1308 | } |
1309 | } |
1310 | |
1311 | /// Computes the absolute value of self, |
1312 | /// with overflow information, see |
1313 | #[doc = concat!("[`" , stringify!($Int), "::overflowing_abs`]." )] |
1314 | /// |
1315 | /// # Example |
1316 | /// |
1317 | /// ``` |
1318 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
1319 | /// # fn main() { test().unwrap(); } |
1320 | /// # fn test() -> Option<()> { |
1321 | #[doc = concat!("let pos = " , stringify!($Ty), "::new(1)?;" )] |
1322 | #[doc = concat!("let neg = " , stringify!($Ty), "::new(-1)?;" )] |
1323 | #[doc = concat!("let min = " , stringify!($Ty), "::new(" , |
1324 | stringify!($Int), "::MIN)?;" )] |
1325 | /// |
1326 | /// assert_eq!((pos, false), pos.overflowing_abs()); |
1327 | /// assert_eq!((pos, false), neg.overflowing_abs()); |
1328 | /// assert_eq!((min, true), min.overflowing_abs()); |
1329 | /// # Some(()) |
1330 | /// # } |
1331 | /// ``` |
1332 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
1333 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
1334 | #[must_use = "this returns the result of the operation, \ |
1335 | without modifying the original" ] |
1336 | #[inline] |
1337 | pub const fn overflowing_abs(self) -> (Self, bool) { |
1338 | let (nz, flag) = self.get().overflowing_abs(); |
1339 | ( |
1340 | // SAFETY: absolute value of nonzero cannot yield zero values. |
1341 | unsafe { Self::new_unchecked(nz) }, |
1342 | flag, |
1343 | ) |
1344 | } |
1345 | |
1346 | /// Saturating absolute value, see |
1347 | #[doc = concat!("[`" , stringify!($Int), "::saturating_abs`]." )] |
1348 | /// |
1349 | /// # Example |
1350 | /// |
1351 | /// ``` |
1352 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
1353 | /// # fn main() { test().unwrap(); } |
1354 | /// # fn test() -> Option<()> { |
1355 | #[doc = concat!("let pos = " , stringify!($Ty), "::new(1)?;" )] |
1356 | #[doc = concat!("let neg = " , stringify!($Ty), "::new(-1)?;" )] |
1357 | #[doc = concat!("let min = " , stringify!($Ty), "::new(" , |
1358 | stringify!($Int), "::MIN)?;" )] |
1359 | #[doc = concat!("let min_plus = " , stringify!($Ty), "::new(" , |
1360 | stringify!($Int), "::MIN + 1)?;" )] |
1361 | #[doc = concat!("let max = " , stringify!($Ty), "::new(" , |
1362 | stringify!($Int), "::MAX)?;" )] |
1363 | /// |
1364 | /// assert_eq!(pos, pos.saturating_abs()); |
1365 | /// assert_eq!(pos, neg.saturating_abs()); |
1366 | /// assert_eq!(max, min.saturating_abs()); |
1367 | /// assert_eq!(max, min_plus.saturating_abs()); |
1368 | /// # Some(()) |
1369 | /// # } |
1370 | /// ``` |
1371 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
1372 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
1373 | #[must_use = "this returns the result of the operation, \ |
1374 | without modifying the original" ] |
1375 | #[inline] |
1376 | pub const fn saturating_abs(self) -> Self { |
1377 | // SAFETY: absolute value of nonzero cannot yield zero values. |
1378 | unsafe { Self::new_unchecked(self.get().saturating_abs()) } |
1379 | } |
1380 | |
1381 | /// Wrapping absolute value, see |
1382 | #[doc = concat!("[`" , stringify!($Int), "::wrapping_abs`]." )] |
1383 | /// |
1384 | /// # Example |
1385 | /// |
1386 | /// ``` |
1387 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
1388 | /// # fn main() { test().unwrap(); } |
1389 | /// # fn test() -> Option<()> { |
1390 | #[doc = concat!("let pos = " , stringify!($Ty), "::new(1)?;" )] |
1391 | #[doc = concat!("let neg = " , stringify!($Ty), "::new(-1)?;" )] |
1392 | #[doc = concat!("let min = " , stringify!($Ty), "::new(" , |
1393 | stringify!($Int), "::MIN)?;" )] |
1394 | #[doc = concat!("# let max = " , stringify!($Ty), "::new(" , |
1395 | stringify!($Int), "::MAX)?;" )] |
1396 | /// |
1397 | /// assert_eq!(pos, pos.wrapping_abs()); |
1398 | /// assert_eq!(pos, neg.wrapping_abs()); |
1399 | /// assert_eq!(min, min.wrapping_abs()); |
1400 | /// assert_eq!(max, (-max).wrapping_abs()); |
1401 | /// # Some(()) |
1402 | /// # } |
1403 | /// ``` |
1404 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
1405 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
1406 | #[must_use = "this returns the result of the operation, \ |
1407 | without modifying the original" ] |
1408 | #[inline] |
1409 | pub const fn wrapping_abs(self) -> Self { |
1410 | // SAFETY: absolute value of nonzero cannot yield zero values. |
1411 | unsafe { Self::new_unchecked(self.get().wrapping_abs()) } |
1412 | } |
1413 | |
1414 | /// Computes the absolute value of self |
1415 | /// without any wrapping or panicking. |
1416 | /// |
1417 | /// # Example |
1418 | /// |
1419 | /// ``` |
1420 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
1421 | #[doc = concat!("# use std::num::" , stringify!($Uty), ";" )] |
1422 | /// |
1423 | /// # fn main() { test().unwrap(); } |
1424 | /// # fn test() -> Option<()> { |
1425 | #[doc = concat!("let u_pos = " , stringify!($Uty), "::new(1)?;" )] |
1426 | #[doc = concat!("let i_pos = " , stringify!($Ty), "::new(1)?;" )] |
1427 | #[doc = concat!("let i_neg = " , stringify!($Ty), "::new(-1)?;" )] |
1428 | #[doc = concat!("let i_min = " , stringify!($Ty), "::new(" , |
1429 | stringify!($Int), "::MIN)?;" )] |
1430 | #[doc = concat!("let u_max = " , stringify!($Uty), "::new(" , |
1431 | stringify!($Uint), "::MAX / 2 + 1)?;" )] |
1432 | /// |
1433 | /// assert_eq!(u_pos, i_pos.unsigned_abs()); |
1434 | /// assert_eq!(u_pos, i_neg.unsigned_abs()); |
1435 | /// assert_eq!(u_max, i_min.unsigned_abs()); |
1436 | /// # Some(()) |
1437 | /// # } |
1438 | /// ``` |
1439 | #[stable(feature = "nonzero_checked_ops" , since = "1.64.0" )] |
1440 | #[rustc_const_stable(feature = "const_nonzero_checked_ops" , since = "1.64.0" )] |
1441 | #[must_use = "this returns the result of the operation, \ |
1442 | without modifying the original" ] |
1443 | #[inline] |
1444 | pub const fn unsigned_abs(self) -> $Uty { |
1445 | // SAFETY: absolute value of nonzero cannot yield zero values. |
1446 | unsafe { $Uty::new_unchecked(self.get().unsigned_abs()) } |
1447 | } |
1448 | |
1449 | /// Returns `true` if `self` is positive and `false` if the |
1450 | /// number is negative. |
1451 | /// |
1452 | /// # Example |
1453 | /// |
1454 | /// ``` |
1455 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
1456 | /// # fn main() { test().unwrap(); } |
1457 | /// # fn test() -> Option<()> { |
1458 | #[doc = concat!("let pos_five = " , stringify!($Ty), "::new(5)?;" )] |
1459 | #[doc = concat!("let neg_five = " , stringify!($Ty), "::new(-5)?;" )] |
1460 | /// |
1461 | /// assert!(pos_five.is_positive()); |
1462 | /// assert!(!neg_five.is_positive()); |
1463 | /// # Some(()) |
1464 | /// # } |
1465 | /// ``` |
1466 | #[must_use] |
1467 | #[inline] |
1468 | #[stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
1469 | #[rustc_const_stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
1470 | pub const fn is_positive(self) -> bool { |
1471 | self.get().is_positive() |
1472 | } |
1473 | |
1474 | /// Returns `true` if `self` is negative and `false` if the |
1475 | /// number is positive. |
1476 | /// |
1477 | /// # Example |
1478 | /// |
1479 | /// ``` |
1480 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
1481 | /// # fn main() { test().unwrap(); } |
1482 | /// # fn test() -> Option<()> { |
1483 | #[doc = concat!("let pos_five = " , stringify!($Ty), "::new(5)?;" )] |
1484 | #[doc = concat!("let neg_five = " , stringify!($Ty), "::new(-5)?;" )] |
1485 | /// |
1486 | /// assert!(neg_five.is_negative()); |
1487 | /// assert!(!pos_five.is_negative()); |
1488 | /// # Some(()) |
1489 | /// # } |
1490 | /// ``` |
1491 | #[must_use] |
1492 | #[inline] |
1493 | #[stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
1494 | #[rustc_const_stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
1495 | pub const fn is_negative(self) -> bool { |
1496 | self.get().is_negative() |
1497 | } |
1498 | |
1499 | /// Checked negation. Computes `-self`, |
1500 | #[doc = concat!("returning `None` if `self == " , stringify!($Ty), "::MIN`." )] |
1501 | /// |
1502 | /// # Example |
1503 | /// |
1504 | /// ``` |
1505 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
1506 | /// # fn main() { test().unwrap(); } |
1507 | /// # fn test() -> Option<()> { |
1508 | #[doc = concat!("let pos_five = " , stringify!($Ty), "::new(5)?;" )] |
1509 | #[doc = concat!("let neg_five = " , stringify!($Ty), "::new(-5)?;" )] |
1510 | #[doc = concat!("let min = " , stringify!($Ty), "::new(" , |
1511 | stringify!($Int), "::MIN)?;" )] |
1512 | /// |
1513 | /// assert_eq!(pos_five.checked_neg(), Some(neg_five)); |
1514 | /// assert_eq!(min.checked_neg(), None); |
1515 | /// # Some(()) |
1516 | /// # } |
1517 | /// ``` |
1518 | #[inline] |
1519 | #[stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
1520 | #[rustc_const_stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
1521 | pub const fn checked_neg(self) -> Option<Self> { |
1522 | if let Some(result) = self.get().checked_neg() { |
1523 | // SAFETY: negation of nonzero cannot yield zero values. |
1524 | return Some(unsafe { Self::new_unchecked(result) }); |
1525 | } |
1526 | None |
1527 | } |
1528 | |
1529 | /// Negates self, overflowing if this is equal to the minimum value. |
1530 | /// |
1531 | #[doc = concat!("See [`" , stringify!($Int), "::overflowing_neg`]" )] |
1532 | /// for documentation on overflow behaviour. |
1533 | /// |
1534 | /// # Example |
1535 | /// |
1536 | /// ``` |
1537 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
1538 | /// # fn main() { test().unwrap(); } |
1539 | /// # fn test() -> Option<()> { |
1540 | #[doc = concat!("let pos_five = " , stringify!($Ty), "::new(5)?;" )] |
1541 | #[doc = concat!("let neg_five = " , stringify!($Ty), "::new(-5)?;" )] |
1542 | #[doc = concat!("let min = " , stringify!($Ty), "::new(" , |
1543 | stringify!($Int), "::MIN)?;" )] |
1544 | /// |
1545 | /// assert_eq!(pos_five.overflowing_neg(), (neg_five, false)); |
1546 | /// assert_eq!(min.overflowing_neg(), (min, true)); |
1547 | /// # Some(()) |
1548 | /// # } |
1549 | /// ``` |
1550 | #[inline] |
1551 | #[stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
1552 | #[rustc_const_stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
1553 | pub const fn overflowing_neg(self) -> (Self, bool) { |
1554 | let (result, overflow) = self.get().overflowing_neg(); |
1555 | // SAFETY: negation of nonzero cannot yield zero values. |
1556 | ((unsafe { Self::new_unchecked(result) }), overflow) |
1557 | } |
1558 | |
1559 | /// Saturating negation. Computes `-self`, |
1560 | #[doc = concat!("returning [`" , stringify!($Ty), "::MAX`]" )] |
1561 | #[doc = concat!("if `self == " , stringify!($Ty), "::MIN`" )] |
1562 | /// instead of overflowing. |
1563 | /// |
1564 | /// # Example |
1565 | /// |
1566 | /// ``` |
1567 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
1568 | /// # fn main() { test().unwrap(); } |
1569 | /// # fn test() -> Option<()> { |
1570 | #[doc = concat!("let pos_five = " , stringify!($Ty), "::new(5)?;" )] |
1571 | #[doc = concat!("let neg_five = " , stringify!($Ty), "::new(-5)?;" )] |
1572 | #[doc = concat!("let min = " , stringify!($Ty), "::new(" , |
1573 | stringify!($Int), "::MIN)?;" )] |
1574 | #[doc = concat!("let min_plus_one = " , stringify!($Ty), "::new(" , |
1575 | stringify!($Int), "::MIN + 1)?;" )] |
1576 | #[doc = concat!("let max = " , stringify!($Ty), "::new(" , |
1577 | stringify!($Int), "::MAX)?;" )] |
1578 | /// |
1579 | /// assert_eq!(pos_five.saturating_neg(), neg_five); |
1580 | /// assert_eq!(min.saturating_neg(), max); |
1581 | /// assert_eq!(max.saturating_neg(), min_plus_one); |
1582 | /// # Some(()) |
1583 | /// # } |
1584 | /// ``` |
1585 | #[inline] |
1586 | #[stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
1587 | #[rustc_const_stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
1588 | pub const fn saturating_neg(self) -> Self { |
1589 | if let Some(result) = self.checked_neg() { |
1590 | return result; |
1591 | } |
1592 | Self::MAX |
1593 | } |
1594 | |
1595 | /// Wrapping (modular) negation. Computes `-self`, wrapping around at the boundary |
1596 | /// of the type. |
1597 | /// |
1598 | #[doc = concat!("See [`" , stringify!($Int), "::wrapping_neg`]" )] |
1599 | /// for documentation on overflow behaviour. |
1600 | /// |
1601 | /// # Example |
1602 | /// |
1603 | /// ``` |
1604 | #[doc = concat!("# use std::num::" , stringify!($Ty), ";" )] |
1605 | /// # fn main() { test().unwrap(); } |
1606 | /// # fn test() -> Option<()> { |
1607 | #[doc = concat!("let pos_five = " , stringify!($Ty), "::new(5)?;" )] |
1608 | #[doc = concat!("let neg_five = " , stringify!($Ty), "::new(-5)?;" )] |
1609 | #[doc = concat!("let min = " , stringify!($Ty), "::new(" , |
1610 | stringify!($Int), "::MIN)?;" )] |
1611 | /// |
1612 | /// assert_eq!(pos_five.wrapping_neg(), neg_five); |
1613 | /// assert_eq!(min.wrapping_neg(), min); |
1614 | /// # Some(()) |
1615 | /// # } |
1616 | /// ``` |
1617 | #[inline] |
1618 | #[stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
1619 | #[rustc_const_stable(feature = "nonzero_negation_ops" , since = "1.71.0" )] |
1620 | pub const fn wrapping_neg(self) -> Self { |
1621 | let result = self.get().wrapping_neg(); |
1622 | // SAFETY: negation of nonzero cannot yield zero values. |
1623 | unsafe { Self::new_unchecked(result) } |
1624 | } |
1625 | }; |
1626 | } |
1627 | |
1628 | // Use this when the generated code should differ between signed and unsigned types. |
1629 | macro_rules! sign_dependent_expr { |
1630 | (signed ? if signed { $signed_case:expr } if unsigned { $unsigned_case:expr } ) => { |
1631 | $signed_case |
1632 | }; |
1633 | (unsigned ? if signed { $signed_case:expr } if unsigned { $unsigned_case:expr } ) => { |
1634 | $unsigned_case |
1635 | }; |
1636 | } |
1637 | |
1638 | nonzero_integer! { |
1639 | Self = NonZeroU8, |
1640 | Primitive = unsigned u8, |
1641 | } |
1642 | |
1643 | nonzero_integer! { |
1644 | Self = NonZeroU16, |
1645 | Primitive = unsigned u16, |
1646 | } |
1647 | |
1648 | nonzero_integer! { |
1649 | Self = NonZeroU32, |
1650 | Primitive = unsigned u32, |
1651 | } |
1652 | |
1653 | nonzero_integer! { |
1654 | Self = NonZeroU64, |
1655 | Primitive = unsigned u64, |
1656 | } |
1657 | |
1658 | nonzero_integer! { |
1659 | Self = NonZeroU128, |
1660 | Primitive = unsigned u128, |
1661 | } |
1662 | |
1663 | nonzero_integer! { |
1664 | Self = NonZeroUsize, |
1665 | Primitive = unsigned usize, |
1666 | } |
1667 | |
1668 | nonzero_integer! { |
1669 | Self = NonZeroI8, |
1670 | Primitive = signed i8, |
1671 | UnsignedNonZero = NonZeroU8, |
1672 | UnsignedPrimitive = u8, |
1673 | } |
1674 | |
1675 | nonzero_integer! { |
1676 | Self = NonZeroI16, |
1677 | Primitive = signed i16, |
1678 | UnsignedNonZero = NonZeroU16, |
1679 | UnsignedPrimitive = u16, |
1680 | } |
1681 | |
1682 | nonzero_integer! { |
1683 | Self = NonZeroI32, |
1684 | Primitive = signed i32, |
1685 | UnsignedNonZero = NonZeroU32, |
1686 | UnsignedPrimitive = u32, |
1687 | } |
1688 | |
1689 | nonzero_integer! { |
1690 | Self = NonZeroI64, |
1691 | Primitive = signed i64, |
1692 | UnsignedNonZero = NonZeroU64, |
1693 | UnsignedPrimitive = u64, |
1694 | } |
1695 | |
1696 | nonzero_integer! { |
1697 | Self = NonZeroI128, |
1698 | Primitive = signed i128, |
1699 | UnsignedNonZero = NonZeroU128, |
1700 | UnsignedPrimitive = u128, |
1701 | } |
1702 | |
1703 | nonzero_integer! { |
1704 | Self = NonZeroIsize, |
1705 | Primitive = signed isize, |
1706 | UnsignedNonZero = NonZeroUsize, |
1707 | UnsignedPrimitive = usize, |
1708 | } |
1709 | |