core/num/
saturating.rs

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

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy