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(message="no implementation for `{Self} & {Rhs}`",
116 label="no implementation for `{Self} & {Rhs}`")]
117 pub trait BitAnd<Rhs=Self> {
118 /// The resulting type after applying the `&` operator.
119 #[stable(feature = "rust1", since = "1.0.0")]
122 /// Performs the `&` operation.
124 #[stable(feature = "rust1", since = "1.0.0")]
125 fn bitand(self, rhs: Rhs) -> Self::Output;
128 macro_rules! bitand_impl {
130 #[stable(feature = "rust1", since = "1.0.0")]
135 fn bitand(self, rhs: $t) -> $t { self & rhs }
138 forward_ref_binop! { impl BitAnd, bitand for $t, $t }
142 bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
144 /// The bitwise OR operator `|`.
146 /// Note that `Rhs` is `Self` by default, but this is not mandatory.
150 /// An implementation of `BitOr` for a wrapper around `bool`.
153 /// use std::ops::BitOr;
155 /// #[derive(Debug, PartialEq)]
156 /// struct Scalar(bool);
158 /// impl BitOr for Scalar {
159 /// type Output = Self;
161 /// // rhs is the "right-hand side" of the expression `a | b`
162 /// fn bitor(self, rhs: Self) -> Self {
163 /// Scalar(self.0 | rhs.0)
167 /// assert_eq!(Scalar(true) | Scalar(true), Scalar(true));
168 /// assert_eq!(Scalar(true) | Scalar(false), Scalar(true));
169 /// assert_eq!(Scalar(false) | Scalar(true), Scalar(true));
170 /// assert_eq!(Scalar(false) | Scalar(false), Scalar(false));
173 /// An implementation of `BitOr` for a wrapper around `Vec<bool>`.
176 /// use std::ops::BitOr;
178 /// #[derive(Debug, PartialEq)]
179 /// struct BooleanVector(Vec<bool>);
181 /// impl BitOr for BooleanVector {
182 /// type Output = Self;
184 /// fn bitor(self, BooleanVector(rhs): Self) -> Self::Output {
185 /// let BooleanVector(lhs) = self;
186 /// assert_eq!(lhs.len(), rhs.len());
187 /// BooleanVector(lhs.iter().zip(rhs.iter()).map(|(x, y)| *x || *y).collect())
191 /// let bv1 = BooleanVector(vec![true, true, false, false]);
192 /// let bv2 = BooleanVector(vec![true, false, true, false]);
193 /// let expected = BooleanVector(vec![true, true, true, false]);
194 /// assert_eq!(bv1 | bv2, expected);
198 #[stable(feature = "rust1", since = "1.0.0")]
199 #[rustc_on_unimplemented(message="no implementation for `{Self} | {Rhs}`",
200 label="no implementation for `{Self} | {Rhs}`")]
201 pub trait BitOr<Rhs=Self> {
202 /// The resulting type after applying the `|` operator.
203 #[stable(feature = "rust1", since = "1.0.0")]
206 /// Performs the `|` operation.
208 #[stable(feature = "rust1", since = "1.0.0")]
209 fn bitor(self, rhs: Rhs) -> Self::Output;
212 macro_rules! bitor_impl {
214 #[stable(feature = "rust1", since = "1.0.0")]
219 fn bitor(self, rhs: $t) -> $t { self | rhs }
222 forward_ref_binop! { impl BitOr, bitor for $t, $t }
226 bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
228 /// The bitwise XOR operator `^`.
230 /// Note that `Rhs` is `Self` by default, but this is not mandatory.
234 /// An implementation of `BitXor` that lifts `^` to a wrapper around `bool`.
237 /// use std::ops::BitXor;
239 /// #[derive(Debug, PartialEq)]
240 /// struct Scalar(bool);
242 /// impl BitXor for Scalar {
243 /// type Output = Self;
245 /// // rhs is the "right-hand side" of the expression `a ^ b`
246 /// fn bitxor(self, rhs: Self) -> Self::Output {
247 /// Scalar(self.0 ^ rhs.0)
251 /// assert_eq!(Scalar(true) ^ Scalar(true), Scalar(false));
252 /// assert_eq!(Scalar(true) ^ Scalar(false), Scalar(true));
253 /// assert_eq!(Scalar(false) ^ Scalar(true), Scalar(true));
254 /// assert_eq!(Scalar(false) ^ Scalar(false), Scalar(false));
257 /// An implementation of `BitXor` trait for a wrapper around `Vec<bool>`.
260 /// use std::ops::BitXor;
262 /// #[derive(Debug, PartialEq)]
263 /// struct BooleanVector(Vec<bool>);
265 /// impl BitXor for BooleanVector {
266 /// type Output = Self;
268 /// fn bitxor(self, BooleanVector(rhs): Self) -> Self::Output {
269 /// let BooleanVector(lhs) = self;
270 /// assert_eq!(lhs.len(), rhs.len());
271 /// BooleanVector(lhs.iter()
273 /// .map(|(x, y)| (*x || *y) && !(*x && *y))
278 /// let bv1 = BooleanVector(vec![true, true, false, false]);
279 /// let bv2 = BooleanVector(vec![true, false, true, false]);
280 /// let expected = BooleanVector(vec![false, true, true, false]);
281 /// assert_eq!(bv1 ^ bv2, expected);
285 #[stable(feature = "rust1", since = "1.0.0")]
286 #[rustc_on_unimplemented(message="no implementation for `{Self} ^ {Rhs}`",
287 label="no implementation for `{Self} ^ {Rhs}`")]
288 pub trait BitXor<Rhs=Self> {
289 /// The resulting type after applying the `^` operator.
290 #[stable(feature = "rust1", since = "1.0.0")]
293 /// Performs the `^` operation.
295 #[stable(feature = "rust1", since = "1.0.0")]
296 fn bitxor(self, rhs: Rhs) -> Self::Output;
299 macro_rules! bitxor_impl {
301 #[stable(feature = "rust1", since = "1.0.0")]
306 fn bitxor(self, other: $t) -> $t { self ^ other }
309 forward_ref_binop! { impl BitXor, bitxor for $t, $t }
313 bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
315 /// The left shift operator `<<`. Note that because this trait is implemented
316 /// for all integer types with multiple right-hand-side types, Rust's type
317 /// checker has special handling for `_ << _`, setting the result type for
318 /// integer operations to the type of the left-hand-side operand. This means
319 /// that though `a << b` and `a.shl(b)` are one and the same from an evaluation
320 /// standpoint, they are different when it comes to type inference.
324 /// An implementation of `Shl` that lifts the `<<` operation on integers to a
325 /// wrapper around `usize`.
328 /// use std::ops::Shl;
330 /// #[derive(PartialEq, Debug)]
331 /// struct Scalar(usize);
333 /// impl Shl<Scalar> for Scalar {
334 /// type Output = Self;
336 /// fn shl(self, Scalar(rhs): Self) -> Scalar {
337 /// let Scalar(lhs) = self;
338 /// Scalar(lhs << rhs)
342 /// assert_eq!(Scalar(4) << Scalar(2), Scalar(16));
345 /// An implementation of `Shl` that spins a vector leftward by a given amount.
348 /// use std::ops::Shl;
350 /// #[derive(PartialEq, Debug)]
351 /// struct SpinVector<T: Clone> {
355 /// impl<T: Clone> Shl<usize> for SpinVector<T> {
356 /// type Output = Self;
358 /// fn shl(self, rhs: usize) -> Self::Output {
359 /// // Rotate the vector by `rhs` places.
360 /// let (a, b) = self.vec.split_at(rhs);
361 /// let mut spun_vector: Vec<T> = vec![];
362 /// spun_vector.extend_from_slice(b);
363 /// spun_vector.extend_from_slice(a);
364 /// SpinVector { vec: spun_vector }
368 /// assert_eq!(SpinVector { vec: vec![0, 1, 2, 3, 4] } << 2,
369 /// SpinVector { vec: vec![2, 3, 4, 0, 1] });
373 #[stable(feature = "rust1", since = "1.0.0")]
374 #[rustc_on_unimplemented(message="no implementation for `{Self} << {Rhs}`",
375 label="no implementation for `{Self} << {Rhs}`")]
376 pub trait Shl<Rhs=Self> {
377 /// The resulting type after applying the `<<` operator.
378 #[stable(feature = "rust1", since = "1.0.0")]
381 /// Performs the `<<` operation.
383 #[stable(feature = "rust1", since = "1.0.0")]
384 fn shl(self, rhs: Rhs) -> Self::Output;
387 macro_rules! shl_impl {
389 #[stable(feature = "rust1", since = "1.0.0")]
390 impl Shl<$f> for $t {
394 #[rustc_inherit_overflow_checks]
395 fn shl(self, other: $f) -> $t {
400 forward_ref_binop! { impl Shl, shl for $t, $f }
404 macro_rules! shl_impl_all {
407 shl_impl! { $t, u16 }
408 shl_impl! { $t, u32 }
409 shl_impl! { $t, u64 }
410 shl_impl! { $t, u128 }
411 shl_impl! { $t, usize }
414 shl_impl! { $t, i16 }
415 shl_impl! { $t, i32 }
416 shl_impl! { $t, i64 }
417 shl_impl! { $t, i128 }
418 shl_impl! { $t, isize }
422 shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 }
424 /// The right shift operator `>>`. Note that because this trait is implemented
425 /// for all integer types with multiple right-hand-side types, Rust's type
426 /// checker has special handling for `_ >> _`, setting the result type for
427 /// integer operations to the type of the left-hand-side operand. This means
428 /// that though `a >> b` and `a.shr(b)` are one and the same from an evaluation
429 /// standpoint, they are different when it comes to type inference.
433 /// An implementation of `Shr` that lifts the `>>` operation on integers to a
434 /// wrapper around `usize`.
437 /// use std::ops::Shr;
439 /// #[derive(PartialEq, Debug)]
440 /// struct Scalar(usize);
442 /// impl Shr<Scalar> for Scalar {
443 /// type Output = Self;
445 /// fn shr(self, Scalar(rhs): Self) -> Scalar {
446 /// let Scalar(lhs) = self;
447 /// Scalar(lhs >> rhs)
451 /// assert_eq!(Scalar(16) >> Scalar(2), Scalar(4));
454 /// An implementation of `Shr` that spins a vector rightward by a given amount.
457 /// use std::ops::Shr;
459 /// #[derive(PartialEq, Debug)]
460 /// struct SpinVector<T: Clone> {
464 /// impl<T: Clone> Shr<usize> for SpinVector<T> {
465 /// type Output = Self;
467 /// fn shr(self, rhs: usize) -> Self::Output {
468 /// // Rotate the vector by `rhs` places.
469 /// let (a, b) = self.vec.split_at(self.vec.len() - rhs);
470 /// let mut spun_vector: Vec<T> = vec![];
471 /// spun_vector.extend_from_slice(b);
472 /// spun_vector.extend_from_slice(a);
473 /// SpinVector { vec: spun_vector }
477 /// assert_eq!(SpinVector { vec: vec![0, 1, 2, 3, 4] } >> 2,
478 /// SpinVector { vec: vec![3, 4, 0, 1, 2] });
482 #[stable(feature = "rust1", since = "1.0.0")]
483 #[rustc_on_unimplemented(message="no implementation for `{Self} >> {Rhs}`",
484 label="no implementation for `{Self} >> {Rhs}`")]
485 pub trait Shr<Rhs=Self> {
486 /// The resulting type after applying the `>>` operator.
487 #[stable(feature = "rust1", since = "1.0.0")]
490 /// Performs the `>>` operation.
492 #[stable(feature = "rust1", since = "1.0.0")]
493 fn shr(self, rhs: Rhs) -> Self::Output;
496 macro_rules! shr_impl {
498 #[stable(feature = "rust1", since = "1.0.0")]
499 impl Shr<$f> for $t {
503 #[rustc_inherit_overflow_checks]
504 fn shr(self, other: $f) -> $t {
509 forward_ref_binop! { impl Shr, shr for $t, $f }
513 macro_rules! shr_impl_all {
516 shr_impl! { $t, u16 }
517 shr_impl! { $t, u32 }
518 shr_impl! { $t, u64 }
519 shr_impl! { $t, u128 }
520 shr_impl! { $t, usize }
523 shr_impl! { $t, i16 }
524 shr_impl! { $t, i32 }
525 shr_impl! { $t, i64 }
526 shr_impl! { $t, i128 }
527 shr_impl! { $t, isize }
531 shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
533 /// The bitwise AND assignment operator `&=`.
537 /// An implementation of `BitAndAssign` that lifts the `&=` operator to a
538 /// wrapper around `bool`.
541 /// use std::ops::BitAndAssign;
543 /// #[derive(Debug, PartialEq)]
544 /// struct Scalar(bool);
546 /// impl BitAndAssign for Scalar {
547 /// // rhs is the "right-hand side" of the expression `a &= b`
548 /// fn bitand_assign(&mut self, rhs: Self) {
549 /// *self = Scalar(self.0 & rhs.0)
553 /// let mut scalar = Scalar(true);
554 /// scalar &= Scalar(true);
555 /// assert_eq!(scalar, Scalar(true));
557 /// let mut scalar = Scalar(true);
558 /// scalar &= Scalar(false);
559 /// assert_eq!(scalar, Scalar(false));
561 /// let mut scalar = Scalar(false);
562 /// scalar &= Scalar(true);
563 /// assert_eq!(scalar, Scalar(false));
565 /// let mut scalar = Scalar(false);
566 /// scalar &= Scalar(false);
567 /// assert_eq!(scalar, Scalar(false));
570 /// Here, the `BitAndAssign` trait is implemented for a wrapper around
574 /// use std::ops::BitAndAssign;
576 /// #[derive(Debug, PartialEq)]
577 /// struct BooleanVector(Vec<bool>);
579 /// impl BitAndAssign for BooleanVector {
580 /// // `rhs` is the "right-hand side" of the expression `a &= b`.
581 /// fn bitand_assign(&mut self, rhs: Self) {
582 /// assert_eq!(self.0.len(), rhs.0.len());
583 /// *self = BooleanVector(self.0
585 /// .zip(rhs.0.iter())
586 /// .map(|(x, y)| *x && *y)
591 /// let mut bv = BooleanVector(vec![true, true, false, false]);
592 /// bv &= BooleanVector(vec![true, false, true, false]);
593 /// let expected = BooleanVector(vec![true, false, false, false]);
594 /// assert_eq!(bv, expected);
596 #[lang = "bitand_assign"]
598 #[stable(feature = "op_assign_traits", since = "1.8.0")]
599 #[rustc_on_unimplemented(message="no implementation for `{Self} &= {Rhs}`",
600 label="no implementation for `{Self} &= {Rhs}`")]
601 pub trait BitAndAssign<Rhs=Self> {
602 /// Performs the `&=` operation.
603 #[stable(feature = "op_assign_traits", since = "1.8.0")]
604 fn bitand_assign(&mut self, rhs: Rhs);
607 macro_rules! bitand_assign_impl {
609 #[stable(feature = "op_assign_traits", since = "1.8.0")]
610 impl BitAndAssign for $t {
612 fn bitand_assign(&mut self, other: $t) { *self &= other }
615 forward_ref_op_assign! { impl BitAndAssign, bitand_assign for $t, $t }
619 bitand_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
621 /// The bitwise OR assignment operator `|=`.
626 /// use std::ops::BitOrAssign;
628 /// #[derive(Debug, PartialEq)]
629 /// struct PersonalPreferences {
630 /// likes_cats: bool,
631 /// likes_dogs: bool,
634 /// impl BitOrAssign for PersonalPreferences {
635 /// fn bitor_assign(&mut self, rhs: Self) {
636 /// self.likes_cats |= rhs.likes_cats;
637 /// self.likes_dogs |= rhs.likes_dogs;
641 /// let mut prefs = PersonalPreferences { likes_cats: true, likes_dogs: false };
642 /// prefs |= PersonalPreferences { likes_cats: false, likes_dogs: true };
643 /// assert_eq!(prefs, PersonalPreferences { likes_cats: true, likes_dogs: true });
645 #[lang = "bitor_assign"]
647 #[stable(feature = "op_assign_traits", since = "1.8.0")]
648 #[rustc_on_unimplemented(message="no implementation for `{Self} |= {Rhs}`",
649 label="no implementation for `{Self} |= {Rhs}`")]
650 pub trait BitOrAssign<Rhs=Self> {
651 /// Performs the `|=` operation.
652 #[stable(feature = "op_assign_traits", since = "1.8.0")]
653 fn bitor_assign(&mut self, rhs: Rhs);
656 macro_rules! bitor_assign_impl {
658 #[stable(feature = "op_assign_traits", since = "1.8.0")]
659 impl BitOrAssign for $t {
661 fn bitor_assign(&mut self, other: $t) { *self |= other }
664 forward_ref_op_assign! { impl BitOrAssign, bitor_assign for $t, $t }
668 bitor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
670 /// The bitwise XOR assignment operator `^=`.
675 /// use std::ops::BitXorAssign;
677 /// #[derive(Debug, PartialEq)]
678 /// struct Personality {
680 /// likes_knitting: bool,
683 /// impl BitXorAssign for Personality {
684 /// fn bitxor_assign(&mut self, rhs: Self) {
685 /// self.has_soul ^= rhs.has_soul;
686 /// self.likes_knitting ^= rhs.likes_knitting;
690 /// let mut personality = Personality { has_soul: false, likes_knitting: true };
691 /// personality ^= Personality { has_soul: true, likes_knitting: true };
692 /// assert_eq!(personality, Personality { has_soul: true, likes_knitting: false});
694 #[lang = "bitxor_assign"]
696 #[stable(feature = "op_assign_traits", since = "1.8.0")]
697 #[rustc_on_unimplemented(message="no implementation for `{Self} ^= {Rhs}`",
698 label="no implementation for `{Self} ^= {Rhs}`")]
699 pub trait BitXorAssign<Rhs=Self> {
700 /// Performs the `^=` operation.
701 #[stable(feature = "op_assign_traits", since = "1.8.0")]
702 fn bitxor_assign(&mut self, rhs: Rhs);
705 macro_rules! bitxor_assign_impl {
707 #[stable(feature = "op_assign_traits", since = "1.8.0")]
708 impl BitXorAssign for $t {
710 fn bitxor_assign(&mut self, other: $t) { *self ^= other }
713 forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for $t, $t }
717 bitxor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
719 /// The left shift assignment operator `<<=`.
723 /// An implementation of `ShlAssign` for a wrapper around `usize`.
726 /// use std::ops::ShlAssign;
728 /// #[derive(Debug, PartialEq)]
729 /// struct Scalar(usize);
731 /// impl ShlAssign<usize> for Scalar {
732 /// fn shl_assign(&mut self, rhs: usize) {
737 /// let mut scalar = Scalar(4);
739 /// assert_eq!(scalar, Scalar(16));
741 #[lang = "shl_assign"]
742 #[doc(alias = "<<=")]
743 #[stable(feature = "op_assign_traits", since = "1.8.0")]
744 #[rustc_on_unimplemented(message="no implementation for `{Self} <<= {Rhs}`",
745 label="no implementation for `{Self} <<= {Rhs}`")]
746 pub trait ShlAssign<Rhs=Self> {
747 /// Performs the `<<=` operation.
748 #[stable(feature = "op_assign_traits", since = "1.8.0")]
749 fn shl_assign(&mut self, rhs: Rhs);
752 macro_rules! shl_assign_impl {
754 #[stable(feature = "op_assign_traits", since = "1.8.0")]
755 impl ShlAssign<$f> for $t {
757 #[rustc_inherit_overflow_checks]
758 fn shl_assign(&mut self, other: $f) {
763 forward_ref_op_assign! { impl ShlAssign, shl_assign for $t, $f }
767 macro_rules! shl_assign_impl_all {
769 shl_assign_impl! { $t, u8 }
770 shl_assign_impl! { $t, u16 }
771 shl_assign_impl! { $t, u32 }
772 shl_assign_impl! { $t, u64 }
773 shl_assign_impl! { $t, u128 }
774 shl_assign_impl! { $t, usize }
776 shl_assign_impl! { $t, i8 }
777 shl_assign_impl! { $t, i16 }
778 shl_assign_impl! { $t, i32 }
779 shl_assign_impl! { $t, i64 }
780 shl_assign_impl! { $t, i128 }
781 shl_assign_impl! { $t, isize }
785 shl_assign_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
787 /// The right shift assignment operator `>>=`.
791 /// An implementation of `ShrAssign` for a wrapper around `usize`.
794 /// use std::ops::ShrAssign;
796 /// #[derive(Debug, PartialEq)]
797 /// struct Scalar(usize);
799 /// impl ShrAssign<usize> for Scalar {
800 /// fn shr_assign(&mut self, rhs: usize) {
805 /// let mut scalar = Scalar(16);
807 /// assert_eq!(scalar, Scalar(4));
809 #[lang = "shr_assign"]
810 #[doc(alias = ">>=")]
811 #[stable(feature = "op_assign_traits", since = "1.8.0")]
812 #[rustc_on_unimplemented(message="no implementation for `{Self} >>= {Rhs}`",
813 label="no implementation for `{Self} >>= {Rhs}`")]
814 pub trait ShrAssign<Rhs=Self> {
815 /// Performs the `>>=` operation.
816 #[stable(feature = "op_assign_traits", since = "1.8.0")]
817 fn shr_assign(&mut self, rhs: Rhs);
820 macro_rules! shr_assign_impl {
822 #[stable(feature = "op_assign_traits", since = "1.8.0")]
823 impl ShrAssign<$f> for $t {
825 #[rustc_inherit_overflow_checks]
826 fn shr_assign(&mut self, other: $f) {
831 forward_ref_op_assign! { impl ShrAssign, shr_assign for $t, $f }
835 macro_rules! shr_assign_impl_all {
837 shr_assign_impl! { $t, u8 }
838 shr_assign_impl! { $t, u16 }
839 shr_assign_impl! { $t, u32 }
840 shr_assign_impl! { $t, u64 }
841 shr_assign_impl! { $t, u128 }
842 shr_assign_impl! { $t, usize }
844 shr_assign_impl! { $t, i8 }
845 shr_assign_impl! { $t, i16 }
846 shr_assign_impl! { $t, i32 }
847 shr_assign_impl! { $t, i64 }
848 shr_assign_impl! { $t, i128 }
849 shr_assign_impl! { $t, isize }
853 shr_assign_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }