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