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        /// Basic usage:
304        ///
305        /// ```
306        /// use std::num::Saturating;
307        ///
308        #[doc = concat!("assert_eq!(Saturating(2", stringify!($t), "), Saturating(5", stringify!($t), ") / Saturating(2));")]
309        #[doc = concat!("assert_eq!(Saturating(", stringify!($t), "::MAX), Saturating(", stringify!($t), "::MAX) / Saturating(1));")]
310        #[doc = concat!("assert_eq!(Saturating(", stringify!($t), "::MIN), Saturating(", stringify!($t), "::MIN) / Saturating(1));")]
311        /// ```
312        ///
313        /// ```should_panic
314        /// use std::num::Saturating;
315        ///
316        #[doc = concat!("let _ = Saturating(0", stringify!($t), ") / Saturating(0);")]
317        /// ```
318        #[stable(feature = "saturating_int_impl", since = "1.74.0")]
319        impl Div for Saturating<$t> {
320            type Output = Saturating<$t>;
321
322            #[inline]
323            fn div(self, other: Saturating<$t>) -> Saturating<$t> {
324                Saturating(self.0.saturating_div(other.0))
325            }
326        }
327        forward_ref_binop! { impl Div, div for Saturating<$t>, Saturating<$t>,
328                #[stable(feature = "saturating_int_impl", since = "1.74.0")] }
329
330
331        #[stable(feature = "saturating_int_impl", since = "1.74.0")]
332        impl DivAssign for Saturating<$t> {
333            #[inline]
334            fn div_assign(&mut self, other: Saturating<$t>) {
335                *self = *self / other;
336            }
337        }
338        forward_ref_op_assign! { impl DivAssign, div_assign for Saturating<$t>, Saturating<$t> }
339
340        #[stable(feature = "saturating_int_assign_impl", since = "1.74.0")]
341        impl DivAssign<$t> for Saturating<$t> {
342            #[inline]
343            fn div_assign(&mut self, other: $t) {
344                *self = *self / Saturating(other);
345            }
346        }
347        forward_ref_op_assign! { impl DivAssign, div_assign for Saturating<$t>, $t }
348
349        #[stable(feature = "saturating_int_impl", since = "1.74.0")]
350        impl Rem for Saturating<$t> {
351            type Output = Saturating<$t>;
352
353            #[inline]
354            fn rem(self, other: Saturating<$t>) -> Saturating<$t> {
355                Saturating(self.0.rem(other.0))
356            }
357        }
358        forward_ref_binop! { impl Rem, rem for Saturating<$t>, Saturating<$t>,
359                #[stable(feature = "saturating_int_impl", since = "1.74.0")] }
360
361        #[stable(feature = "saturating_int_impl", since = "1.74.0")]
362        impl RemAssign for Saturating<$t> {
363            #[inline]
364            fn rem_assign(&mut self, other: Saturating<$t>) {
365                *self = *self % other;
366            }
367        }
368        forward_ref_op_assign! { impl RemAssign, rem_assign for Saturating<$t>, Saturating<$t> }
369
370        #[stable(feature = "saturating_int_assign_impl", since = "1.74.0")]
371        impl RemAssign<$t> for Saturating<$t> {
372            #[inline]
373            fn rem_assign(&mut self, other: $t) {
374                *self = *self % Saturating(other);
375            }
376        }
377        forward_ref_op_assign! { impl RemAssign, rem_assign for Saturating<$t>, $t }
378
379        #[stable(feature = "saturating_int_impl", since = "1.74.0")]
380        impl Not for Saturating<$t> {
381            type Output = Saturating<$t>;
382
383            #[inline]
384            fn not(self) -> Saturating<$t> {
385                Saturating(!self.0)
386            }
387        }
388        forward_ref_unop! { impl Not, not for Saturating<$t>,
389                #[stable(feature = "saturating_int_impl", since = "1.74.0")] }
390
391        #[stable(feature = "saturating_int_impl", since = "1.74.0")]
392        impl BitXor for Saturating<$t> {
393            type Output = Saturating<$t>;
394
395            #[inline]
396            fn bitxor(self, other: Saturating<$t>) -> Saturating<$t> {
397                Saturating(self.0 ^ other.0)
398            }
399        }
400        forward_ref_binop! { impl BitXor, bitxor for Saturating<$t>, Saturating<$t>,
401                #[stable(feature = "saturating_int_impl", since = "1.74.0")] }
402
403        #[stable(feature = "saturating_int_impl", since = "1.74.0")]
404        impl BitXorAssign for Saturating<$t> {
405            #[inline]
406            fn bitxor_assign(&mut self, other: Saturating<$t>) {
407                *self = *self ^ other;
408            }
409        }
410        forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for Saturating<$t>, Saturating<$t> }
411
412        #[stable(feature = "saturating_int_assign_impl", since = "1.74.0")]
413        impl BitXorAssign<$t> for Saturating<$t> {
414            #[inline]
415            fn bitxor_assign(&mut self, other: $t) {
416                *self = *self ^ Saturating(other);
417            }
418        }
419        forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for Saturating<$t>, $t }
420
421        #[stable(feature = "saturating_int_impl", since = "1.74.0")]
422        impl BitOr for Saturating<$t> {
423            type Output = Saturating<$t>;
424
425            #[inline]
426            fn bitor(self, other: Saturating<$t>) -> Saturating<$t> {
427                Saturating(self.0 | other.0)
428            }
429        }
430        forward_ref_binop! { impl BitOr, bitor for Saturating<$t>, Saturating<$t>,
431                #[stable(feature = "saturating_int_impl", since = "1.74.0")] }
432
433        #[stable(feature = "saturating_int_impl", since = "1.74.0")]
434        impl BitOrAssign for Saturating<$t> {
435            #[inline]
436            fn bitor_assign(&mut self, other: Saturating<$t>) {
437                *self = *self | other;
438            }
439        }
440        forward_ref_op_assign! { impl BitOrAssign, bitor_assign for Saturating<$t>, Saturating<$t> }
441
442        #[stable(feature = "saturating_int_assign_impl", since = "1.74.0")]
443        impl BitOrAssign<$t> for Saturating<$t> {
444            #[inline]
445            fn bitor_assign(&mut self, other: $t) {
446                *self = *self | Saturating(other);
447            }
448        }
449        forward_ref_op_assign! { impl BitOrAssign, bitor_assign for Saturating<$t>, $t }
450
451        #[stable(feature = "saturating_int_impl", since = "1.74.0")]
452        impl BitAnd for Saturating<$t> {
453            type Output = Saturating<$t>;
454
455            #[inline]
456            fn bitand(self, other: Saturating<$t>) -> Saturating<$t> {
457                Saturating(self.0 & other.0)
458            }
459        }
460        forward_ref_binop! { impl BitAnd, bitand for Saturating<$t>, Saturating<$t>,
461                #[stable(feature = "saturating_int_impl", since = "1.74.0")] }
462
463        #[stable(feature = "saturating_int_impl", since = "1.74.0")]
464        impl BitAndAssign for Saturating<$t> {
465            #[inline]
466            fn bitand_assign(&mut self, other: Saturating<$t>) {
467                *self = *self & other;
468            }
469        }
470        forward_ref_op_assign! { impl BitAndAssign, bitand_assign for Saturating<$t>, Saturating<$t> }
471
472        #[stable(feature = "saturating_int_assign_impl", since = "1.74.0")]
473        impl BitAndAssign<$t> for Saturating<$t> {
474            #[inline]
475            fn bitand_assign(&mut self, other: $t) {
476                *self = *self & Saturating(other);
477            }
478        }
479        forward_ref_op_assign! { impl BitAndAssign, bitand_assign for Saturating<$t>, $t }
480
481    )*)
482}
483
484saturating_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
485
486macro_rules! saturating_int_impl {
487    ($($t:ty)*) => ($(
488        impl Saturating<$t> {
489            /// Returns the smallest value that can be represented by this integer type.
490            ///
491            /// # Examples
492            ///
493            /// Basic usage:
494            ///
495            /// ```
496            /// use std::num::Saturating;
497            ///
498            #[doc = concat!("assert_eq!(<Saturating<", stringify!($t), ">>::MIN, Saturating(", stringify!($t), "::MIN));")]
499            /// ```
500            #[stable(feature = "saturating_int_impl", since = "1.74.0")]
501            pub const MIN: Self = Self(<$t>::MIN);
502
503            /// Returns the largest value that can be represented by this integer type.
504            ///
505            /// # Examples
506            ///
507            /// Basic usage:
508            ///
509            /// ```
510            /// use std::num::Saturating;
511            ///
512            #[doc = concat!("assert_eq!(<Saturating<", stringify!($t), ">>::MAX, Saturating(", stringify!($t), "::MAX));")]
513            /// ```
514            #[stable(feature = "saturating_int_impl", since = "1.74.0")]
515            pub const MAX: Self = Self(<$t>::MAX);
516
517            /// Returns the size of this integer type in bits.
518            ///
519            /// # Examples
520            ///
521            /// Basic usage:
522            ///
523            /// ```
524            /// use std::num::Saturating;
525            ///
526            #[doc = concat!("assert_eq!(<Saturating<", stringify!($t), ">>::BITS, ", stringify!($t), "::BITS);")]
527            /// ```
528            #[stable(feature = "saturating_int_impl", since = "1.74.0")]
529            pub const BITS: u32 = <$t>::BITS;
530
531            /// Returns the number of ones in the binary representation of `self`.
532            ///
533            /// # Examples
534            ///
535            /// Basic usage:
536            ///
537            /// ```
538            /// use std::num::Saturating;
539            ///
540            #[doc = concat!("let n = Saturating(0b01001100", stringify!($t), ");")]
541            ///
542            /// assert_eq!(n.count_ones(), 3);
543            /// ```
544            #[inline]
545            #[doc(alias = "popcount")]
546            #[doc(alias = "popcnt")]
547            #[must_use = "this returns the result of the operation, \
548                          without modifying the original"]
549            #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")]
550            #[stable(feature = "saturating_int_impl", since = "1.74.0")]
551            pub const fn count_ones(self) -> u32 {
552                self.0.count_ones()
553            }
554
555            /// Returns the number of zeros in the binary representation of `self`.
556            ///
557            /// # Examples
558            ///
559            /// Basic usage:
560            ///
561            /// ```
562            /// use std::num::Saturating;
563            ///
564            #[doc = concat!("assert_eq!(Saturating(!0", stringify!($t), ").count_zeros(), 0);")]
565            /// ```
566            #[inline]
567            #[must_use = "this returns the result of the operation, \
568                          without modifying the original"]
569            #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")]
570            #[stable(feature = "saturating_int_impl", since = "1.74.0")]
571            pub const fn count_zeros(self) -> u32 {
572                self.0.count_zeros()
573            }
574
575            /// Returns the number of trailing zeros in the binary representation of `self`.
576            ///
577            /// # Examples
578            ///
579            /// Basic usage:
580            ///
581            /// ```
582            /// use std::num::Saturating;
583            ///
584            #[doc = concat!("let n = Saturating(0b0101000", stringify!($t), ");")]
585            ///
586            /// assert_eq!(n.trailing_zeros(), 3);
587            /// ```
588            #[inline]
589            #[must_use = "this returns the result of the operation, \
590                          without modifying the original"]
591            #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")]
592            #[stable(feature = "saturating_int_impl", since = "1.74.0")]
593            pub const fn trailing_zeros(self) -> u32 {
594                self.0.trailing_zeros()
595            }
596
597            /// Shifts the bits to the left by a specified amount, `n`,
598            /// saturating the truncated bits to the end of the resulting
599            /// integer.
600            ///
601            /// Please note this isn't the same operation as the `<<` shifting
602            /// operator!
603            ///
604            /// # Examples
605            ///
606            /// Basic usage:
607            ///
608            /// ```
609            /// use std::num::Saturating;
610            ///
611            /// let n: Saturating<i64> = Saturating(0x0123456789ABCDEF);
612            /// let m: Saturating<i64> = Saturating(-0x76543210FEDCBA99);
613            ///
614            /// assert_eq!(n.rotate_left(32), m);
615            /// ```
616            #[inline]
617            #[must_use = "this returns the result of the operation, \
618                          without modifying the original"]
619            #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")]
620            #[stable(feature = "saturating_int_impl", since = "1.74.0")]
621            pub const fn rotate_left(self, n: u32) -> Self {
622                Saturating(self.0.rotate_left(n))
623            }
624
625            /// Shifts the bits to the right by a specified amount, `n`,
626            /// saturating the truncated bits to the beginning of the resulting
627            /// integer.
628            ///
629            /// Please note this isn't the same operation as the `>>` shifting
630            /// operator!
631            ///
632            /// # Examples
633            ///
634            /// Basic usage:
635            ///
636            /// ```
637            /// use std::num::Saturating;
638            ///
639            /// let n: Saturating<i64> = Saturating(0x0123456789ABCDEF);
640            /// let m: Saturating<i64> = Saturating(-0xFEDCBA987654322);
641            ///
642            /// assert_eq!(n.rotate_right(4), m);
643            /// ```
644            #[inline]
645            #[must_use = "this returns the result of the operation, \
646                          without modifying the original"]
647            #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")]
648            #[stable(feature = "saturating_int_impl", since = "1.74.0")]
649            pub const fn rotate_right(self, n: u32) -> Self {
650                Saturating(self.0.rotate_right(n))
651            }
652
653            /// Reverses the byte order of the integer.
654            ///
655            /// # Examples
656            ///
657            /// Basic usage:
658            ///
659            /// ```
660            /// use std::num::Saturating;
661            ///
662            /// let n: Saturating<i16> = Saturating(0b0000000_01010101);
663            /// assert_eq!(n, Saturating(85));
664            ///
665            /// let m = n.swap_bytes();
666            ///
667            /// assert_eq!(m, Saturating(0b01010101_00000000));
668            /// assert_eq!(m, Saturating(21760));
669            /// ```
670            #[inline]
671            #[must_use = "this returns the result of the operation, \
672                          without modifying the original"]
673            #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")]
674            #[stable(feature = "saturating_int_impl", since = "1.74.0")]
675            pub const fn swap_bytes(self) -> Self {
676                Saturating(self.0.swap_bytes())
677            }
678
679            /// Reverses the bit pattern of the integer.
680            ///
681            /// # Examples
682            ///
683            /// Please note that this example is shared between integer types.
684            /// Which explains why `i16` is used here.
685            ///
686            /// Basic usage:
687            ///
688            /// ```
689            /// use std::num::Saturating;
690            ///
691            /// let n = Saturating(0b0000000_01010101i16);
692            /// assert_eq!(n, Saturating(85));
693            ///
694            /// let m = n.reverse_bits();
695            ///
696            /// assert_eq!(m.0 as u16, 0b10101010_00000000);
697            /// assert_eq!(m, Saturating(-22016));
698            /// ```
699            #[inline]
700            #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")]
701            #[stable(feature = "saturating_int_impl", since = "1.74.0")]
702            #[must_use = "this returns the result of the operation, \
703                          without modifying the original"]
704            pub const fn reverse_bits(self) -> Self {
705                Saturating(self.0.reverse_bits())
706            }
707
708            /// Converts an integer from big endian to the target's endianness.
709            ///
710            /// On big endian this is a no-op. On little endian the bytes are
711            /// swapped.
712            ///
713            /// # Examples
714            ///
715            /// Basic usage:
716            ///
717            /// ```
718            /// use std::num::Saturating;
719            ///
720            #[doc = concat!("let n = Saturating(0x1A", stringify!($t), ");")]
721            ///
722            /// if cfg!(target_endian = "big") {
723            #[doc = concat!("    assert_eq!(<Saturating<", stringify!($t), ">>::from_be(n), n)")]
724            /// } else {
725            #[doc = concat!("    assert_eq!(<Saturating<", stringify!($t), ">>::from_be(n), n.swap_bytes())")]
726            /// }
727            /// ```
728            #[inline]
729            #[must_use]
730            #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")]
731            #[stable(feature = "saturating_int_impl", since = "1.74.0")]
732            pub const fn from_be(x: Self) -> Self {
733                Saturating(<$t>::from_be(x.0))
734            }
735
736            /// Converts an integer from little endian to the target's endianness.
737            ///
738            /// On little endian this is a no-op. On big endian the bytes are
739            /// swapped.
740            ///
741            /// # Examples
742            ///
743            /// Basic usage:
744            ///
745            /// ```
746            /// use std::num::Saturating;
747            ///
748            #[doc = concat!("let n = Saturating(0x1A", stringify!($t), ");")]
749            ///
750            /// if cfg!(target_endian = "little") {
751            #[doc = concat!("    assert_eq!(<Saturating<", stringify!($t), ">>::from_le(n), n)")]
752            /// } else {
753            #[doc = concat!("    assert_eq!(<Saturating<", stringify!($t), ">>::from_le(n), n.swap_bytes())")]
754            /// }
755            /// ```
756            #[inline]
757            #[must_use]
758            #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")]
759            #[stable(feature = "saturating_int_impl", since = "1.74.0")]
760            pub const fn from_le(x: Self) -> Self {
761                Saturating(<$t>::from_le(x.0))
762            }
763
764            /// Converts `self` to big endian from the target's endianness.
765            ///
766            /// On big endian this is a no-op. On little endian the bytes are
767            /// swapped.
768            ///
769            /// # Examples
770            ///
771            /// Basic usage:
772            ///
773            /// ```
774            /// use std::num::Saturating;
775            ///
776            #[doc = concat!("let n = Saturating(0x1A", stringify!($t), ");")]
777            ///
778            /// if cfg!(target_endian = "big") {
779            ///     assert_eq!(n.to_be(), n)
780            /// } else {
781            ///     assert_eq!(n.to_be(), n.swap_bytes())
782            /// }
783            /// ```
784            #[inline]
785            #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")]
786            #[stable(feature = "saturating_int_impl", since = "1.74.0")]
787            #[must_use = "this returns the result of the operation, \
788                          without modifying the original"]
789            pub const fn to_be(self) -> Self {
790                Saturating(self.0.to_be())
791            }
792
793            /// Converts `self` to little endian from the target's endianness.
794            ///
795            /// On little endian this is a no-op. On big endian the bytes are
796            /// swapped.
797            ///
798            /// # Examples
799            ///
800            /// Basic usage:
801            ///
802            /// ```
803            /// use std::num::Saturating;
804            ///
805            #[doc = concat!("let n = Saturating(0x1A", stringify!($t), ");")]
806            ///
807            /// if cfg!(target_endian = "little") {
808            ///     assert_eq!(n.to_le(), n)
809            /// } else {
810            ///     assert_eq!(n.to_le(), n.swap_bytes())
811            /// }
812            /// ```
813            #[inline]
814            #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")]
815            #[stable(feature = "saturating_int_impl", since = "1.74.0")]
816            #[must_use = "this returns the result of the operation, \
817                          without modifying the original"]
818            pub const fn to_le(self) -> Self {
819                Saturating(self.0.to_le())
820            }
821
822            /// Raises self to the power of `exp`, using exponentiation by squaring.
823            ///
824            /// # Examples
825            ///
826            /// Basic usage:
827            ///
828            /// ```
829            /// use std::num::Saturating;
830            ///
831            #[doc = concat!("assert_eq!(Saturating(3", stringify!($t), ").pow(4), Saturating(81));")]
832            /// ```
833            ///
834            /// Results that are too large are saturated:
835            ///
836            /// ```
837            /// use std::num::Saturating;
838            ///
839            /// assert_eq!(Saturating(3i8).pow(5), Saturating(127));
840            /// assert_eq!(Saturating(3i8).pow(6), Saturating(127));
841            /// ```
842            #[inline]
843            #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")]
844            #[stable(feature = "saturating_int_impl", since = "1.74.0")]
845            #[must_use = "this returns the result of the operation, \
846                          without modifying the original"]
847            pub const fn pow(self, exp: u32) -> Self {
848                Saturating(self.0.saturating_pow(exp))
849            }
850        }
851    )*)
852}
853
854saturating_int_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
855
856macro_rules! saturating_int_impl_signed {
857    ($($t:ty)*) => ($(
858        impl Saturating<$t> {
859            /// Returns the number of leading zeros in the binary representation of `self`.
860            ///
861            /// # Examples
862            ///
863            /// Basic usage:
864            ///
865            /// ```
866            /// use std::num::Saturating;
867            ///
868            #[doc = concat!("let n = Saturating(", stringify!($t), "::MAX >> 2);")]
869            ///
870            /// assert_eq!(n.leading_zeros(), 3);
871            /// ```
872            #[inline]
873            #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")]
874            #[stable(feature = "saturating_int_impl", since = "1.74.0")]
875            #[must_use = "this returns the result of the operation, \
876                          without modifying the original"]
877            pub const fn leading_zeros(self) -> u32 {
878                self.0.leading_zeros()
879            }
880
881            /// Saturating absolute value. Computes `self.abs()`, returning `MAX` if `self == MIN`
882            /// instead of overflowing.
883            ///
884            /// # Examples
885            ///
886            /// Basic usage:
887            ///
888            /// ```
889            /// use std::num::Saturating;
890            ///
891            #[doc = concat!("assert_eq!(Saturating(100", stringify!($t), ").abs(), Saturating(100));")]
892            #[doc = concat!("assert_eq!(Saturating(-100", stringify!($t), ").abs(), Saturating(100));")]
893            #[doc = concat!("assert_eq!(Saturating(", stringify!($t), "::MIN).abs(), Saturating((", stringify!($t), "::MIN + 1).abs()));")]
894            #[doc = concat!("assert_eq!(Saturating(", stringify!($t), "::MIN).abs(), Saturating(", stringify!($t), "::MIN.saturating_abs()));")]
895            #[doc = concat!("assert_eq!(Saturating(", stringify!($t), "::MIN).abs(), Saturating(", stringify!($t), "::MAX));")]
896            /// ```
897            #[inline]
898            #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")]
899            #[stable(feature = "saturating_int_impl", since = "1.74.0")]
900            #[must_use = "this returns the result of the operation, \
901                          without modifying the original"]
902            pub const fn abs(self) -> Saturating<$t> {
903                Saturating(self.0.saturating_abs())
904            }
905
906            /// Returns a number representing sign of `self`.
907            ///
908            ///  - `0` if the number is zero
909            ///  - `1` if the number is positive
910            ///  - `-1` if the number is negative
911            ///
912            /// # Examples
913            ///
914            /// Basic usage:
915            ///
916            /// ```
917            /// use std::num::Saturating;
918            ///
919            #[doc = concat!("assert_eq!(Saturating(10", stringify!($t), ").signum(), Saturating(1));")]
920            #[doc = concat!("assert_eq!(Saturating(0", stringify!($t), ").signum(), Saturating(0));")]
921            #[doc = concat!("assert_eq!(Saturating(-10", stringify!($t), ").signum(), Saturating(-1));")]
922            /// ```
923            #[inline]
924            #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")]
925            #[stable(feature = "saturating_int_impl", since = "1.74.0")]
926            #[must_use = "this returns the result of the operation, \
927                          without modifying the original"]
928            pub const fn signum(self) -> Saturating<$t> {
929                Saturating(self.0.signum())
930            }
931
932            /// Returns `true` if `self` is positive and `false` if the number is zero or
933            /// negative.
934            ///
935            /// # Examples
936            ///
937            /// Basic usage:
938            ///
939            /// ```
940            /// use std::num::Saturating;
941            ///
942            #[doc = concat!("assert!(Saturating(10", stringify!($t), ").is_positive());")]
943            #[doc = concat!("assert!(!Saturating(-10", stringify!($t), ").is_positive());")]
944            /// ```
945            #[must_use]
946            #[inline]
947            #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")]
948            #[stable(feature = "saturating_int_impl", since = "1.74.0")]
949            pub const fn is_positive(self) -> bool {
950                self.0.is_positive()
951            }
952
953            /// Returns `true` if `self` is negative and `false` if the number is zero or
954            /// positive.
955            ///
956            /// # Examples
957            ///
958            /// Basic usage:
959            ///
960            /// ```
961            /// use std::num::Saturating;
962            ///
963            #[doc = concat!("assert!(Saturating(-10", stringify!($t), ").is_negative());")]
964            #[doc = concat!("assert!(!Saturating(10", stringify!($t), ").is_negative());")]
965            /// ```
966            #[must_use]
967            #[inline]
968            #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")]
969            #[stable(feature = "saturating_int_impl", since = "1.74.0")]
970            pub const fn is_negative(self) -> bool {
971                self.0.is_negative()
972            }
973        }
974
975        #[stable(feature = "saturating_int_impl", since = "1.74.0")]
976        impl Neg for Saturating<$t> {
977            type Output = Self;
978            #[inline]
979            fn neg(self) -> Self {
980                Saturating(self.0.saturating_neg())
981            }
982        }
983        forward_ref_unop! { impl Neg, neg for Saturating<$t>,
984                #[stable(feature = "saturating_int_impl", since = "1.74.0")] }
985    )*)
986}
987
988saturating_int_impl_signed! { isize i8 i16 i32 i64 i128 }
989
990macro_rules! saturating_int_impl_unsigned {
991    ($($t:ty)*) => ($(
992        impl Saturating<$t> {
993            /// Returns the number of leading zeros in the binary representation of `self`.
994            ///
995            /// # Examples
996            ///
997            /// Basic usage:
998            ///
999            /// ```
1000            /// use std::num::Saturating;
1001            ///
1002            #[doc = concat!("let n = Saturating(", stringify!($t), "::MAX >> 2);")]
1003            ///
1004            /// assert_eq!(n.leading_zeros(), 2);
1005            /// ```
1006            #[inline]
1007            #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")]
1008            #[stable(feature = "saturating_int_impl", since = "1.74.0")]
1009            #[must_use = "this returns the result of the operation, \
1010                          without modifying the original"]
1011            pub const fn leading_zeros(self) -> u32 {
1012                self.0.leading_zeros()
1013            }
1014
1015            /// Returns `true` if and only if `self == 2^k` for some `k`.
1016            ///
1017            /// # Examples
1018            ///
1019            /// Basic usage:
1020            ///
1021            /// ```
1022            /// use std::num::Saturating;
1023            ///
1024            #[doc = concat!("assert!(Saturating(16", stringify!($t), ").is_power_of_two());")]
1025            #[doc = concat!("assert!(!Saturating(10", stringify!($t), ").is_power_of_two());")]
1026            /// ```
1027            #[must_use]
1028            #[inline]
1029            #[rustc_const_stable(feature = "saturating_int_impl", since = "1.74.0")]
1030            #[stable(feature = "saturating_int_impl", since = "1.74.0")]
1031            pub const fn is_power_of_two(self) -> bool {
1032                self.0.is_power_of_two()
1033            }
1034
1035        }
1036    )*)
1037}
1038
1039saturating_int_impl_unsigned! { usize u8 u16 u32 u64 u128 }
1040
1041// Related to potential Shl and ShlAssign implementation
1042//
1043// mod shift_max {
1044//     #![allow(non_upper_case_globals)]
1045//
1046//     #[cfg(target_pointer_width = "16")]
1047//     mod platform {
1048//         pub const usize: u32 = super::u16;
1049//         pub const isize: u32 = super::i16;
1050//     }
1051//
1052//     #[cfg(target_pointer_width = "32")]
1053//     mod platform {
1054//         pub const usize: u32 = super::u32;
1055//         pub const isize: u32 = super::i32;
1056//     }
1057//
1058//     #[cfg(target_pointer_width = "64")]
1059//     mod platform {
1060//         pub const usize: u32 = super::u64;
1061//         pub const isize: u32 = super::i64;
1062//     }
1063//
1064//     pub const i8: u32 = (1 << 3) - 1;
1065//     pub const i16: u32 = (1 << 4) - 1;
1066//     pub const i32: u32 = (1 << 5) - 1;
1067//     pub const i64: u32 = (1 << 6) - 1;
1068//     pub const i128: u32 = (1 << 7) - 1;
1069//     pub use self::platform::isize;
1070//
1071//     pub const u8: u32 = i8;
1072//     pub const u16: u32 = i16;
1073//     pub const u32: u32 = i32;
1074//     pub const u64: u32 = i64;
1075//     pub const u128: u32 = i128;
1076//     pub use self::platform::usize;
1077// }