Skip to main content

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