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_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 // } 1082