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