Skip to main content

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#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
34#[doc(alias = "!")]
35pub const trait Not {
36    /// The resulting type after applying the `!` operator.
37    #[stable(feature = "rust1", since = "1.0.0")]
38    type Output;
39
40    /// Performs the unary `!` operation.
41    ///
42    /// # Examples
43    ///
44    /// ```
45    /// assert_eq!(!true, false);
46    /// assert_eq!(!false, true);
47    /// assert_eq!(!1u8, 254);
48    /// assert_eq!(!0u8, 255);
49    /// ```
50    #[must_use]
51    #[stable(feature = "rust1", since = "1.0.0")]
52    fn not(self) -> Self::Output;
53}
54
55macro_rules! not_impl {
56    ($($t:ty)*) => ($(
57        #[stable(feature = "rust1", since = "1.0.0")]
58        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
59        const impl Not for $t {
60            type Output = $t;
61
62            #[inline]
63            fn not(self) -> $t { !self }
64        }
65
66        forward_ref_unop! { impl Not, not for $t,
67        #[stable(feature = "rust1", since = "1.0.0")]
68        #[rustc_const_unstable(feature = "const_ops", issue = "143802")] }
69    )*)
70}
71
72not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
73
74#[stable(feature = "not_never", since = "1.60.0")]
75#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
76const impl Not for ! {
77    type Output = !;
78
79    #[inline]
80    fn not(self) -> ! {
81        match self {}
82    }
83}
84
85/// The bitwise AND operator `&`.
86///
87/// Note that `Rhs` is `Self` by default, but this is not mandatory.
88///
89/// # Examples
90///
91/// An implementation of `BitAnd` for a wrapper around `bool`.
92///
93/// ```
94/// use std::ops::BitAnd;
95///
96/// #[derive(Debug, PartialEq)]
97/// struct Scalar(bool);
98///
99/// impl BitAnd for Scalar {
100///     type Output = Self;
101///
102///     // rhs is the "right-hand side" of the expression `a & b`
103///     fn bitand(self, rhs: Self) -> Self::Output {
104///         Self(self.0 & rhs.0)
105///     }
106/// }
107///
108/// assert_eq!(Scalar(true) & Scalar(true), Scalar(true));
109/// assert_eq!(Scalar(true) & Scalar(false), Scalar(false));
110/// assert_eq!(Scalar(false) & Scalar(true), Scalar(false));
111/// assert_eq!(Scalar(false) & Scalar(false), Scalar(false));
112/// ```
113///
114/// An implementation of `BitAnd` for a wrapper around `Vec<bool>`.
115///
116/// ```
117/// use std::ops::BitAnd;
118///
119/// #[derive(Debug, PartialEq)]
120/// struct BooleanVector(Vec<bool>);
121///
122/// impl BitAnd for BooleanVector {
123///     type Output = Self;
124///
125///     fn bitand(self, Self(rhs): Self) -> Self::Output {
126///         let Self(lhs) = self;
127///         assert_eq!(lhs.len(), rhs.len());
128///         Self(
129///             lhs.iter()
130///                 .zip(rhs.iter())
131///                 .map(|(x, y)| *x & *y)
132///                 .collect()
133///         )
134///     }
135/// }
136///
137/// let bv1 = BooleanVector(vec![true, true, false, false]);
138/// let bv2 = BooleanVector(vec![true, false, true, false]);
139/// let expected = BooleanVector(vec![true, false, false, false]);
140/// assert_eq!(bv1 & bv2, expected);
141/// ```
142#[lang = "bitand"]
143#[doc(alias = "&")]
144#[stable(feature = "rust1", since = "1.0.0")]
145#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
146#[diagnostic::on_unimplemented(
147    message = "no implementation for `{Self} & {Rhs}`",
148    label = "no implementation for `{Self} & {Rhs}`"
149)]
150pub const trait BitAnd<Rhs = Self> {
151    /// The resulting type after applying the `&` operator.
152    #[stable(feature = "rust1", since = "1.0.0")]
153    type Output;
154
155    /// Performs the `&` operation.
156    ///
157    /// # Examples
158    ///
159    /// ```
160    /// assert_eq!(true & false, false);
161    /// assert_eq!(true & true, true);
162    /// assert_eq!(5u8 & 1u8, 1);
163    /// assert_eq!(5u8 & 2u8, 0);
164    /// ```
165    #[must_use]
166    #[stable(feature = "rust1", since = "1.0.0")]
167    fn bitand(self, rhs: Rhs) -> Self::Output;
168}
169
170macro_rules! bitand_impl {
171    ($($t:ty)*) => ($(
172        #[stable(feature = "rust1", since = "1.0.0")]
173        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
174        const impl BitAnd for $t {
175            type Output = $t;
176
177            #[inline]
178            fn bitand(self, rhs: $t) -> $t { self & rhs }
179        }
180
181        forward_ref_binop! { impl BitAnd, bitand for $t, $t,
182        #[stable(feature = "rust1", since = "1.0.0")]
183        #[rustc_const_unstable(feature = "const_ops", issue = "143802")] }
184    )*)
185}
186
187bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
188
189/// The bitwise OR operator `|`.
190///
191/// Note that `Rhs` is `Self` by default, but this is not mandatory.
192///
193/// # Examples
194///
195/// An implementation of `BitOr` for a wrapper around `bool`.
196///
197/// ```
198/// use std::ops::BitOr;
199///
200/// #[derive(Debug, PartialEq)]
201/// struct Scalar(bool);
202///
203/// impl BitOr for Scalar {
204///     type Output = Self;
205///
206///     // rhs is the "right-hand side" of the expression `a | b`
207///     fn bitor(self, rhs: Self) -> Self::Output {
208///         Self(self.0 | rhs.0)
209///     }
210/// }
211///
212/// assert_eq!(Scalar(true) | Scalar(true), Scalar(true));
213/// assert_eq!(Scalar(true) | Scalar(false), Scalar(true));
214/// assert_eq!(Scalar(false) | Scalar(true), Scalar(true));
215/// assert_eq!(Scalar(false) | Scalar(false), Scalar(false));
216/// ```
217///
218/// An implementation of `BitOr` for a wrapper around `Vec<bool>`.
219///
220/// ```
221/// use std::ops::BitOr;
222///
223/// #[derive(Debug, PartialEq)]
224/// struct BooleanVector(Vec<bool>);
225///
226/// impl BitOr for BooleanVector {
227///     type Output = Self;
228///
229///     fn bitor(self, Self(rhs): Self) -> Self::Output {
230///         let Self(lhs) = self;
231///         assert_eq!(lhs.len(), rhs.len());
232///         Self(
233///             lhs.iter()
234///                 .zip(rhs.iter())
235///                 .map(|(x, y)| *x | *y)
236///                 .collect()
237///         )
238///     }
239/// }
240///
241/// let bv1 = BooleanVector(vec![true, true, false, false]);
242/// let bv2 = BooleanVector(vec![true, false, true, false]);
243/// let expected = BooleanVector(vec![true, true, true, false]);
244/// assert_eq!(bv1 | bv2, expected);
245/// ```
246#[lang = "bitor"]
247#[doc(alias = "|")]
248#[stable(feature = "rust1", since = "1.0.0")]
249#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
250#[diagnostic::on_unimplemented(
251    message = "no implementation for `{Self} | {Rhs}`",
252    label = "no implementation for `{Self} | {Rhs}`"
253)]
254pub const trait BitOr<Rhs = Self> {
255    /// The resulting type after applying the `|` operator.
256    #[stable(feature = "rust1", since = "1.0.0")]
257    type Output;
258
259    /// Performs the `|` operation.
260    ///
261    /// # Examples
262    ///
263    /// ```
264    /// assert_eq!(true | false, true);
265    /// assert_eq!(false | false, false);
266    /// assert_eq!(5u8 | 1u8, 5);
267    /// assert_eq!(5u8 | 2u8, 7);
268    /// ```
269    #[must_use]
270    #[stable(feature = "rust1", since = "1.0.0")]
271    fn bitor(self, rhs: Rhs) -> Self::Output;
272}
273
274macro_rules! bitor_impl {
275    ($($t:ty)*) => ($(
276        #[stable(feature = "rust1", since = "1.0.0")]
277        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
278        const impl BitOr for $t {
279            type Output = $t;
280
281            #[inline]
282            fn bitor(self, rhs: $t) -> $t { self | rhs }
283        }
284
285        forward_ref_binop! { impl BitOr, bitor for $t, $t,
286        #[stable(feature = "rust1", since = "1.0.0")]
287        #[rustc_const_unstable(feature = "const_ops", issue = "143802")] }
288    )*)
289}
290
291bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
292
293/// The bitwise XOR operator `^`.
294///
295/// Note that `Rhs` is `Self` by default, but this is not mandatory.
296///
297/// # Examples
298///
299/// An implementation of `BitXor` that lifts `^` to a wrapper around `bool`.
300///
301/// ```
302/// use std::ops::BitXor;
303///
304/// #[derive(Debug, PartialEq)]
305/// struct Scalar(bool);
306///
307/// impl BitXor for Scalar {
308///     type Output = Self;
309///
310///     // rhs is the "right-hand side" of the expression `a ^ b`
311///     fn bitxor(self, rhs: Self) -> Self::Output {
312///         Self(self.0 ^ rhs.0)
313///     }
314/// }
315///
316/// assert_eq!(Scalar(true) ^ Scalar(true), Scalar(false));
317/// assert_eq!(Scalar(true) ^ Scalar(false), Scalar(true));
318/// assert_eq!(Scalar(false) ^ Scalar(true), Scalar(true));
319/// assert_eq!(Scalar(false) ^ Scalar(false), Scalar(false));
320/// ```
321///
322/// An implementation of `BitXor` trait for a wrapper around `Vec<bool>`.
323///
324/// ```
325/// use std::ops::BitXor;
326///
327/// #[derive(Debug, PartialEq)]
328/// struct BooleanVector(Vec<bool>);
329///
330/// impl BitXor for BooleanVector {
331///     type Output = Self;
332///
333///     fn bitxor(self, Self(rhs): Self) -> Self::Output {
334///         let Self(lhs) = self;
335///         assert_eq!(lhs.len(), rhs.len());
336///         Self(
337///             lhs.iter()
338///                 .zip(rhs.iter())
339///                 .map(|(x, y)| *x ^ *y)
340///                 .collect()
341///         )
342///     }
343/// }
344///
345/// let bv1 = BooleanVector(vec![true, true, false, false]);
346/// let bv2 = BooleanVector(vec![true, false, true, false]);
347/// let expected = BooleanVector(vec![false, true, true, false]);
348/// assert_eq!(bv1 ^ bv2, expected);
349/// ```
350#[lang = "bitxor"]
351#[doc(alias = "^")]
352#[stable(feature = "rust1", since = "1.0.0")]
353#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
354#[diagnostic::on_unimplemented(
355    message = "no implementation for `{Self} ^ {Rhs}`",
356    label = "no implementation for `{Self} ^ {Rhs}`"
357)]
358pub const trait BitXor<Rhs = Self> {
359    /// The resulting type after applying the `^` operator.
360    #[stable(feature = "rust1", since = "1.0.0")]
361    type Output;
362
363    /// Performs the `^` operation.
364    ///
365    /// # Examples
366    ///
367    /// ```
368    /// assert_eq!(true ^ false, true);
369    /// assert_eq!(true ^ true, false);
370    /// assert_eq!(5u8 ^ 1u8, 4);
371    /// assert_eq!(5u8 ^ 2u8, 7);
372    /// ```
373    #[must_use]
374    #[stable(feature = "rust1", since = "1.0.0")]
375    fn bitxor(self, rhs: Rhs) -> Self::Output;
376}
377
378macro_rules! bitxor_impl {
379    ($($t:ty)*) => ($(
380        #[stable(feature = "rust1", since = "1.0.0")]
381        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
382        const impl BitXor for $t {
383            type Output = $t;
384
385            #[inline]
386            fn bitxor(self, other: $t) -> $t { self ^ other }
387        }
388
389        forward_ref_binop! { impl BitXor, bitxor for $t, $t,
390        #[stable(feature = "rust1", since = "1.0.0")]
391        #[rustc_const_unstable(feature = "const_ops", issue = "143802")] }
392    )*)
393}
394
395bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
396
397/// The left shift operator `<<`. Note that because this trait is implemented
398/// for all integer types with multiple right-hand-side types, Rust's type
399/// checker has special handling for `_ << _`, setting the result type for
400/// integer operations to the type of the left-hand-side operand. This means
401/// that though `a << b` and `a.shl(b)` are one and the same from an evaluation
402/// standpoint, they are different when it comes to type inference.
403///
404/// # Examples
405///
406/// An implementation of `Shl` that lifts the `<<` operation on integers to a