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