1 /// The unary logical negation operator `!`.
5 /// An implementation of `Not` for `Answer`, which enables the use of `!` to
11 /// #[derive(Debug, PartialEq)]
17 /// impl Not for Answer {
18 /// type Output = Answer;
20 /// fn not(self) -> Self::Output {
22 /// Answer::Yes => Answer::No,
23 /// Answer::No => Answer::Yes
28 /// assert_eq!(!Answer::Yes, Answer::No);
29 /// assert_eq!(!Answer::No, Answer::Yes);
32 #[stable(feature = "rust1", since = "1.0.0")]
34 /// The resulting type after applying the `!` operator.
35 #[stable(feature = "rust1", since = "1.0.0")]
38 /// Performs the unary `!` operation.
40 #[stable(feature = "rust1", since = "1.0.0")]
41 fn not(self) -> Self::Output;
44 macro_rules! not_impl {
46 #[stable(feature = "rust1", since = "1.0.0")]
51 fn not(self) -> $t { !self }
54 forward_ref_unop! { impl Not, not for $t }
58 not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
60 /// The bitwise AND operator `&`.
62 /// Note that `Rhs` is `Self` by default, but this is not mandatory.
66 /// An implementation of `BitAnd` for a wrapper around `bool`.
69 /// use std::ops::BitAnd;
71 /// #[derive(Debug, PartialEq)]
72 /// struct Scalar(bool);
74 /// impl BitAnd for Scalar {
75 /// type Output = Self;
77 /// // rhs is the "right-hand side" of the expression `a & b`
78 /// fn bitand(self, rhs: Self) -> Self::Output {
79 /// Scalar(self.0 & rhs.0)
83 /// assert_eq!(Scalar(true) & Scalar(true), Scalar(true));
84 /// assert_eq!(Scalar(true) & Scalar(false), Scalar(false));
85 /// assert_eq!(Scalar(false) & Scalar(true), Scalar(false));
86 /// assert_eq!(Scalar(false) & Scalar(false), Scalar(false));
89 /// An implementation of `BitAnd` for a wrapper around `Vec<bool>`.
92 /// use std::ops::BitAnd;
94 /// #[derive(Debug, PartialEq)]
95 /// struct BooleanVector(Vec<bool>);
97 /// impl BitAnd for BooleanVector {
98 /// type Output = Self;
100 /// fn bitand(self, BooleanVector(rhs): Self) -> Self::Output {
101 /// let BooleanVector(lhs) = self;
102 /// assert_eq!(lhs.len(), rhs.len());
103 /// BooleanVector(lhs.iter().zip(rhs.iter()).map(|(x, y)| *x && *y).collect())
107 /// let bv1 = BooleanVector(vec![true, true, false, false]);
108 /// let bv2 = BooleanVector(vec![true, false, true, false]);
109 /// let expected = BooleanVector(vec![true, false, false, false]);
110 /// assert_eq!(bv1 & bv2, expected);
114 #[stable(feature = "rust1", since = "1.0.0")]
115 #[rustc_on_unimplemented(
116 message = "no implementation for `{Self} & {Rhs}`",
117 label = "no implementation for `{Self} & {Rhs}`"
119 pub trait BitAnd<Rhs = Self> {
120 /// The resulting type after applying the `&` operator.
121 #[stable(feature = "rust1", since = "1.0.0")]
124 /// Performs the `&` operation.
126 #[stable(feature = "rust1", since = "1.0.0")]
127 fn bitand(self, rhs: Rhs) -> Self::Output;
130 macro_rules! bitand_impl {
132 #[stable(feature = "rust1", since = "1.0.0")]
137 fn bitand(self, rhs: $t) -> $t { self & rhs }
140 forward_ref_binop! { impl BitAnd, bitand for $t, $t }
144 bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
146 /// The bitwise OR operator `|`.
148 /// Note that `Rhs` is `Self` by default, but this is not mandatory.
152 /// An implementation of `BitOr` for a wrapper around `bool`.
155 /// use std::ops::BitOr;
157 /// #[derive(Debug, PartialEq)]
158 /// struct Scalar(bool);
160 /// impl BitOr for Scalar {
161 /// type Output = Self;
163 /// // rhs is the "right-hand side" of the expression `a | b`
164 /// fn bitor(self, rhs: Self) -> Self {
165 /// Scalar(self.0 | rhs.0)
169 /// assert_eq!(Scalar(true) | Scalar(true), Scalar(true));
170 /// assert_eq!(Scalar(true) | Scalar(false), Scalar(true));
171 /// assert_eq!(Scalar(false) | Scalar(true), Scalar(true));
172 /// assert_eq!(Scalar(false) | Scalar(false), Scalar(false));
175 /// An implementation of `BitOr` for a wrapper around `Vec<bool>`.
178 /// use std::ops::BitOr;
180 /// #[derive(Debug, PartialEq)]
181 /// struct BooleanVector(Vec<bool>);
183 /// impl BitOr for BooleanVector {
184 /// type Output = Self;
186 /// fn bitor(self, BooleanVector(rhs): Self) -> Self::Output {
187 /// let BooleanVector(lhs) = self;
188 /// assert_eq!(lhs.len(), rhs.len());
189 /// BooleanVector(lhs.iter().zip(rhs.iter()).map(|(x, y)| *x || *y).collect())
193 /// let bv1 = BooleanVector(vec![true, true, false, false]);
194 /// let bv2 = BooleanVector(vec![true, false, true, false]);
195 /// let expected = BooleanVector(vec![true, true, true, false]);
196 /// assert_eq!(bv1 | bv2, expected);
200 #[stable(feature = "rust1", since = "1.0.0")]
201 #[rustc_on_unimplemented(
202 message = "no implementation for `{Self} | {Rhs}`",
203 label = "no implementation for `{Self} | {Rhs}`"
205 pub trait BitOr<Rhs = Self> {
206 /// The resulting type after applying the `|` operator.
207 #[stable(feature = "rust1", since = "1.0.0")]
210 /// Performs the `|` operation.
212 #[stable(feature = "rust1", since = "1.0.0")]
213 fn bitor(self, rhs: Rhs) -> Self::Output;
216 macro_rules! bitor_impl {
218 #[stable(feature = "rust1", since = "1.0.0")]
223 fn bitor(self, rhs: $t) -> $t { self | rhs }
226 forward_ref_binop! { impl BitOr, bitor for $t, $t }
230 bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
232 /// The bitwise XOR operator `^`.
234 /// Note that `Rhs` is `Self` by default, but this is not mandatory.
238 /// An implementation of `BitXor` that lifts `^` to a wrapper around `bool`.
241 /// use std::ops::BitXor;
243 /// #[derive(Debug, PartialEq)]
244 /// struct Scalar(bool);
246 /// impl BitXor for Scalar {
247 /// type Output = Self;
249 /// // rhs is the "right-hand side" of the expression `a ^ b`
250 /// fn bitxor(self, rhs: Self) -> Self::Output {
251 /// Scalar(self.0 ^ rhs.0)
255 /// assert_eq!(Scalar(true) ^ Scalar(true), Scalar(false));
256 /// assert_eq!(Scalar(true) ^ Scalar(false), Scalar(true));
257 /// assert_eq!(Scalar(false) ^ Scalar(true), Scalar(true));
258 /// assert_eq!(Scalar(false) ^ Scalar(false), Scalar(false));
261 /// An implementation of `BitXor` trait for a wrapper around `Vec<bool>`.
264 /// use std::ops::BitXor;
266 /// #[derive(Debug, PartialEq)]
267 /// struct BooleanVector(Vec<bool>);
269 /// impl BitXor for BooleanVector {
270 /// type Output = Self;
272 /// fn bitxor(self, BooleanVector(rhs): Self) -> Self::Output {
273 /// let BooleanVector(lhs) = self;
274 /// assert_eq!(lhs.len(), rhs.len());
275 /// BooleanVector(lhs.iter()
277 /// .map(|(x, y)| (*x || *y) && !(*x && *y))
282 /// let bv1 = BooleanVector(vec![true, true, false, false]);
283 /// let bv2 = BooleanVector(vec![true, false, true, false]);
284 /// let expected = BooleanVector(vec![false, true, true, false]);
285 /// assert_eq!(bv1 ^ bv2, expected);
289 #[stable(feature = "rust1", since = "1.0.0")]
290 #[rustc_on_unimplemented(
291 message = "no implementation for `{Self} ^ {Rhs}`",
292 label = "no implementation for `{Self} ^ {Rhs}`"
294 pub trait BitXor<Rhs = Self> {
295 /// The resulting type after applying the `^` operator.
296 #[stable(feature = "rust1", since = "1.0.0")]
299 /// Performs the `^` operation.
301 #[stable(feature = "rust1", since = "1.0.0")]
302 fn bitxor(self, rhs: Rhs) -> Self::Output;
305 macro_rules! bitxor_impl {
307 #[stable(feature = "rust1", since = "1.0.0")]
312 fn bitxor(self, other: $t) -> $t { self ^ other }
315 forward_ref_binop! { impl BitXor, bitxor for $t, $t }
319 bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
321 /// The left shift operator `<<`. Note that because this trait is implemented
322 /// for all integer types with multiple right-hand-side types, Rust's type
323 /// checker has special handling for `_ << _`, setting the result type for
324 /// integer operations to the type of the left-hand-side operand. This means
325 /// that though `a << b` and `a.shl(b)` are one and the same from an evaluation
326 /// standpoint, they are different when it comes to type inference.
330 /// An implementation of `Shl` that lifts the `<<` operation on integers to a
331 /// wrapper around `usize`.
334 /// use std::ops::Shl;
336 /// #[derive(PartialEq, Debug)]
337 /// struct Scalar(usize);
339 /// impl Shl<Scalar> for Scalar {
340 /// type Output = Self;
342 /// fn shl(self, Scalar(rhs): Self) -> Scalar {
343 /// let Scalar(lhs) = self;
344 /// Scalar(lhs << rhs)
348 /// assert_eq!(Scalar(4) << Scalar(2), Scalar(16));
351 /// An implementation of `Shl` that spins a vector leftward by a given amount.
354 /// use std::ops::Shl;
356 /// #[derive(PartialEq, Debug)]
357 /// struct SpinVector<T: Clone> {
361 /// impl<T: Clone> Shl<usize> for SpinVector<T> {
362 /// type Output = Self;
364 /// fn shl(self, rhs: usize) -> Self::Output {
365 /// // Rotate the vector by `rhs` places.
366 /// let (a, b) = self.vec.split_at(rhs);
367 /// let mut spun_vector: Vec<T> = vec![];
368 /// spun_vector.extend_from_slice(b);
369 /// spun_vector.extend_from_slice(a);
370 /// SpinVector { vec: spun_vector }
374 /// assert_eq!(SpinVector { vec: vec![0, 1, 2, 3, 4] } << 2,
375 /// SpinVector { vec: vec![2, 3, 4, 0, 1] });
379 #[stable(feature = "rust1", since = "1.0.0")]
380 #[rustc_on_unimplemented(
381 message = "no implementation for `{Self} << {Rhs}`",
382 label = "no implementation for `{Self} << {Rhs}`"
384 pub trait Shl<Rhs = Self> {
385 /// The resulting type after applying the `<<` operator.
386 #[stable(feature = "rust1", since = "1.0.0")]
389 /// Performs the `<<` operation.
391 #[stable(feature = "rust1", since = "1.0.0")]
392 fn shl(self, rhs: Rhs) -> Self::Output;
395 macro_rules! shl_impl {
397 #[stable(feature = "rust1", since = "1.0.0")]
398 impl Shl<$f> for $t {
402 #[rustc_inherit_overflow_checks]
403 fn shl(self, other: $f) -> $t {
408 forward_ref_binop! { impl Shl, shl for $t, $f }
412 macro_rules! shl_impl_all {
415 shl_impl! { $t, u16 }
416 shl_impl! { $t, u32 }
417 shl_impl! { $t, u64 }
418 shl_impl! { $t, u128 }
419 shl_impl! { $t, usize }
422 shl_impl! { $t, i16 }
423 shl_impl! { $t, i32 }
424 shl_impl! { $t, i64 }
425 shl_impl! { $t, i128 }
426 shl_impl! { $t, isize }
430 shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 }
432 /// The right shift operator `>>`. Note that because this trait is implemented
433 /// for all integer types with multiple right-hand-side types, Rust's type
434 /// checker has special handling for `_ >> _`, setting the result type for
435 /// integer operations to the type of the left-hand-side operand. This means
436 /// that though `a >> b` and `a.shr(b)` are one and the same from an evaluation
437 /// standpoint, they are different when it comes to type inference.
441 /// An implementation of `Shr` that lifts the `>>` operation on integers to a
442 /// wrapper around `usize`.
445 /// use std::ops::Shr;
447 /// #[derive(PartialEq, Debug)]
448 /// struct Scalar(usize);
450 /// impl Shr<Scalar> for Scalar {
451 /// type Output = Self;
453 /// fn shr(self, Scalar(rhs): Self) -> Scalar {
454 /// let Scalar(lhs) = self;
455 /// Scalar(lhs >> rhs)
459 /// assert_eq!(Scalar(16) >> Scalar(2), Scalar(4));
462 /// An implementation of `Shr` that spins a vector rightward by a given amount.
465 /// use std::ops::Shr;
467 /// #[derive(PartialEq, Debug)]
468 /// struct SpinVector<T: Clone> {
472 /// impl<T: Clone> Shr<usize> for SpinVector<T> {
473 /// type Output = Self;
475 /// fn shr(self, rhs: usize) -> Self::Output {
476 /// // Rotate the vector by `rhs` places.
477 /// let (a, b) = self.vec.split_at(self.vec.len() - rhs);
478 /// let mut spun_vector: Vec<T> = vec![];
479 /// spun_vector.extend_from_slice(b);
480 /// spun_vector.extend_from_slice(a);
481 /// SpinVector { vec: spun_vector }
485 /// assert_eq!(SpinVector { vec: vec![0, 1, 2, 3, 4] } >> 2,
486 /// SpinVector { vec: vec![3, 4, 0, 1, 2] });
490 #[stable(feature = "rust1", since = "1.0.0")]
491 #[rustc_on_unimplemented(
492 message = "no implementation for `{Self} >> {Rhs}`",
493 label = "no implementation for `{Self} >> {Rhs}`"
495 pub trait Shr<Rhs = Self> {
496 /// The resulting type after applying the `>>` operator.
497 #[stable(feature = "rust1", since = "1.0.0")]
500 /// Performs the `>>` operation.
502 #[stable(feature = "rust1", since = "1.0.0")]
503 fn shr(self, rhs: Rhs) -> Self::Output;
506 macro_rules! shr_impl {
508 #[stable(feature = "rust1", since = "1.0.0")]
509 impl Shr<$f> for $t {
513 #[rustc_inherit_overflow_checks]
514 fn shr(self, other: $f) -> $t {
519 forward_ref_binop! { impl Shr, shr for $t, $f }
523 macro_rules! shr_impl_all {
526 shr_impl! { $t, u16 }
527 shr_impl! { $t, u32 }
528 shr_impl! { $t, u64 }
529 shr_impl! { $t, u128 }
530 shr_impl! { $t, usize }
533 shr_impl! { $t, i16 }
534 shr_impl! { $t, i32 }
535 shr_impl! { $t, i64 }
536 shr_impl! { $t, i128 }
537 shr_impl! { $t, isize }
541 shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
543 /// The bitwise AND assignment operator `&=`.
547 /// An implementation of `BitAndAssign` that lifts the `&=` operator to a
548 /// wrapper around `bool`.
551 /// use std::ops::BitAndAssign;
553 /// #[derive(Debug, PartialEq)]
554 /// struct Scalar(bool);
556 /// impl BitAndAssign for Scalar {
557 /// // rhs is the "right-hand side" of the expression `a &= b`
558 /// fn bitand_assign(&mut self, rhs: Self) {
559 /// *self = Scalar(self.0 & rhs.0)
563 /// let mut scalar = Scalar(true);
564 /// scalar &= Scalar(true);
565 /// assert_eq!(scalar, Scalar(true));
567 /// let mut scalar = Scalar(true);
568 /// scalar &= Scalar(false);
569 /// assert_eq!(scalar, Scalar(false));
571 /// let mut scalar = Scalar(false);
572 /// scalar &= Scalar(true);
573 /// assert_eq!(scalar, Scalar(false));
575 /// let mut scalar = Scalar(false);
576 /// scalar &= Scalar(false);
577 /// assert_eq!(scalar, Scalar(false));
580 /// Here, the `BitAndAssign` trait is implemented for a wrapper around
584 /// use std::ops::BitAndAssign;
586 /// #[derive(Debug, PartialEq)]
587 /// struct BooleanVector(Vec<bool>);
589 /// impl BitAndAssign for BooleanVector {
590 /// // `rhs` is the "right-hand side" of the expression `a &= b`.
591 /// fn bitand_assign(&mut self, rhs: Self) {
592 /// assert_eq!(self.0.len(), rhs.0.len());
593 /// *self = BooleanVector(self.0
595 /// .zip(rhs.0.iter())
596 /// .map(|(x, y)| *x && *y)
601 /// let mut bv = BooleanVector(vec![true, true, false, false]);
602 /// bv &= BooleanVector(vec![true, false, true, false]);
603 /// let expected = BooleanVector(vec![true, false, false, false]);
604 /// assert_eq!(bv, expected);
606 #[lang = "bitand_assign"]
608 #[stable(feature = "op_assign_traits", since = "1.8.0")]
609 #[rustc_on_unimplemented(
610 message = "no implementation for `{Self} &= {Rhs}`",
611 label = "no implementation for `{Self} &= {Rhs}`"
613 pub trait BitAndAssign<Rhs = Self> {
614 /// Performs the `&=` operation.
615 #[stable(feature = "op_assign_traits", since = "1.8.0")]
616 fn bitand_assign(&mut self, rhs: Rhs);
619 macro_rules! bitand_assign_impl {
621 #[stable(feature = "op_assign_traits", since = "1.8.0")]
622 impl BitAndAssign for $t {
624 fn bitand_assign(&mut self, other: $t) { *self &= other }
627 forward_ref_op_assign! { impl BitAndAssign, bitand_assign for $t, $t }
631 bitand_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
633 /// The bitwise OR assignment operator `|=`.
638 /// use std::ops::BitOrAssign;
640 /// #[derive(Debug, PartialEq)]
641 /// struct PersonalPreferences {
642 /// likes_cats: bool,
643 /// likes_dogs: bool,
646 /// impl BitOrAssign for PersonalPreferences {
647 /// fn bitor_assign(&mut self, rhs: Self) {
648 /// self.likes_cats |= rhs.likes_cats;
649 /// self.likes_dogs |= rhs.likes_dogs;
653 /// let mut prefs = PersonalPreferences { likes_cats: true, likes_dogs: false };
654 /// prefs |= PersonalPreferences { likes_cats: false, likes_dogs: true };
655 /// assert_eq!(prefs, PersonalPreferences { likes_cats: true, likes_dogs: true });
657 #[lang = "bitor_assign"]
659 #[stable(feature = "op_assign_traits", since = "1.8.0")]
660 #[rustc_on_unimplemented(
661 message = "no implementation for `{Self} |= {Rhs}`",
662 label = "no implementation for `{Self} |= {Rhs}`"
664 pub trait BitOrAssign<Rhs = Self> {
665 /// Performs the `|=` operation.
666 #[stable(feature = "op_assign_traits", since = "1.8.0")]
667 fn bitor_assign(&mut self, rhs: Rhs);
670 macro_rules! bitor_assign_impl {
672 #[stable(feature = "op_assign_traits", since = "1.8.0")]
673 impl BitOrAssign for $t {
675 fn bitor_assign(&mut self, other: $t) { *self |= other }
678 forward_ref_op_assign! { impl BitOrAssign, bitor_assign for $t, $t }
682 bitor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
684 /// The bitwise XOR assignment operator `^=`.
689 /// use std::ops::BitXorAssign;
691 /// #[derive(Debug, PartialEq)]
692 /// struct Personality {
694 /// likes_knitting: bool,
697 /// impl BitXorAssign for Personality {
698 /// fn bitxor_assign(&mut self, rhs: Self) {
699 /// self.has_soul ^= rhs.has_soul;
700 /// self.likes_knitting ^= rhs.likes_knitting;
704 /// let mut personality = Personality { has_soul: false, likes_knitting: true };
705 /// personality ^= Personality { has_soul: true, likes_knitting: true };
706 /// assert_eq!(personality, Personality { has_soul: true, likes_knitting: false});
708 #[lang = "bitxor_assign"]
710 #[stable(feature = "op_assign_traits", since = "1.8.0")]
711 #[rustc_on_unimplemented(
712 message = "no implementation for `{Self} ^= {Rhs}`",
713 label = "no implementation for `{Self} ^= {Rhs}`"
715 pub trait BitXorAssign<Rhs = Self> {
716 /// Performs the `^=` operation.
717 #[stable(feature = "op_assign_traits", since = "1.8.0")]
718 fn bitxor_assign(&mut self, rhs: Rhs);
721 macro_rules! bitxor_assign_impl {
723 #[stable(feature = "op_assign_traits", since = "1.8.0")]
724 impl BitXorAssign for $t {
726 fn bitxor_assign(&mut self, other: $t) { *self ^= other }
729 forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for $t, $t }
733 bitxor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
735 /// The left shift assignment operator `<<=`.
739 /// An implementation of `ShlAssign` for a wrapper around `usize`.
742 /// use std::ops::ShlAssign;
744 /// #[derive(Debug, PartialEq)]
745 /// struct Scalar(usize);
747 /// impl ShlAssign<usize> for Scalar {
748 /// fn shl_assign(&mut self, rhs: usize) {
753 /// let mut scalar = Scalar(4);
755 /// assert_eq!(scalar, Scalar(16));
757 #[lang = "shl_assign"]
758 #[doc(alias = "<<=")]
759 #[stable(feature = "op_assign_traits", since = "1.8.0")]
760 #[rustc_on_unimplemented(
761 message = "no implementation for `{Self} <<= {Rhs}`",
762 label = "no implementation for `{Self} <<= {Rhs}`"
764 pub trait ShlAssign<Rhs = Self> {
765 /// Performs the `<<=` operation.
766 #[stable(feature = "op_assign_traits", since = "1.8.0")]
767 fn shl_assign(&mut self, rhs: Rhs);
770 macro_rules! shl_assign_impl {
772 #[stable(feature = "op_assign_traits", since = "1.8.0")]
773 impl ShlAssign<$f> for $t {
775 #[rustc_inherit_overflow_checks]
776 fn shl_assign(&mut self, other: $f) {
781 forward_ref_op_assign! { impl ShlAssign, shl_assign for $t, $f }
785 macro_rules! shl_assign_impl_all {
787 shl_assign_impl! { $t, u8 }
788 shl_assign_impl! { $t, u16 }
789 shl_assign_impl! { $t, u32 }
790 shl_assign_impl! { $t, u64 }
791 shl_assign_impl! { $t, u128 }
792 shl_assign_impl! { $t, usize }
794 shl_assign_impl! { $t, i8 }
795 shl_assign_impl! { $t, i16 }
796 shl_assign_impl! { $t, i32 }
797 shl_assign_impl! { $t, i64 }
798 shl_assign_impl! { $t, i128 }
799 shl_assign_impl! { $t, isize }
803 shl_assign_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
805 /// The right shift assignment operator `>>=`.
809 /// An implementation of `ShrAssign` for a wrapper around `usize`.
812 /// use std::ops::ShrAssign;
814 /// #[derive(Debug, PartialEq)]
815 /// struct Scalar(usize);
817 /// impl ShrAssign<usize> for Scalar {
818 /// fn shr_assign(&mut self, rhs: usize) {
823 /// let mut scalar = Scalar(16);
825 /// assert_eq!(scalar, Scalar(4));
827 #[lang = "shr_assign"]
828 #[doc(alias = ">>=")]
829 #[stable(feature = "op_assign_traits", since = "1.8.0")]
830 #[rustc_on_unimplemented(
831 message = "no implementation for `{Self} >>= {Rhs}`",
832 label = "no implementation for `{Self} >>= {Rhs}`"
834 pub trait ShrAssign<Rhs = Self> {
835 /// Performs the `>>=` operation.
836 #[stable(feature = "op_assign_traits", since = "1.8.0")]
837 fn shr_assign(&mut self, rhs: Rhs);
840 macro_rules! shr_assign_impl {
842 #[stable(feature = "op_assign_traits", since = "1.8.0")]
843 impl ShrAssign<$f> for $t {
845 #[rustc_inherit_overflow_checks]
846 fn shr_assign(&mut self, other: $f) {
851 forward_ref_op_assign! { impl ShrAssign, shr_assign for $t, $f }
855 macro_rules! shr_assign_impl_all {
857 shr_assign_impl! { $t, u8 }
858 shr_assign_impl! { $t, u16 }
859 shr_assign_impl! { $t, u32 }
860 shr_assign_impl! { $t, u64 }
861 shr_assign_impl! { $t, u128 }
862 shr_assign_impl! { $t, usize }
864 shr_assign_impl! { $t, i8 }
865 shr_assign_impl! { $t, i16 }
866 shr_assign_impl! { $t, i32 }
867 shr_assign_impl! { $t, i64 }
868 shr_assign_impl! { $t, i128 }
869 shr_assign_impl! { $t, isize }
873 shr_assign_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }