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