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