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