1 /// The unary logical negation operator `!`. 2 /// 3 /// # Examples 4 /// 5 /// An implementation of `Not` for `Answer`, which enables the use of `!` to 6 /// invert its value. 7 /// 8 /// ``` 9 /// use std::ops::Not; 10 /// 11 /// #[derive(Debug, PartialEq)] 12 /// enum Answer { 13 /// Yes, 14 /// No, 15 /// } 16 /// 17 /// impl Not for Answer { 18 /// type Output = Self; 19 /// 20 /// fn not(self) -> Self::Output { 21 /// match self { 22 /// Answer::Yes => Answer::No, 23 /// Answer::No => Answer::Yes 24 /// } 25 /// } 26 /// } 27 /// 28 /// assert_eq!(!Answer::Yes, Answer::No); 29 /// assert_eq!(!Answer::No, Answer::Yes); 30 /// ``` 31 #[lang = "not"] 32 #[stable(feature = "rust1", since = "1.0.0")] 33 #[doc(alias = "!")] 34 pub trait Not { 35 /// The resulting type after applying the `!` operator. 36 #[stable(feature = "rust1", since = "1.0.0")] 37 type Output; 38 39 /// Performs the unary `!` operation. 40 /// 41 /// # Examples 42 /// 43 /// ``` 44 /// assert_eq!(!true, false); 45 /// assert_eq!(!false, true); 46 /// assert_eq!(!1u8, 254); 47 /// assert_eq!(!0u8, 255); 48 /// ``` 49 #[must_use] 50 #[stable(feature = "rust1", since = "1.0.0")] not(self) -> Self::Output51 fn not(self) -> Self::Output; 52 } 53 54 macro_rules! not_impl { 55 ($($t:ty)*) => ($( 56 #[stable(feature = "rust1", since = "1.0.0")] 57 #[rustc_const_unstable(feature = "const_ops", issue = "90080")] 58 impl const Not for $t { 59 type Output = $t; 60 61 #[inline] 62 fn not(self) -> $t { !self } 63 } 64 65 forward_ref_unop! { impl const Not, not for $t } 66 )*) 67 } 68 69 not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } 70 71 /// The bitwise AND operator `&`. 72 /// 73 /// Note that `Rhs` is `Self` by default, but this is not mandatory. 74 /// 75 /// # Examples 76 /// 77 /// An implementation of `BitAnd` for a wrapper around `bool`. 78 /// 79 /// ``` 80 /// use std::ops::BitAnd; 81 /// 82 /// #[derive(Debug, PartialEq)] 83 /// struct Scalar(bool); 84 /// 85 /// impl BitAnd for Scalar { 86 /// type Output = Self; 87 /// 88 /// // rhs is the "right-hand side" of the expression `a & b` 89 /// fn bitand(self, rhs: Self) -> Self::Output { 90 /// Self(self.0 & rhs.0) 91 /// } 92 /// } 93 /// 94 /// assert_eq!(Scalar(true) & Scalar(true), Scalar(true)); 95 /// assert_eq!(Scalar(true) & Scalar(false), Scalar(false)); 96 /// assert_eq!(Scalar(false) & Scalar(true), Scalar(false)); 97 /// assert_eq!(Scalar(false) & Scalar(false), Scalar(false)); 98 /// ``` 99 /// 100 /// An implementation of `BitAnd` for a wrapper around `Vec<bool>`. 101 /// 102 /// ``` 103 /// use std::ops::BitAnd; 104 /// 105 /// #[derive(Debug, PartialEq)] 106 /// struct BooleanVector(Vec<bool>); 107 /// 108 /// impl BitAnd for BooleanVector { 109 /// type Output = Self; 110 /// 111 /// fn bitand(self, Self(rhs): Self) -> Self::Output { 112 /// let Self(lhs) = self; 113 /// assert_eq!(lhs.len(), rhs.len()); 114 /// Self( 115 /// lhs.iter() 116 /// .zip(rhs.iter()) 117 /// .map(|(x, y)| *x & *y) 118 /// .collect() 119 /// ) 120 /// } 121 /// } 122 /// 123 /// let bv1 = BooleanVector(vec![true, true, false, false]); 124 /// let bv2 = BooleanVector(vec![true, false, true, false]); 125 /// let expected = BooleanVector(vec![true, false, false, false]); 126 /// assert_eq!(bv1 & bv2, expected); 127 /// ``` 128 #[lang = "bitand"] 129 #[doc(alias = "&")] 130 #[stable(feature = "rust1", since = "1.0.0")] 131 #[rustc_on_unimplemented( 132 message = "no implementation for `{Self} & {Rhs}`", 133 label = "no implementation for `{Self} & {Rhs}`" 134 )] 135 pub trait BitAnd<Rhs = Self> { 136 /// The resulting type after applying the `&` operator. 137 #[stable(feature = "rust1", since = "1.0.0")] 138 type Output; 139 140 /// Performs the `&` operation. 141 /// 142 /// # Examples 143 /// 144 /// ``` 145 /// assert_eq!(true & false, false); 146 /// assert_eq!(true & true, true); 147 /// assert_eq!(5u8 & 1u8, 1); 148 /// assert_eq!(5u8 & 2u8, 0); 149 /// ``` 150 #[must_use] 151 #[stable(feature = "rust1", since = "1.0.0")] bitand(self, rhs: Rhs) -> Self::Output152 fn bitand(self, rhs: Rhs) -> Self::Output; 153 } 154 155 macro_rules! bitand_impl { 156 ($($t:ty)*) => ($( 157 #[stable(feature = "rust1", since = "1.0.0")] 158 #[rustc_const_unstable(feature = "const_ops", issue = "90080")] 159 impl const BitAnd for $t { 160 type Output = $t; 161 162 #[inline] 163 fn bitand(self, rhs: $t) -> $t { self & rhs } 164 } 165 166 forward_ref_binop! { impl const BitAnd, bitand for $t, $t } 167 )*) 168 } 169 170 bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } 171 172 /// The bitwise OR operator `|`. 173 /// 174 /// Note that `Rhs` is `Self` by default, but this is not mandatory. 175 /// 176 /// # Examples 177 /// 178 /// An implementation of `BitOr` for a wrapper around `bool`. 179 /// 180 /// ``` 181 /// use std::ops::BitOr; 182 /// 183 /// #[derive(Debug, PartialEq)] 184 /// struct Scalar(bool); 185 /// 186 /// impl BitOr for Scalar { 187 /// type Output = Self; 188 /// 189 /// // rhs is the "right-hand side" of the expression `a | b` 190 /// fn bitor(self, rhs: Self) -> Self::Output { 191 /// Self(self.0 | rhs.0) 192 /// } 193 /// } 194 /// 195 /// assert_eq!(Scalar(true) | Scalar(true), Scalar(true)); 196 /// assert_eq!(Scalar(true) | Scalar(false), Scalar(true)); 197 /// assert_eq!(Scalar(false) | Scalar(true), Scalar(true)); 198 /// assert_eq!(Scalar(false) | Scalar(false), Scalar(false)); 199 /// ``` 200 /// 201 /// An implementation of `BitOr` for a wrapper around `Vec<bool>`. 202 /// 203 /// ``` 204 /// use std::ops::BitOr; 205 /// 206 /// #[derive(Debug, PartialEq)] 207 /// struct BooleanVector(Vec<bool>); 208 /// 209 /// impl BitOr for BooleanVector { 210 /// type Output = Self; 211 /// 212 /// fn bitor(self, Self(rhs): Self) -> Self::Output { 213 /// let Self(lhs) = self; 214 /// assert_eq!(lhs.len(), rhs.len()); 215 /// Self( 216 /// lhs.iter() 217 /// .zip(rhs.iter()) 218 /// .map(|(x, y)| *x | *y) 219 /// .collect() 220 /// ) 221 /// } 222 /// } 223 /// 224 /// let bv1 = BooleanVector(vec![true, true, false, false]); 225 /// let bv2 = BooleanVector(vec![true, false, true, false]); 226 /// let expected = BooleanVector(vec![true, true, true, false]); 227 /// assert_eq!(bv1 | bv2, expected); 228 /// ``` 229 #[lang = "bitor"] 230 #[doc(alias = "|")] 231 #[stable(feature = "rust1", since = "1.0.0")] 232 #[rustc_on_unimplemented( 233 message = "no implementation for `{Self} | {Rhs}`", 234 label = "no implementation for `{Self} | {Rhs}`" 235 )] 236 pub trait BitOr<Rhs = Self> { 237 /// The resulting type after applying the `|` operator. 238 #[stable(feature = "rust1", since = "1.0.0")] 239 type Output; 240 241 /// Performs the `|` operation. 242 /// 243 /// # Examples 244 /// 245 /// ``` 246 /// assert_eq!(true | false, true); 247 /// assert_eq!(false | false, false); 248 /// assert_eq!(5u8 | 1u8, 5); 249 /// assert_eq!(5u8 | 2u8, 7); 250 /// ``` 251 #[must_use] 252 #[stable(feature = "rust1", since = "1.0.0")] bitor(self, rhs: Rhs) -> Self::Output253 fn bitor(self, rhs: Rhs) -> Self::Output; 254 } 255 256 macro_rules! bitor_impl { 257 ($($t:ty)*) => ($( 258 #[stable(feature = "rust1", since = "1.0.0")] 259 #[rustc_const_unstable(feature = "const_ops", issue = "90080")] 260 impl const BitOr for $t { 261 type Output = $t; 262 263 #[inline] 264 fn bitor(self, rhs: $t) -> $t { self | rhs } 265 } 266 267 forward_ref_binop! { impl const BitOr, bitor for $t, $t } 268 )*) 269 } 270 271 bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } 272 273 /// The bitwise XOR operator `^`. 274 /// 275 /// Note that `Rhs` is `Self` by default, but this is not mandatory. 276 /// 277 /// # Examples 278 /// 279 /// An implementation of `BitXor` that lifts `^` to a wrapper around `bool`. 280 /// 281 /// ``` 282 /// use std::ops::BitXor; 283 /// 284 /// #[derive(Debug, PartialEq)] 285 /// struct Scalar(bool); 286 /// 287 /// impl BitXor for Scalar { 288 /// type Output = Self; 289 /// 290 /// // rhs is the "right-hand side" of the expression `a ^ b` 291 /// fn bitxor(self, rhs: Self) -> Self::Output { 292 /// Self(self.0 ^ rhs.0) 293 /// } 294 /// } 295 /// 296 /// assert_eq!(Scalar(true) ^ Scalar(true), Scalar(false)); 297 /// assert_eq!(Scalar(true) ^ Scalar(false), Scalar(true)); 298 /// assert_eq!(Scalar(false) ^ Scalar(true), Scalar(true)); 299 /// assert_eq!(Scalar(false) ^ Scalar(false), Scalar(false)); 300 /// ``` 301 /// 302 /// An implementation of `BitXor` trait for a wrapper around `Vec<bool>`. 303 /// 304 /// ``` 305 /// use std::ops::BitXor; 306 /// 307 /// #[derive(Debug, PartialEq)] 308 /// struct BooleanVector(Vec<bool>); 309 /// 310 /// impl BitXor for BooleanVector { 311 /// type Output = Self; 312 /// 313 /// fn bitxor(self, Self(rhs): Self) -> Self::Output { 314 /// let Self(lhs) = self; 315 /// assert_eq!(lhs.len(), rhs.len()); 316 /// Self( 317 /// lhs.iter() 318 /// .zip(rhs.iter()) 319 /// .map(|(x, y)| *x ^ *y) 320 /// .collect() 321 /// ) 322 /// } 323 /// } 324 /// 325 /// let bv1 = BooleanVector(vec![true, true, false, false]); 326 /// let bv2 = BooleanVector(vec![true, false, true, false]); 327 /// let expected = BooleanVector(vec![false, true, true, false]); 328 /// assert_eq!(bv1 ^ bv2, expected); 329 /// ``` 330 #[lang = "bitxor"] 331 #[doc(alias = "^")] 332 #[stable(feature = "rust1", since = "1.0.0")] 333 #[rustc_on_unimplemented( 334 message = "no implementation for `{Self} ^ {Rhs}`", 335 label = "no implementation for `{Self} ^ {Rhs}`" 336 )] 337 pub trait BitXor<Rhs = Self> { 338 /// The resulting type after applying the `^` operator. 339 #[stable(feature = "rust1", since = "1.0.0")] 340 type Output; 341 342 /// Performs the `^` operation. 343 /// 344 /// # Examples 345 /// 346 /// ``` 347 /// assert_eq!(true ^ false, true); 348 /// assert_eq!(true ^ true, false); 349 /// assert_eq!(5u8 ^ 1u8, 4); 350 /// assert_eq!(5u8 ^ 2u8, 7); 351 /// ``` 352 #[must_use] 353 #[stable(feature = "rust1", since = "1.0.0")] bitxor(self, rhs: Rhs) -> Self::Output354 fn bitxor(self, rhs: Rhs) -> Self::Output; 355 } 356 357 macro_rules! bitxor_impl { 358 ($($t:ty)*) => ($( 359 #[stable(feature = "rust1", since = "1.0.0")] 360 #[rustc_const_unstable(feature = "const_ops", issue = "90080")] 361 impl const BitXor for $t { 362 type Output = $t; 363 364 #[inline] 365 fn bitxor(self, other: $t) -> $t { self ^ other } 366 } 367 368 forward_ref_binop! { impl const BitXor, bitxor for $t, $t } 369 )*) 370 } 371 372 bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } 373 374 /// The left shift operator `<<`. Note that because this trait is implemented 375 /// for all integer types with multiple right-hand-side types, Rust's type 376 /// checker has special handling for `_ << _`, setting the result type for 377 /// integer operations to the type of the left-hand-side operand. This means 378 /// that though `a << b` and `a.shl(b)` are one and the same from an evaluation 379 /// standpoint, they are different when it comes to type inference. 380 /// 381 /// # Examples 382 /// 383 /// An implementation of `Shl` that lifts the `<<` operation on integers to a 384 /// wrapper around `usize`. 385 /// 386 /// ``` 387 /// use std::ops::Shl; 388 /// 389 /// #[derive(PartialEq, Debug)] 390 /// struct Scalar(usize); 391 /// 392 /// impl Shl<Scalar> for Scalar { 393 /// type Output = Self; 394 /// 395 /// fn shl(self, Self(rhs): Self) -> Self::Output { 396 /// let Self(lhs) = self; 397 /// Self(lhs << rhs) 398 /// } 399 /// } 400 /// 401 /// assert_eq!(Scalar(4) << Scalar(2), Scalar(16)); 402 /// ``` 403 /// 404 /// An implementation of `Shl` that spins a vector leftward by a given amount. 405 /// 406 /// ``` 407 /// use std::ops::Shl; 408 /// 409 /// #[derive(PartialEq, Debug)] 410 /// struct SpinVector<T: Clone> { 411 /// vec: Vec<T>, 412 /// } 413 /// 414 /// impl<T: Clone> Shl<usize> for SpinVector<T> { 415 /// type Output = Self; 416 /// 417 /// fn shl(self, rhs: usize) -> Self::Output { 418 /// // Rotate the vector by `rhs` places. 419 /// let (a, b) = self.vec.split_at(rhs); 420 /// let mut spun_vector = vec![]; 421 /// spun_vector.extend_from_slice(b); 422 /// spun_vector.extend_from_slice(a); 423 /// Self { vec: spun_vector } 424 /// } 425 /// } 426 /// 427 /// assert_eq!(SpinVector { vec: vec![0, 1, 2, 3, 4] } << 2, 428 /// SpinVector { vec: vec![2, 3, 4, 0, 1] }); 429 /// ``` 430 #[lang = "shl"] 431 #[doc(alias = "<<")] 432 #[stable(feature = "rust1", since = "1.0.0")] 433 #[rustc_on_unimplemented( 434 message = "no implementation for `{Self} << {Rhs}`", 435 label = "no implementation for `{Self} << {Rhs}`" 436 )] 437 pub trait Shl<Rhs = Self> { 438 /// The resulting type after applying the `<<` operator. 439 #[stable(feature = "rust1", since = "1.0.0")] 440 type Output; 441 442 /// Performs the `<<` operation. 443 /// 444 /// # Examples 445 /// 446 /// ``` 447 /// assert_eq!(5u8 << 1, 10); 448 /// assert_eq!(1u8 << 1, 2); 449 /// ``` 450 #[must_use] 451 #[stable(feature = "rust1", since = "1.0.0")] shl(self, rhs: Rhs) -> Self::Output452 fn shl(self, rhs: Rhs) -> Self::Output; 453 } 454 455 macro_rules! shl_impl { 456 ($t:ty, $f:ty) => { 457 #[stable(feature = "rust1", since = "1.0.0")] 458 #[rustc_const_unstable(feature = "const_ops", issue = "90080")] 459 impl const Shl<$f> for $t { 460 type Output = $t; 461 462 #[inline] 463 #[rustc_inherit_overflow_checks] 464 fn shl(self, other: $f) -> $t { 465 self << other 466 } 467 } 468 469 forward_ref_binop! { impl const Shl, shl for $t, $f } 470 }; 471 } 472 473 macro_rules! shl_impl_all { 474 ($($t:ty)*) => ($( 475 shl_impl! { $t, u8 } 476 shl_impl! { $t, u16 } 477 shl_impl! { $t, u32 } 478 shl_impl! { $t, u64 } 479 shl_impl! { $t, u128 } 480 shl_impl! { $t, usize } 481 482 shl_impl! { $t, i8 } 483 shl_impl! { $t, i16 } 484 shl_impl! { $t, i32 } 485 shl_impl! { $t, i64 } 486 shl_impl! { $t, i128 } 487 shl_impl! { $t, isize } 488 )*) 489 } 490 491 shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 } 492 493 /// The right shift operator `>>`. Note that because this trait is implemented 494 /// for all integer types with multiple right-hand-side types, Rust's type 495 /// checker has special handling for `_ >> _`, setting the result type for 496 /// integer operations to the type of the left-hand-side operand. This means 497 /// that though `a >> b` and `a.shr(b)` are one and the same from an evaluation 498 /// standpoint, they are different when it comes to type inference. 499 /// 500 /// # Examples 501 /// 502 /// An implementation of `Shr` that lifts the `>>` operation on integers to a 503 /// wrapper around `usize`. 504 /// 505 /// ``` 506 /// use std::ops::Shr; 507 /// 508 /// #[derive(PartialEq, Debug)] 509 /// struct Scalar(usize); 510 /// 511 /// impl Shr<Scalar> for Scalar { 512 /// type Output = Self; 513 /// 514 /// fn shr(self, Self(rhs): Self) -> Self::Output { 515 /// let Self(lhs) = self; 516 /// Self(lhs >> rhs) 517 /// } 518 /// } 519 /// 520 /// assert_eq!(Scalar(16) >> Scalar(2), Scalar(4)); 521 /// ``` 522 /// 523 /// An implementation of `Shr` that spins a vector rightward by a given amount. 524 /// 525 /// ``` 526 /// use std::ops::Shr; 527 /// 528 /// #[derive(PartialEq, Debug)] 529 /// struct SpinVector<T: Clone> { 530 /// vec: Vec<T>, 531 /// } 532 /// 533 /// impl<T: Clone> Shr<usize> for SpinVector<T> { 534 /// type Output = Self; 535 /// 536 /// fn shr(self, rhs: usize) -> Self::Output { 537 /// // Rotate the vector by `rhs` places. 538 /// let (a, b) = self.vec.split_at(self.vec.len() - rhs); 539 /// let mut spun_vector = vec![]; 540 /// spun_vector.extend_from_slice(b); 541 /// spun_vector.extend_from_slice(a); 542 /// Self { vec: spun_vector } 543 /// } 544 /// } 545 /// 546 /// assert_eq!(SpinVector { vec: vec![0, 1, 2, 3, 4] } >> 2, 547 /// SpinVector { vec: vec![3, 4, 0, 1, 2] }); 548 /// ``` 549 #[lang = "shr"] 550 #[doc(alias = ">>")] 551 #[stable(feature = "rust1", since = "1.0.0")] 552 #[rustc_on_unimplemented( 553 message = "no implementation for `{Self} >> {Rhs}`", 554 label = "no implementation for `{Self} >> {Rhs}`" 555 )] 556 pub trait Shr<Rhs = Self> { 557 /// The resulting type after applying the `>>` operator. 558 #[stable(feature = "rust1", since = "1.0.0")] 559 type Output; 560 561 /// Performs the `>>` operation. 562 /// 563 /// # Examples 564 /// 565 /// ``` 566 /// assert_eq!(5u8 >> 1, 2); 567 /// assert_eq!(2u8 >> 1, 1); 568 /// ``` 569 #[must_use] 570 #[stable(feature = "rust1", since = "1.0.0")] shr(self, rhs: Rhs) -> Self::Output571 fn shr(self, rhs: Rhs) -> Self::Output; 572 } 573 574 macro_rules! shr_impl { 575 ($t:ty, $f:ty) => { 576 #[stable(feature = "rust1", since = "1.0.0")] 577 #[rustc_const_unstable(feature = "const_ops", issue = "90080")] 578 impl const Shr<$f> for $t { 579 type Output = $t; 580 581 #[inline] 582 #[rustc_inherit_overflow_checks] 583 fn shr(self, other: $f) -> $t { 584 self >> other 585 } 586 } 587 588 forward_ref_binop! { impl const Shr, shr for $t, $f } 589 }; 590 } 591 592 macro_rules! shr_impl_all { 593 ($($t:ty)*) => ($( 594 shr_impl! { $t, u8 } 595 shr_impl! { $t, u16 } 596 shr_impl! { $t, u32 } 597 shr_impl! { $t, u64 } 598 shr_impl! { $t, u128 } 599 shr_impl! { $t, usize } 600 601 shr_impl! { $t, i8 } 602 shr_impl! { $t, i16 } 603 shr_impl! { $t, i32 } 604 shr_impl! { $t, i64 } 605 shr_impl! { $t, i128 } 606 shr_impl! { $t, isize } 607 )*) 608 } 609 610 shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } 611 612 /// The bitwise AND assignment operator `&=`. 613 /// 614 /// # Examples 615 /// 616 /// An implementation of `BitAndAssign` that lifts the `&=` operator to a 617 /// wrapper around `bool`. 618 /// 619 /// ``` 620 /// use std::ops::BitAndAssign; 621 /// 622 /// #[derive(Debug, PartialEq)] 623 /// struct Scalar(bool); 624 /// 625 /// impl BitAndAssign for Scalar { 626 /// // rhs is the "right-hand side" of the expression `a &= b` 627 /// fn bitand_assign(&mut self, rhs: Self) { 628 /// *self = Self(self.0 & rhs.0) 629 /// } 630 /// } 631 /// 632 /// let mut scalar = Scalar(true); 633 /// scalar &= Scalar(true); 634 /// assert_eq!(scalar, Scalar(true)); 635 /// 636 /// let mut scalar = Scalar(true); 637 /// scalar &= Scalar(false); 638 /// assert_eq!(scalar, Scalar(false)); 639 /// 640 /// let mut scalar = Scalar(false); 641 /// scalar &= Scalar(true); 642 /// assert_eq!(scalar, Scalar(false)); 643 /// 644 /// let mut scalar = Scalar(false); 645 /// scalar &= Scalar(false); 646 /// assert_eq!(scalar, Scalar(false)); 647 /// ``` 648 /// 649 /// Here, the `BitAndAssign` trait is implemented for a wrapper around 650 /// `Vec<bool>`. 651 /// 652 /// ``` 653 /// use std::ops::BitAndAssign; 654 /// 655 /// #[derive(Debug, PartialEq)] 656 /// struct BooleanVector(Vec<bool>); 657 /// 658 /// impl BitAndAssign for BooleanVector { 659 /// // `rhs` is the "right-hand side" of the expression `a &= b`. 660 /// fn bitand_assign(&mut self, rhs: Self) { 661 /// assert_eq!(self.0.len(), rhs.0.len()); 662 /// *self = Self( 663 /// self.0 664 /// .iter() 665 /// .zip(rhs.0.iter()) 666 /// .map(|(x, y)| *x & *y) 667 /// .collect() 668 /// ); 669 /// } 670 /// } 671 /// 672 /// let mut bv = BooleanVector(vec![true, true, false, false]); 673 /// bv &= BooleanVector(vec![true, false, true, false]); 674 /// let expected = BooleanVector(vec![true, false, false, false]); 675 /// assert_eq!(bv, expected); 676 /// ``` 677 #[lang = "bitand_assign"] 678 #[doc(alias = "&=")] 679 #[stable(feature = "op_assign_traits", since = "1.8.0")] 680 #[rustc_on_unimplemented( 681 message = "no implementation for `{Self} &= {Rhs}`", 682 label = "no implementation for `{Self} &= {Rhs}`" 683 )] 684 pub trait BitAndAssign<Rhs = Self> { 685 /// Performs the `&=` operation. 686 /// 687 /// # Examples 688 /// 689 /// ``` 690 /// let mut x = true; 691 /// x &= false; 692 /// assert_eq!(x, false); 693 /// 694 /// let mut x = true; 695 /// x &= true; 696 /// assert_eq!(x, true); 697 /// 698 /// let mut x: u8 = 5; 699 /// x &= 1; 700 /// assert_eq!(x, 1); 701 /// 702 /// let mut x: u8 = 5; 703 /// x &= 2; 704 /// assert_eq!(x, 0); 705 /// ``` 706 #[stable(feature = "op_assign_traits", since = "1.8.0")] bitand_assign(&mut self, rhs: Rhs)707 fn bitand_assign(&mut self, rhs: Rhs); 708 } 709 710 macro_rules! bitand_assign_impl { 711 ($($t:ty)+) => ($( 712 #[stable(feature = "op_assign_traits", since = "1.8.0")] 713 #[rustc_const_unstable(feature = "const_ops", issue = "90080")] 714 impl const BitAndAssign for $t { 715 #[inline] 716 fn bitand_assign(&mut self, other: $t) { *self &= other } 717 } 718 719 forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for $t, $t } 720 )+) 721 } 722 723 bitand_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } 724 725 /// The bitwise OR assignment operator `|=`. 726 /// 727 /// # Examples 728 /// 729 /// ``` 730 /// use std::ops::BitOrAssign; 731 /// 732 /// #[derive(Debug, PartialEq)] 733 /// struct PersonalPreferences { 734 /// likes_cats: bool, 735 /// likes_dogs: bool, 736 /// } 737 /// 738 /// impl BitOrAssign for PersonalPreferences { 739 /// fn bitor_assign(&mut self, rhs: Self) { 740 /// self.likes_cats |= rhs.likes_cats; 741 /// self.likes_dogs |= rhs.likes_dogs; 742 /// } 743 /// } 744 /// 745 /// let mut prefs = PersonalPreferences { likes_cats: true, likes_dogs: false }; 746 /// prefs |= PersonalPreferences { likes_cats: false, likes_dogs: true }; 747 /// assert_eq!(prefs, PersonalPreferences { likes_cats: true, likes_dogs: true }); 748 /// ``` 749 #[lang = "bitor_assign"] 750 #[doc(alias = "|=")] 751 #[stable(feature = "op_assign_traits", since = "1.8.0")] 752 #[rustc_on_unimplemented( 753 message = "no implementation for `{Self} |= {Rhs}`", 754 label = "no implementation for `{Self} |= {Rhs}`" 755 )] 756 pub trait BitOrAssign<Rhs = Self> { 757 /// Performs the `|=` operation. 758 /// 759 /// # Examples 760 /// 761 /// ``` 762 /// let mut x = true; 763 /// x |= false; 764 /// assert_eq!(x, true); 765 /// 766 /// let mut x = false; 767 /// x |= false; 768 /// assert_eq!(x, false); 769 /// 770 /// let mut x: u8 = 5; 771 /// x |= 1; 772 /// assert_eq!(x, 5); 773 /// 774 /// let mut x: u8 = 5; 775 /// x |= 2; 776 /// assert_eq!(x, 7); 777 /// ``` 778 #[stable(feature = "op_assign_traits", since = "1.8.0")] bitor_assign(&mut self, rhs: Rhs)779 fn bitor_assign(&mut self, rhs: Rhs); 780 } 781 782 macro_rules! bitor_assign_impl { 783 ($($t:ty)+) => ($( 784 #[stable(feature = "op_assign_traits", since = "1.8.0")] 785 #[rustc_const_unstable(feature = "const_ops", issue = "90080")] 786 impl const BitOrAssign for $t { 787 #[inline] 788 fn bitor_assign(&mut self, other: $t) { *self |= other } 789 } 790 791 forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for $t, $t } 792 )+) 793 } 794 795 bitor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } 796 797 /// The bitwise XOR assignment operator `^=`. 798 /// 799 /// # Examples 800 /// 801 /// ``` 802 /// use std::ops::BitXorAssign; 803 /// 804 /// #[derive(Debug, PartialEq)] 805 /// struct Personality { 806 /// has_soul: bool, 807 /// likes_knitting: bool, 808 /// } 809 /// 810 /// impl BitXorAssign for Personality { 811 /// fn bitxor_assign(&mut self, rhs: Self) { 812 /// self.has_soul ^= rhs.has_soul; 813 /// self.likes_knitting ^= rhs.likes_knitting; 814 /// } 815 /// } 816 /// 817 /// let mut personality = Personality { has_soul: false, likes_knitting: true }; 818 /// personality ^= Personality { has_soul: true, likes_knitting: true }; 819 /// assert_eq!(personality, Personality { has_soul: true, likes_knitting: false}); 820 /// ``` 821 #[lang = "bitxor_assign"] 822 #[doc(alias = "^=")] 823 #[stable(feature = "op_assign_traits", since = "1.8.0")] 824 #[rustc_on_unimplemented( 825 message = "no implementation for `{Self} ^= {Rhs}`", 826 label = "no implementation for `{Self} ^= {Rhs}`" 827 )] 828 pub trait BitXorAssign<Rhs = Self> { 829 /// Performs the `^=` operation. 830 /// 831 /// # Examples 832 /// 833 /// ``` 834 /// let mut x = true; 835 /// x ^= false; 836 /// assert_eq!(x, true); 837 /// 838 /// let mut x = true; 839 /// x ^= true; 840 /// assert_eq!(x, false); 841 /// 842 /// let mut x: u8 = 5; 843 /// x ^= 1; 844 /// assert_eq!(x, 4); 845 /// 846 /// let mut x: u8 = 5; 847 /// x ^= 2; 848 /// assert_eq!(x, 7); 849 /// ``` 850 #[stable(feature = "op_assign_traits", since = "1.8.0")] bitxor_assign(&mut self, rhs: Rhs)851 fn bitxor_assign(&mut self, rhs: Rhs); 852 } 853 854 macro_rules! bitxor_assign_impl { 855 ($($t:ty)+) => ($( 856 #[stable(feature = "op_assign_traits", since = "1.8.0")] 857 #[rustc_const_unstable(feature = "const_ops", issue = "90080")] 858 impl const BitXorAssign for $t { 859 #[inline] 860 fn bitxor_assign(&mut self, other: $t) { *self ^= other } 861 } 862 863 forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for $t, $t } 864 )+) 865 } 866 867 bitxor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } 868 869 /// The left shift assignment operator `<<=`. 870 /// 871 /// # Examples 872 /// 873 /// An implementation of `ShlAssign` for a wrapper around `usize`. 874 /// 875 /// ``` 876 /// use std::ops::ShlAssign; 877 /// 878 /// #[derive(Debug, PartialEq)] 879 /// struct Scalar(usize); 880 /// 881 /// impl ShlAssign<usize> for Scalar { 882 /// fn shl_assign(&mut self, rhs: usize) { 883 /// self.0 <<= rhs; 884 /// } 885 /// } 886 /// 887 /// let mut scalar = Scalar(4); 888 /// scalar <<= 2; 889 /// assert_eq!(scalar, Scalar(16)); 890 /// ``` 891 #[lang = "shl_assign"] 892 #[doc(alias = "<<=")] 893 #[stable(feature = "op_assign_traits", since = "1.8.0")] 894 #[rustc_on_unimplemented( 895 message = "no implementation for `{Self} <<= {Rhs}`", 896 label = "no implementation for `{Self} <<= {Rhs}`" 897 )] 898 pub trait ShlAssign<Rhs = Self> { 899 /// Performs the `<<=` operation. 900 /// 901 /// # Examples 902 /// 903 /// ``` 904 /// let mut x: u8 = 5; 905 /// x <<= 1; 906 /// assert_eq!(x, 10); 907 /// 908 /// let mut x: u8 = 1; 909 /// x <<= 1; 910 /// assert_eq!(x, 2); 911 /// ``` 912 #[stable(feature = "op_assign_traits", since = "1.8.0")] shl_assign(&mut self, rhs: Rhs)913 fn shl_assign(&mut self, rhs: Rhs); 914 } 915 916 macro_rules! shl_assign_impl { 917 ($t:ty, $f:ty) => { 918 #[stable(feature = "op_assign_traits", since = "1.8.0")] 919 #[rustc_const_unstable(feature = "const_ops", issue = "90080")] 920 impl const ShlAssign<$f> for $t { 921 #[inline] 922 #[rustc_inherit_overflow_checks] 923 fn shl_assign(&mut self, other: $f) { 924 *self <<= other 925 } 926 } 927 928 forward_ref_op_assign! { impl const ShlAssign, shl_assign for $t, $f } 929 }; 930 } 931 932 macro_rules! shl_assign_impl_all { 933 ($($t:ty)*) => ($( 934 shl_assign_impl! { $t, u8 } 935 shl_assign_impl! { $t, u16 } 936 shl_assign_impl! { $t, u32 } 937 shl_assign_impl! { $t, u64 } 938 shl_assign_impl! { $t, u128 } 939 shl_assign_impl! { $t, usize } 940 941 shl_assign_impl! { $t, i8 } 942 shl_assign_impl! { $t, i16 } 943 shl_assign_impl! { $t, i32 } 944 shl_assign_impl! { $t, i64 } 945 shl_assign_impl! { $t, i128 } 946 shl_assign_impl! { $t, isize } 947 )*) 948 } 949 950 shl_assign_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } 951 952 /// The right shift assignment operator `>>=`. 953 /// 954 /// # Examples 955 /// 956 /// An implementation of `ShrAssign` for a wrapper around `usize`. 957 /// 958 /// ``` 959 /// use std::ops::ShrAssign; 960 /// 961 /// #[derive(Debug, PartialEq)] 962 /// struct Scalar(usize); 963 /// 964 /// impl ShrAssign<usize> for Scalar { 965 /// fn shr_assign(&mut self, rhs: usize) { 966 /// self.0 >>= rhs; 967 /// } 968 /// } 969 /// 970 /// let mut scalar = Scalar(16); 971 /// scalar >>= 2; 972 /// assert_eq!(scalar, Scalar(4)); 973 /// ``` 974 #[lang = "shr_assign"] 975 #[doc(alias = ">>=")] 976 #[stable(feature = "op_assign_traits", since = "1.8.0")] 977 #[rustc_on_unimplemented( 978 message = "no implementation for `{Self} >>= {Rhs}`", 979 label = "no implementation for `{Self} >>= {Rhs}`" 980 )] 981 pub trait ShrAssign<Rhs = Self> { 982 /// Performs the `>>=` operation. 983 /// 984 /// # Examples 985 /// 986 /// ``` 987 /// let mut x: u8 = 5; 988 /// x >>= 1; 989 /// assert_eq!(x, 2); 990 /// 991 /// let mut x: u8 = 2; 992 /// x >>= 1; 993 /// assert_eq!(x, 1); 994 /// ``` 995 #[stable(feature = "op_assign_traits", since = "1.8.0")] shr_assign(&mut self, rhs: Rhs)996 fn shr_assign(&mut self, rhs: Rhs); 997 } 998 999 macro_rules! shr_assign_impl { 1000 ($t:ty, $f:ty) => { 1001 #[stable(feature = "op_assign_traits", since = "1.8.0")] 1002 #[rustc_const_unstable(feature = "const_ops", issue = "90080")] 1003 impl const ShrAssign<$f> for $t { 1004 #[inline] 1005 #[rustc_inherit_overflow_checks] 1006 fn shr_assign(&mut self, other: $f) { 1007 *self >>= other 1008 } 1009 } 1010 1011 forward_ref_op_assign! { impl const ShrAssign, shr_assign for $t, $f } 1012 }; 1013 } 1014 1015 macro_rules! shr_assign_impl_all { 1016 ($($t:ty)*) => ($( 1017 shr_assign_impl! { $t, u8 } 1018 shr_assign_impl! { $t, u16 } 1019 shr_assign_impl! { $t, u32 } 1020 shr_assign_impl! { $t, u64 } 1021 shr_assign_impl! { $t, u128 } 1022 shr_assign_impl! { $t, usize } 1023 1024 shr_assign_impl! { $t, i8 } 1025 shr_assign_impl! { $t, i16 } 1026 shr_assign_impl! { $t, i32 } 1027 shr_assign_impl! { $t, i64 } 1028 shr_assign_impl! { $t, i128 } 1029 shr_assign_impl! { $t, isize } 1030 )*) 1031 } 1032 1033 shr_assign_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } 1034