]> git.lizzy.rs Git - rust.git/blob - library/core/src/num/saturating.rs
4f1937c68c7e2b9dfe1474d2b91e468766ab80ba
[rust.git] / library / core / src / num / saturating.rs
1 //! Definitions of `Saturating<T>`.
2
3 use crate::fmt;
4 use crate::ops::{Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign};
5 use crate::ops::{BitXor, BitXorAssign, Div, DivAssign};
6 use crate::ops::{Mul, MulAssign, Neg, Not};
7 use crate::ops::{Sub, SubAssign};
8
9 /// Provides intentionally-wrapped arithmetic on `T`.
10 ///
11 /// Operations like `+` on `u32` values are intended to never overflow,
12 /// and in some debug configurations overflow is detected and results
13 /// in a panic. While most arithmetic falls into this category, some
14 /// code explicitly expects and relies upon modular arithmetic (e.g.,
15 /// hashing).
16 ///
17 /// Saturating arithmetic can be achieved either through methods like
18 /// `saturating_add`, or through the `Saturating<T>` type, which says that
19 /// all standard arithmetic operations on the underlying value are
20 /// intended to have saturating semantics.
21 ///
22 /// The underlying value can be retrieved through the `.0` index of the
23 /// `Saturating` tuple.
24 ///
25 /// # Examples
26 ///
27 /// ```
28 /// #![feature(saturating_int_impl)]
29 /// use std::num::Saturating;
30 ///
31 /// let max = Saturating(u32::MAX);
32 /// let one = Saturating(1u32);
33 ///
34 /// assert_eq!(u32::MAX, (max + one).0);
35 /// ```
36 #[unstable(feature = "saturating_int_impl", issue = "87920")]
37 #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default, Hash)]
38 #[repr(transparent)]
39 pub struct Saturating<T>(#[stable(feature = "rust1", since = "1.0.0")] pub T);
40
41 #[stable(feature = "rust1", since = "1.0.0")]
42 impl<T: fmt::Debug> fmt::Debug for Saturating<T> {
43     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44         self.0.fmt(f)
45     }
46 }
47
48 #[stable(feature = "saturating_display", since = "1.10.0")]
49 impl<T: fmt::Display> fmt::Display for Saturating<T> {
50     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51         self.0.fmt(f)
52     }
53 }
54
55 #[stable(feature = "saturating_fmt", since = "1.11.0")]
56 impl<T: fmt::Binary> fmt::Binary for Saturating<T> {
57     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58         self.0.fmt(f)
59     }
60 }
61
62 #[stable(feature = "saturating_fmt", since = "1.11.0")]
63 impl<T: fmt::Octal> fmt::Octal for Saturating<T> {
64     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65         self.0.fmt(f)
66     }
67 }
68
69 #[stable(feature = "saturating_fmt", since = "1.11.0")]
70 impl<T: fmt::LowerHex> fmt::LowerHex for Saturating<T> {
71     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72         self.0.fmt(f)
73     }
74 }
75
76 #[stable(feature = "saturating_fmt", since = "1.11.0")]
77 impl<T: fmt::UpperHex> fmt::UpperHex for Saturating<T> {
78     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79         self.0.fmt(f)
80     }
81 }
82
83 #[allow(unused_macros)]
84 macro_rules! sh_impl_signed {
85     ($t:ident, $f:ident) => {
86
87     };
88 }
89
90 macro_rules! sh_impl_unsigned {
91     ($t:ident, $f:ident) => {
92
93     };
94 }
95
96 // FIXME (#23545): uncomment the remaining impls
97 macro_rules! sh_impl_all {
98     ($($t:ident)*) => ($(
99         //sh_impl_unsigned! { $t, u8 }
100         //sh_impl_unsigned! { $t, u16 }
101         //sh_impl_unsigned! { $t, u32 }
102         //sh_impl_unsigned! { $t, u64 }
103         //sh_impl_unsigned! { $t, u128 }
104         sh_impl_unsigned! { $t, usize }
105
106         //sh_impl_signed! { $t, i8 }
107         //sh_impl_signed! { $t, i16 }
108         //sh_impl_signed! { $t, i32 }
109         //sh_impl_signed! { $t, i64 }
110         //sh_impl_signed! { $t, i128 }
111         //sh_impl_signed! { $t, isize }
112     )*)
113 }
114
115 sh_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
116
117 // FIXME(30524): impl Op<T> for Saturating<T>, impl OpAssign<T> for Saturating<T>
118 macro_rules! saturating_impl {
119     ($($t:ty)*) => ($(
120         #[stable(feature = "rust1", since = "1.0.0")]
121         impl Add for Saturating<$t> {
122             type Output = Saturating<$t>;
123
124             #[inline]
125             fn add(self, other: Saturating<$t>) -> Saturating<$t> {
126                 Saturating(self.0.saturating_add(other.0))
127             }
128         }
129         forward_ref_binop! { impl Add, add for Saturating<$t>, Saturating<$t>,
130                 #[stable(feature = "saturating_ref", since = "1.14.0")] }
131
132         #[stable(feature = "op_assign_traits", since = "1.8.0")]
133         impl AddAssign for Saturating<$t> {
134             #[inline]
135             fn add_assign(&mut self, other: Saturating<$t>) {
136                 *self = *self + other;
137             }
138         }
139         forward_ref_op_assign! { impl AddAssign, add_assign for Saturating<$t>, Saturating<$t> }
140
141         #[stable(feature = "rust1", since = "1.0.0")]
142         impl Sub for Saturating<$t> {
143             type Output = Saturating<$t>;
144
145             #[inline]
146             fn sub(self, other: Saturating<$t>) -> Saturating<$t> {
147                 Saturating(self.0.saturating_sub(other.0))
148             }
149         }
150         forward_ref_binop! { impl Sub, sub for Saturating<$t>, Saturating<$t>,
151                 #[stable(feature = "saturating_ref", since = "1.14.0")] }
152
153         #[stable(feature = "op_assign_traits", since = "1.8.0")]
154         impl SubAssign for Saturating<$t> {
155             #[inline]
156             fn sub_assign(&mut self, other: Saturating<$t>) {
157                 *self = *self - other;
158             }
159         }
160         forward_ref_op_assign! { impl SubAssign, sub_assign for Saturating<$t>, Saturating<$t> }
161
162         #[stable(feature = "rust1", since = "1.0.0")]
163         impl Mul for Saturating<$t> {
164             type Output = Saturating<$t>;
165
166             #[inline]
167             fn mul(self, other: Saturating<$t>) -> Saturating<$t> {
168                 Saturating(self.0.saturating_mul(other.0))
169             }
170         }
171         forward_ref_binop! { impl Mul, mul for Saturating<$t>, Saturating<$t>,
172                 #[stable(feature = "saturating_ref", since = "1.14.0")] }
173
174         #[stable(feature = "op_assign_traits", since = "1.8.0")]
175         impl MulAssign for Saturating<$t> {
176             #[inline]
177             fn mul_assign(&mut self, other: Saturating<$t>) {
178                 *self = *self * other;
179             }
180         }
181         forward_ref_op_assign! { impl MulAssign, mul_assign for Saturating<$t>, Saturating<$t> }
182
183         #[stable(feature = "saturating_div", since = "1.3.0")]
184         impl Div for Saturating<$t> {
185             type Output = Saturating<$t>;
186
187             #[inline]
188             fn div(self, other: Saturating<$t>) -> Saturating<$t> {
189                 // saturating div is the default behavior?
190                 Saturating(self.0.div(other.0))
191             }
192         }
193         forward_ref_binop! { impl Div, div for Saturating<$t>, Saturating<$t>,
194                 #[stable(feature = "saturating_ref", since = "1.14.0")] }
195
196         #[stable(feature = "op_assign_traits", since = "1.8.0")]
197         impl DivAssign for Saturating<$t> {
198             #[inline]
199             fn div_assign(&mut self, other: Saturating<$t>) {
200                 *self = *self / other;
201             }
202         }
203         forward_ref_op_assign! { impl DivAssign, div_assign for Saturating<$t>, Saturating<$t> }
204
205         #[stable(feature = "rust1", since = "1.0.0")]
206         impl Not for Saturating<$t> {
207             type Output = Saturating<$t>;
208
209             #[inline]
210             fn not(self) -> Saturating<$t> {
211                 Saturating(!self.0)
212             }
213         }
214         forward_ref_unop! { impl Not, not for Saturating<$t>,
215                 #[stable(feature = "saturating_ref", since = "1.14.0")] }
216
217         #[stable(feature = "rust1", since = "1.0.0")]
218         impl BitXor for Saturating<$t> {
219             type Output = Saturating<$t>;
220
221             #[inline]
222             fn bitxor(self, other: Saturating<$t>) -> Saturating<$t> {
223                 Saturating(self.0 ^ other.0)
224             }
225         }
226         forward_ref_binop! { impl BitXor, bitxor for Saturating<$t>, Saturating<$t>,
227                 #[stable(feature = "saturating_ref", since = "1.14.0")] }
228
229         #[stable(feature = "op_assign_traits", since = "1.8.0")]
230         impl BitXorAssign for Saturating<$t> {
231             #[inline]
232             fn bitxor_assign(&mut self, other: Saturating<$t>) {
233                 *self = *self ^ other;
234             }
235         }
236         forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for Saturating<$t>, Saturating<$t> }
237
238         #[stable(feature = "rust1", since = "1.0.0")]
239         impl BitOr for Saturating<$t> {
240             type Output = Saturating<$t>;
241
242             #[inline]
243             fn bitor(self, other: Saturating<$t>) -> Saturating<$t> {
244                 Saturating(self.0 | other.0)
245             }
246         }
247         forward_ref_binop! { impl BitOr, bitor for Saturating<$t>, Saturating<$t>,
248                 #[stable(feature = "saturating_ref", since = "1.14.0")] }
249
250         #[stable(feature = "op_assign_traits", since = "1.8.0")]
251         impl BitOrAssign for Saturating<$t> {
252             #[inline]
253             fn bitor_assign(&mut self, other: Saturating<$t>) {
254                 *self = *self | other;
255             }
256         }
257         forward_ref_op_assign! { impl BitOrAssign, bitor_assign for Saturating<$t>, Saturating<$t> }
258
259         #[stable(feature = "rust1", since = "1.0.0")]
260         impl BitAnd for Saturating<$t> {
261             type Output = Saturating<$t>;
262
263             #[inline]
264             fn bitand(self, other: Saturating<$t>) -> Saturating<$t> {
265                 Saturating(self.0 & other.0)
266             }
267         }
268         forward_ref_binop! { impl BitAnd, bitand for Saturating<$t>, Saturating<$t>,
269                 #[stable(feature = "saturating_ref", since = "1.14.0")] }
270
271         #[stable(feature = "op_assign_traits", since = "1.8.0")]
272         impl BitAndAssign for Saturating<$t> {
273             #[inline]
274             fn bitand_assign(&mut self, other: Saturating<$t>) {
275                 *self = *self & other;
276             }
277         }
278         forward_ref_op_assign! { impl BitAndAssign, bitand_assign for Saturating<$t>, Saturating<$t> }
279
280         #[stable(feature = "saturating_neg", since = "1.45.0")]
281         impl Neg for Saturating<$t> {
282             type Output = Self;
283             #[inline]
284             fn neg(self) -> Self {
285                 Saturating(0) - self
286             }
287         }
288         forward_ref_unop! { impl Neg, neg for Saturating<$t>,
289                 #[stable(feature = "saturating_ref", since = "1.14.0")] }
290
291     )*)
292 }
293
294 saturating_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
295
296 macro_rules! saturating_int_impl {
297     ($($t:ty)*) => ($(
298         impl Saturating<$t> {
299             /// Returns the smallest value that can be represented by this integer type.
300             ///
301             /// # Examples
302             ///
303             /// Basic usage:
304             ///
305             /// ```
306             /// #![feature(saturating_int_impl)]
307             /// use std::num::Saturating;
308             ///
309             #[doc = concat!("assert_eq!(<Saturating<", stringify!($t), ">>::MIN, Saturating(", stringify!($t), "::MIN));")]
310             /// ```
311             #[unstable(feature = "saturating_int_impl", issue = "87920")]
312             pub const MIN: Self = Self(<$t>::MIN);
313
314             /// Returns the largest value that can be represented by this integer type.
315             ///
316             /// # Examples
317             ///
318             /// Basic usage:
319             ///
320             /// ```
321             /// #![feature(saturating_int_impl)]
322             /// use std::num::Saturating;
323             ///
324             #[doc = concat!("assert_eq!(<Saturating<", stringify!($t), ">>::MAX, Saturating(", stringify!($t), "::MAX));")]
325             /// ```
326             #[unstable(feature = "saturating_int_impl", issue = "87920")]
327             pub const MAX: Self = Self(<$t>::MAX);
328
329             /// Returns the size of this integer type in bits.
330             ///
331             /// # Examples
332             ///
333             /// Basic usage:
334             ///
335             /// ```
336             /// #![feature(saturating_int_impl)]
337             /// use std::num::Saturating;
338             ///
339             #[doc = concat!("assert_eq!(<Saturating<", stringify!($t), ">>::BITS, ", stringify!($t), "::BITS);")]
340             /// ```
341             #[unstable(feature = "saturating_int_impl", issue = "87920")]
342             pub const BITS: u32 = <$t>::BITS;
343
344             /// Returns the number of ones in the binary representation of `self`.
345             ///
346             /// # Examples
347             ///
348             /// Basic usage:
349             ///
350             /// ```
351             /// #![feature(saturating_int_impl)]
352             /// use std::num::Saturating;
353             ///
354             #[doc = concat!("let n = Saturating(0b01001100", stringify!($t), ");")]
355             ///
356             /// assert_eq!(n.count_ones(), 3);
357             /// ```
358             #[inline]
359             #[doc(alias = "popcount")]
360             #[doc(alias = "popcnt")]
361             #[unstable(feature = "saturating_int_impl", issue = "87920")]
362             pub const fn count_ones(self) -> u32 {
363                 self.0.count_ones()
364             }
365
366             /// Returns the number of zeros in the binary representation of `self`.
367             ///
368             /// # Examples
369             ///
370             /// Basic usage:
371             ///
372             /// ```
373             /// #![feature(saturating_int_impl)]
374             /// use std::num::Saturating;
375             ///
376             #[doc = concat!("assert_eq!(Saturating(!0", stringify!($t), ").count_zeros(), 0);")]
377             /// ```
378             #[inline]
379             #[unstable(feature = "saturating_int_impl", issue = "87920")]
380             pub const fn count_zeros(self) -> u32 {
381                 self.0.count_zeros()
382             }
383
384             /// Returns the number of trailing zeros in the binary representation of `self`.
385             ///
386             /// # Examples
387             ///
388             /// Basic usage:
389             ///
390             /// ```
391             /// #![feature(saturating_int_impl)]
392             /// use std::num::Saturating;
393             ///
394             #[doc = concat!("let n = Saturating(0b0101000", stringify!($t), ");")]
395             ///
396             /// assert_eq!(n.trailing_zeros(), 3);
397             /// ```
398             #[inline]
399             #[unstable(feature = "saturating_int_impl", issue = "87920")]
400             pub const fn trailing_zeros(self) -> u32 {
401                 self.0.trailing_zeros()
402             }
403
404             /// Shifts the bits to the left by a specified amount, `n`,
405             /// saturating the truncated bits to the end of the resulting
406             /// integer.
407             ///
408             /// Please note this isn't the same operation as the `<<` shifting
409             /// operator!
410             ///
411             /// # Examples
412             ///
413             /// Basic usage:
414             ///
415             /// ```
416             /// #![feature(saturating_int_impl)]
417             /// use std::num::Saturating;
418             ///
419             /// let n: Saturating<i64> = Saturating(0x0123456789ABCDEF);
420             /// let m: Saturating<i64> = Saturating(-0x76543210FEDCBA99);
421             ///
422             /// assert_eq!(n.rotate_left(32), m);
423             /// ```
424             #[inline]
425             #[unstable(feature = "saturating_int_impl", issue = "87920")]
426             pub const fn rotate_left(self, n: u32) -> Self {
427                 Saturating(self.0.rotate_left(n))
428             }
429
430             /// Shifts the bits to the right by a specified amount, `n`,
431             /// saturating the truncated bits to the beginning of the resulting
432             /// integer.
433             ///
434             /// Please note this isn't the same operation as the `>>` shifting
435             /// operator!
436             ///
437             /// # Examples
438             ///
439             /// Basic usage:
440             ///
441             /// ```
442             /// #![feature(saturating_int_impl)]
443             /// use std::num::Saturating;
444             ///
445             /// let n: Saturating<i64> = Saturating(0x0123456789ABCDEF);
446             /// let m: Saturating<i64> = Saturating(-0xFEDCBA987654322);
447             ///
448             /// assert_eq!(n.rotate_right(4), m);
449             /// ```
450             #[inline]
451             #[unstable(feature = "saturating_int_impl", issue = "87920")]
452             pub const fn rotate_right(self, n: u32) -> Self {
453                 Saturating(self.0.rotate_right(n))
454             }
455
456             /// Reverses the byte order of the integer.
457             ///
458             /// # Examples
459             ///
460             /// Basic usage:
461             ///
462             /// ```
463             /// #![feature(saturating_int_impl)]
464             /// use std::num::Saturating;
465             ///
466             /// let n: Saturating<i16> = Saturating(0b0000000_01010101);
467             /// assert_eq!(n, Saturating(85));
468             ///
469             /// let m = n.swap_bytes();
470             ///
471             /// assert_eq!(m, Saturating(0b01010101_00000000));
472             /// assert_eq!(m, Saturating(21760));
473             /// ```
474             #[inline]
475             #[unstable(feature = "saturating_int_impl", issue = "87920")]
476             pub const fn swap_bytes(self) -> Self {
477                 Saturating(self.0.swap_bytes())
478             }
479
480             /// Reverses the bit pattern of the integer.
481             ///
482             /// # Examples
483             ///
484             /// Please note that this example is shared between integer types.
485             /// Which explains why `i16` is used here.
486             ///
487             /// Basic usage:
488             ///
489             /// ```
490             /// #![feature(saturating_int_impl)]
491             /// use std::num::Saturating;
492             ///
493             /// let n = Saturating(0b0000000_01010101i16);
494             /// assert_eq!(n, Saturating(85));
495             ///
496             /// let m = n.reverse_bits();
497             ///
498             /// assert_eq!(m.0 as u16, 0b10101010_00000000);
499             /// assert_eq!(m, Saturating(-22016));
500             /// ```
501             #[stable(feature = "reverse_bits", since = "1.37.0")]
502             #[rustc_const_stable(feature = "const_reverse_bits", since = "1.37.0")]
503             #[inline]
504             #[must_use]
505             pub const fn reverse_bits(self) -> Self {
506                 Saturating(self.0.reverse_bits())
507             }
508
509             /// Converts an integer from big endian to the target's endianness.
510             ///
511             /// On big endian this is a no-op. On little endian the bytes are
512             /// swapped.
513             ///
514             /// # Examples
515             ///
516             /// Basic usage:
517             ///
518             /// ```
519             /// #![feature(saturating_int_impl)]
520             /// use std::num::Saturating;
521             ///
522             #[doc = concat!("let n = Saturating(0x1A", stringify!($t), ");")]
523             ///
524             /// if cfg!(target_endian = "big") {
525             #[doc = concat!("    assert_eq!(<Saturating<", stringify!($t), ">>::from_be(n), n)")]
526             /// } else {
527             #[doc = concat!("    assert_eq!(<Saturating<", stringify!($t), ">>::from_be(n), n.swap_bytes())")]
528             /// }
529             /// ```
530             #[inline]
531             #[unstable(feature = "saturating_int_impl", issue = "87920")]
532             pub const fn from_be(x: Self) -> Self {
533                 Saturating(<$t>::from_be(x.0))
534             }
535
536             /// Converts an integer from little endian to the target's endianness.
537             ///
538             /// On little endian this is a no-op. On big endian the bytes are
539             /// swapped.
540             ///
541             /// # Examples
542             ///
543             /// Basic usage:
544             ///
545             /// ```
546             /// #![feature(saturating_int_impl)]
547             /// use std::num::Saturating;
548             ///
549             #[doc = concat!("let n = Saturating(0x1A", stringify!($t), ");")]
550             ///
551             /// if cfg!(target_endian = "little") {
552             #[doc = concat!("    assert_eq!(<Saturating<", stringify!($t), ">>::from_le(n), n)")]
553             /// } else {
554             #[doc = concat!("    assert_eq!(<Saturating<", stringify!($t), ">>::from_le(n), n.swap_bytes())")]
555             /// }
556             /// ```
557             #[inline]
558             #[unstable(feature = "saturating_int_impl", issue = "87920")]
559             pub const fn from_le(x: Self) -> Self {
560                 Saturating(<$t>::from_le(x.0))
561             }
562
563             /// Converts `self` to big endian from the target's endianness.
564             ///
565             /// On big endian this is a no-op. On little endian the bytes are
566             /// swapped.
567             ///
568             /// # Examples
569             ///
570             /// Basic usage:
571             ///
572             /// ```
573             /// #![feature(saturating_int_impl)]
574             /// use std::num::Saturating;
575             ///
576             #[doc = concat!("let n = Saturating(0x1A", stringify!($t), ");")]
577             ///
578             /// if cfg!(target_endian = "big") {
579             ///     assert_eq!(n.to_be(), n)
580             /// } else {
581             ///     assert_eq!(n.to_be(), n.swap_bytes())
582             /// }
583             /// ```
584             #[inline]
585             #[unstable(feature = "saturating_int_impl", issue = "87920")]
586             pub const fn to_be(self) -> Self {
587                 Saturating(self.0.to_be())
588             }
589
590             /// Converts `self` to little endian from the target's endianness.
591             ///
592             /// On little endian this is a no-op. On big endian the bytes are
593             /// swapped.
594             ///
595             /// # Examples
596             ///
597             /// Basic usage:
598             ///
599             /// ```
600             /// #![feature(saturating_int_impl)]
601             /// use std::num::Saturating;
602             ///
603             #[doc = concat!("let n = Saturating(0x1A", stringify!($t), ");")]
604             ///
605             /// if cfg!(target_endian = "little") {
606             ///     assert_eq!(n.to_le(), n)
607             /// } else {
608             ///     assert_eq!(n.to_le(), n.swap_bytes())
609             /// }
610             /// ```
611             #[inline]
612             #[unstable(feature = "saturating_int_impl", issue = "87920")]
613             pub const fn to_le(self) -> Self {
614                 Saturating(self.0.to_le())
615             }
616
617             /// Raises self to the power of `exp`, using exponentiation by squaring.
618             ///
619             /// # Examples
620             ///
621             /// Basic usage:
622             ///
623             /// ```
624             /// #![feature(saturating_int_impl)]
625             /// use std::num::Saturating;
626             ///
627             #[doc = concat!("assert_eq!(Saturating(3", stringify!($t), ").pow(4), Saturating(81));")]
628             /// ```
629             ///
630             /// Results that are too large are wrapped:
631             ///
632             /// ```
633             /// #![feature(saturating_int_impl)]
634             /// use std::num::Saturating;
635             ///
636             /// assert_eq!(Saturating(3i8).pow(5), Saturating(127));
637             /// assert_eq!(Saturating(3i8).pow(6), Saturating(127));
638             /// ```
639             #[inline]
640             #[unstable(feature = "saturating_int_impl", issue = "87920")]
641             pub fn pow(self, exp: u32) -> Self {
642                 Saturating(self.0.saturating_pow(exp))
643             }
644         }
645     )*)
646 }
647
648 saturating_int_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
649
650 macro_rules! saturating_int_impl_signed {
651     ($($t:ty)*) => ($(
652         impl Saturating<$t> {
653             /// Returns the number of leading zeros in the binary representation of `self`.
654             ///
655             /// # Examples
656             ///
657             /// Basic usage:
658             ///
659             /// ```
660             /// #![feature(saturating_int_impl)]
661             /// use std::num::Saturating;
662             ///
663             #[doc = concat!("let n = Saturating(", stringify!($t), "::MAX) / 4;")]
664             ///
665             /// assert_eq!(n.leading_zeros(), 3);
666             /// ```
667             #[inline]
668             #[unstable(feature = "saturating_int_impl", issue = "87920")]
669             pub const fn leading_zeros(self) -> u32 {
670                 self.0.leading_zeros()
671             }
672
673             /// Computes the absolute value of `self`, saturating around at
674             /// the boundary of the type.
675             ///
676             /// The only case where such saturating can occur is when one takes the absolute value of the negative
677             /// minimal value for the type this is a positive value that is too large to represent in the type. In
678             /// such a case, this function returns `MIN` itself.
679             ///
680             /// # Examples
681             ///
682             /// Basic usage:
683             ///
684             /// ```
685             /// #![feature(saturating_int_impl)]
686             /// use std::num::Saturating;
687             ///
688             #[doc = concat!("assert_eq!(Saturating(100", stringify!($t), ").abs(), Saturating(100));")]
689             #[doc = concat!("assert_eq!(Saturating(-100", stringify!($t), ").abs(), Saturating(100));")]
690             #[doc = concat!("assert_eq!(Saturating(", stringify!($t), "::MIN).abs(), Saturating(", stringify!($t), "::MIN));")]
691             /// assert_eq!(Saturating(-128i8).abs().0 as u8, 128u8);
692             /// ```
693             #[inline]
694             #[unstable(feature = "saturating_int_impl", issue = "87920")]
695             pub fn abs(self) -> Saturating<$t> {
696                 Saturating(self.0.saturating_abs())
697             }
698
699             /// Returns a number representing sign of `self`.
700             ///
701             ///  - `0` if the number is zero
702             ///  - `1` if the number is positive
703             ///  - `-1` if the number is negative
704             ///
705             /// # Examples
706             ///
707             /// Basic usage:
708             ///
709             /// ```
710             /// #![feature(saturating_int_impl)]
711             /// use std::num::Saturating;
712             ///
713             #[doc = concat!("assert_eq!(Saturating(10", stringify!($t), ").signum(), Saturating(1));")]
714             #[doc = concat!("assert_eq!(Saturating(0", stringify!($t), ").signum(), Saturating(0));")]
715             #[doc = concat!("assert_eq!(Saturating(-10", stringify!($t), ").signum(), Saturating(-1));")]
716             /// ```
717             #[inline]
718             #[unstable(feature = "saturating_int_impl", issue = "87920")]
719             pub fn signum(self) -> Saturating<$t> {
720                 Saturating(self.0.signum())
721             }
722
723             /// Returns `true` if `self` is positive and `false` if the number is zero or
724             /// negative.
725             ///
726             /// # Examples
727             ///
728             /// Basic usage:
729             ///
730             /// ```
731             /// #![feature(saturating_int_impl)]
732             /// use std::num::Saturating;
733             ///
734             #[doc = concat!("assert!(Saturating(10", stringify!($t), ").is_positive());")]
735             #[doc = concat!("assert!(!Saturating(-10", stringify!($t), ").is_positive());")]
736             /// ```
737             #[inline]
738             #[unstable(feature = "saturating_int_impl", issue = "87920")]
739             pub const fn is_positive(self) -> bool {
740                 self.0.is_positive()
741             }
742
743             /// Returns `true` if `self` is negative and `false` if the number is zero or
744             /// positive.
745             ///
746             /// # Examples
747             ///
748             /// Basic usage:
749             ///
750             /// ```
751             /// #![feature(saturating_int_impl)]
752             /// use std::num::Saturating;
753             ///
754             #[doc = concat!("assert!(Saturating(-10", stringify!($t), ").is_negative());")]
755             #[doc = concat!("assert!(!Saturating(10", stringify!($t), ").is_negative());")]
756             /// ```
757             #[inline]
758             #[unstable(feature = "saturating_int_impl", issue = "87920")]
759             pub const fn is_negative(self) -> bool {
760                 self.0.is_negative()
761             }
762         }
763     )*)
764 }
765
766 saturating_int_impl_signed! { isize i8 i16 i32 i64 i128 }
767
768 macro_rules! saturating_int_impl_unsigned {
769     ($($t:ty)*) => ($(
770         impl Saturating<$t> {
771             /// Returns the number of leading zeros in the binary representation of `self`.
772             ///
773             /// # Examples
774             ///
775             /// Basic usage:
776             ///
777             /// ```
778             /// #![feature(saturating_int_impl)]
779             /// use std::num::Saturating;
780             ///
781             #[doc = concat!("let n = Saturating(", stringify!($t), "::MAX) / 4;")]
782             ///
783             /// assert_eq!(n.leading_zeros(), 2);
784             /// ```
785             #[inline]
786             #[unstable(feature = "saturating_int_impl", issue = "87920")]
787             pub const fn leading_zeros(self) -> u32 {
788                 self.0.leading_zeros()
789             }
790
791             /// Returns `true` if and only if `self == 2^k` for some `k`.
792             ///
793             /// # Examples
794             ///
795             /// Basic usage:
796             ///
797             /// ```
798             /// #![feature(saturating_int_impl)]
799             /// use std::num::Saturating;
800             ///
801             #[doc = concat!("assert!(Saturating(16", stringify!($t), ").is_power_of_two());")]
802             #[doc = concat!("assert!(!Saturating(10", stringify!($t), ").is_power_of_two());")]
803             /// ```
804             #[inline]
805             #[unstable(feature = "saturating_int_impl", issue = "87920")]
806             pub fn is_power_of_two(self) -> bool {
807                 self.0.is_power_of_two()
808             }
809
810         }
811     )*)
812 }
813
814 saturating_int_impl_unsigned! { usize u8 u16 u32 u64 u128 }