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