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