core/num/
saturating.rs

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