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