core/ops/
bit.rs

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