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