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

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy