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 }