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