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