]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
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 | ||
54a0048b | 11 | //! Overloadable operators. |
1a4d82fc | 12 | //! |
9e0c209e | 13 | //! Implementing these traits allows you to overload certain operators. |
1a4d82fc | 14 | //! |
85aaf69f | 15 | //! Some of these traits are imported by the prelude, so they are available in |
9e0c209e SL |
16 | //! every Rust program. Only operators backed by traits can be overloaded. For |
17 | //! example, the addition operator (`+`) can be overloaded through the `Add` | |
18 | //! trait, but since the assignment operator (`=`) has no backing trait, there | |
19 | //! is no way of overloading its semantics. Additionally, this module does not | |
20 | //! provide any mechanism to create new operators. If traitless overloading or | |
21 | //! custom operators are required, you should look toward macros or compiler | |
22 | //! plugins to extend Rust's syntax. | |
23 | //! | |
24 | //! Note that the `&&` and `||` operators short-circuit, i.e. they only | |
25 | //! evaluate their second operand if it contributes to the result. Since this | |
26 | //! behavior is not enforceable by traits, `&&` and `||` are not supported as | |
27 | //! overloadable operators. | |
1a4d82fc | 28 | //! |
85aaf69f SL |
29 | //! Many of the operators take their operands by value. In non-generic |
30 | //! contexts involving built-in types, this is usually not a problem. | |
31 | //! However, using these operators in generic code, requires some | |
32 | //! attention if values have to be reused as opposed to letting the operators | |
33 | //! consume them. One option is to occasionally use `clone()`. | |
34 | //! Another option is to rely on the types involved providing additional | |
35 | //! operator implementations for references. For example, for a user-defined | |
36 | //! type `T` which is supposed to support addition, it is probably a good | |
37 | //! idea to have both `T` and `&T` implement the traits `Add<T>` and `Add<&T>` | |
38 | //! so that generic code can be written without unnecessary cloning. | |
39 | //! | |
c34b1796 | 40 | //! # Examples |
1a4d82fc | 41 | //! |
62682a34 SL |
42 | //! This example creates a `Point` struct that implements `Add` and `Sub`, and |
43 | //! then demonstrates adding and subtracting two `Point`s. | |
1a4d82fc JJ |
44 | //! |
45 | //! ```rust | |
1a4d82fc JJ |
46 | //! use std::ops::{Add, Sub}; |
47 | //! | |
85aaf69f | 48 | //! #[derive(Debug)] |
1a4d82fc | 49 | //! struct Point { |
85aaf69f | 50 | //! x: i32, |
9cc50fc6 | 51 | //! y: i32, |
1a4d82fc JJ |
52 | //! } |
53 | //! | |
54 | //! impl Add for Point { | |
55 | //! type Output = Point; | |
56 | //! | |
57 | //! fn add(self, other: Point) -> Point { | |
58 | //! Point {x: self.x + other.x, y: self.y + other.y} | |
59 | //! } | |
60 | //! } | |
61 | //! | |
62 | //! impl Sub for Point { | |
63 | //! type Output = Point; | |
64 | //! | |
65 | //! fn sub(self, other: Point) -> Point { | |
66 | //! Point {x: self.x - other.x, y: self.y - other.y} | |
67 | //! } | |
68 | //! } | |
69 | //! fn main() { | |
70 | //! println!("{:?}", Point {x: 1, y: 0} + Point {x: 2, y: 3}); | |
71 | //! println!("{:?}", Point {x: 1, y: 0} - Point {x: 2, y: 3}); | |
72 | //! } | |
73 | //! ``` | |
74 | //! | |
9e0c209e SL |
75 | //! See the documentation for each trait for an example implementation. |
76 | //! | |
77 | //! The [`Fn`], [`FnMut`], and [`FnOnce`] traits are implemented by types that can be | |
78 | //! invoked like functions. Note that `Fn` takes `&self`, `FnMut` takes `&mut | |
79 | //! self` and `FnOnce` takes `self`. These correspond to the three kinds of | |
80 | //! methods that can be invoked on an instance: call-by-reference, | |
81 | //! call-by-mutable-reference, and call-by-value. The most common use of these | |
82 | //! traits is to act as bounds to higher-level functions that take functions or | |
83 | //! closures as arguments. | |
84 | //! | |
85 | //! [`Fn`]: trait.Fn.html | |
86 | //! [`FnMut`]: trait.FnMut.html | |
87 | //! [`FnOnce`]: trait.FnOnce.html | |
88 | //! | |
89 | //! Taking a `Fn` as a parameter: | |
90 | //! | |
91 | //! ```rust | |
92 | //! fn call_with_one<F>(func: F) -> usize | |
93 | //! where F: Fn(usize) -> usize | |
94 | //! { | |
95 | //! func(1) | |
96 | //! } | |
97 | //! | |
98 | //! let double = |x| x * 2; | |
99 | //! assert_eq!(call_with_one(double), 2); | |
100 | //! ``` | |
101 | //! | |
102 | //! Taking a `FnMut` as a parameter: | |
103 | //! | |
104 | //! ```rust | |
105 | //! fn do_twice<F>(mut func: F) | |
106 | //! where F: FnMut() | |
107 | //! { | |
108 | //! func(); | |
109 | //! func(); | |
110 | //! } | |
111 | //! | |
112 | //! let mut x: usize = 1; | |
113 | //! { | |
114 | //! let add_two_to_x = || x += 2; | |
115 | //! do_twice(add_two_to_x); | |
116 | //! } | |
117 | //! | |
118 | //! assert_eq!(x, 5); | |
119 | //! ``` | |
120 | //! | |
121 | //! Taking a `FnOnce` as a parameter: | |
122 | //! | |
123 | //! ```rust | |
124 | //! fn consume_with_relish<F>(func: F) | |
125 | //! where F: FnOnce() -> String | |
126 | //! { | |
127 | //! // `func` consumes its captured variables, so it cannot be run more | |
128 | //! // than once | |
129 | //! println!("Consumed: {}", func()); | |
130 | //! | |
131 | //! println!("Delicious!"); | |
132 | //! | |
133 | //! // Attempting to invoke `func()` again will throw a `use of moved | |
134 | //! // value` error for `func` | |
135 | //! } | |
136 | //! | |
137 | //! let x = String::from("x"); | |
138 | //! let consume_and_return_x = move || x; | |
139 | //! consume_with_relish(consume_and_return_x); | |
140 | //! | |
141 | //! // `consume_and_return_x` can no longer be invoked at this point | |
142 | //! ``` | |
1a4d82fc | 143 | |
85aaf69f | 144 | #![stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 145 | |
1a4d82fc | 146 | use fmt; |
9e0c209e | 147 | use marker::Unsize; |
1a4d82fc | 148 | |
62682a34 SL |
149 | /// The `Drop` trait is used to run some code when a value goes out of scope. |
150 | /// This is sometimes called a 'destructor'. | |
1a4d82fc | 151 | /// |
c34b1796 | 152 | /// # Examples |
1a4d82fc | 153 | /// |
62682a34 SL |
154 | /// A trivial implementation of `Drop`. The `drop` method is called when `_x` |
155 | /// goes out of scope, and therefore `main` prints `Dropping!`. | |
1a4d82fc | 156 | /// |
c34b1796 | 157 | /// ``` |
1a4d82fc JJ |
158 | /// struct HasDrop; |
159 | /// | |
160 | /// impl Drop for HasDrop { | |
161 | /// fn drop(&mut self) { | |
162 | /// println!("Dropping!"); | |
163 | /// } | |
164 | /// } | |
165 | /// | |
166 | /// fn main() { | |
167 | /// let _x = HasDrop; | |
168 | /// } | |
169 | /// ``` | |
d9579d0f | 170 | #[lang = "drop"] |
85aaf69f | 171 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 172 | pub trait Drop { |
b039eaaf | 173 | /// A method called when the value goes out of scope. |
9cc50fc6 SL |
174 | /// |
175 | /// When this method has been called, `self` has not yet been deallocated. | |
176 | /// If it were, `self` would be a dangling reference. | |
177 | /// | |
178 | /// After this function is over, the memory of `self` will be deallocated. | |
179 | /// | |
9e0c209e SL |
180 | /// This function cannot be called explicitly. This is compiler error |
181 | /// [0040]. However, the [`std::mem::drop`] function in the prelude can be | |
182 | /// used to call the argument's `Drop` implementation. | |
183 | /// | |
184 | /// [0040]: https://doc.rust-lang.org/error-index.html#E0040 | |
185 | /// [`std::mem::drop`]: https://doc.rust-lang.org/std/mem/fn.drop.html | |
186 | /// | |
9cc50fc6 SL |
187 | /// # Panics |
188 | /// | |
189 | /// Given that a `panic!` will call `drop()` as it unwinds, any `panic!` in | |
190 | /// a `drop()` implementation will likely abort. | |
85aaf69f | 191 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
192 | fn drop(&mut self); |
193 | } | |
194 | ||
85aaf69f SL |
195 | // implements the unary operator "op &T" |
196 | // based on "op T" where T is expected to be `Copy`able | |
197 | macro_rules! forward_ref_unop { | |
198 | (impl $imp:ident, $method:ident for $t:ty) => { | |
62682a34 | 199 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
200 | impl<'a> $imp for &'a $t { |
201 | type Output = <$t as $imp>::Output; | |
202 | ||
203 | #[inline] | |
204 | fn $method(self) -> <$t as $imp>::Output { | |
205 | $imp::$method(*self) | |
206 | } | |
207 | } | |
208 | } | |
209 | } | |
210 | ||
211 | // implements binary operators "&T op U", "T op &U", "&T op &U" | |
212 | // based on "T op U" where T and U are expected to be `Copy`able | |
213 | macro_rules! forward_ref_binop { | |
214 | (impl $imp:ident, $method:ident for $t:ty, $u:ty) => { | |
62682a34 | 215 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
216 | impl<'a> $imp<$u> for &'a $t { |
217 | type Output = <$t as $imp<$u>>::Output; | |
218 | ||
219 | #[inline] | |
220 | fn $method(self, other: $u) -> <$t as $imp<$u>>::Output { | |
221 | $imp::$method(*self, other) | |
222 | } | |
223 | } | |
224 | ||
62682a34 | 225 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
226 | impl<'a> $imp<&'a $u> for $t { |
227 | type Output = <$t as $imp<$u>>::Output; | |
228 | ||
229 | #[inline] | |
230 | fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output { | |
231 | $imp::$method(self, *other) | |
232 | } | |
233 | } | |
234 | ||
62682a34 | 235 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
236 | impl<'a, 'b> $imp<&'a $u> for &'b $t { |
237 | type Output = <$t as $imp<$u>>::Output; | |
238 | ||
239 | #[inline] | |
240 | fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output { | |
241 | $imp::$method(*self, *other) | |
242 | } | |
243 | } | |
244 | } | |
245 | } | |
246 | ||
1a4d82fc JJ |
247 | /// The `Add` trait is used to specify the functionality of `+`. |
248 | /// | |
c34b1796 | 249 | /// # Examples |
1a4d82fc | 250 | /// |
9e0c209e SL |
251 | /// This example creates a `Point` struct that implements the `Add` trait, and |
252 | /// then demonstrates adding two `Point`s. | |
1a4d82fc | 253 | /// |
c34b1796 | 254 | /// ``` |
1a4d82fc JJ |
255 | /// use std::ops::Add; |
256 | /// | |
9e0c209e SL |
257 | /// #[derive(Debug)] |
258 | /// struct Point { | |
259 | /// x: i32, | |
260 | /// y: i32, | |
261 | /// } | |
1a4d82fc | 262 | /// |
9e0c209e SL |
263 | /// impl Add for Point { |
264 | /// type Output = Point; | |
1a4d82fc | 265 | /// |
9e0c209e SL |
266 | /// fn add(self, other: Point) -> Point { |
267 | /// Point { | |
268 | /// x: self.x + other.x, | |
269 | /// y: self.y + other.y, | |
270 | /// } | |
271 | /// } | |
272 | /// } | |
273 | /// | |
274 | /// impl PartialEq for Point { | |
275 | /// fn eq(&self, other: &Self) -> bool { | |
276 | /// self.x == other.x && self.y == other.y | |
9346a6ac | 277 | /// } |
1a4d82fc JJ |
278 | /// } |
279 | /// | |
280 | /// fn main() { | |
9e0c209e SL |
281 | /// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 }, |
282 | /// Point { x: 3, y: 3 }); | |
1a4d82fc JJ |
283 | /// } |
284 | /// ``` | |
9e0c209e SL |
285 | /// |
286 | /// Note that `RHS = Self` by default, but this is not mandatory. For example, | |
287 | /// [std::time::SystemTime] implements `Add<Duration>`, which permits | |
288 | /// operations of the form `SystemTime = SystemTime + Duration`. | |
289 | /// | |
290 | /// [std::time::SystemTime]: ../../std/time/struct.SystemTime.html | |
d9579d0f | 291 | #[lang = "add"] |
85aaf69f | 292 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 293 | pub trait Add<RHS=Self> { |
c34b1796 | 294 | /// The resulting type after applying the `+` operator |
85aaf69f | 295 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
296 | type Output; |
297 | ||
298 | /// The method for the `+` operator | |
85aaf69f | 299 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
300 | fn add(self, rhs: RHS) -> Self::Output; |
301 | } | |
302 | ||
303 | macro_rules! add_impl { | |
304 | ($($t:ty)*) => ($( | |
85aaf69f | 305 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
306 | impl Add for $t { |
307 | type Output = $t; | |
308 | ||
309 | #[inline] | |
3157f602 | 310 | #[rustc_inherit_overflow_checks] |
1a4d82fc JJ |
311 | fn add(self, other: $t) -> $t { self + other } |
312 | } | |
85aaf69f SL |
313 | |
314 | forward_ref_binop! { impl Add, add for $t, $t } | |
1a4d82fc JJ |
315 | )*) |
316 | } | |
317 | ||
85aaf69f | 318 | add_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } |
1a4d82fc JJ |
319 | |
320 | /// The `Sub` trait is used to specify the functionality of `-`. | |
321 | /// | |
c34b1796 | 322 | /// # Examples |
1a4d82fc | 323 | /// |
9e0c209e SL |
324 | /// This example creates a `Point` struct that implements the `Sub` trait, and |
325 | /// then demonstrates subtracting two `Point`s. | |
1a4d82fc | 326 | /// |
c34b1796 | 327 | /// ``` |
1a4d82fc JJ |
328 | /// use std::ops::Sub; |
329 | /// | |
9e0c209e SL |
330 | /// #[derive(Debug)] |
331 | /// struct Point { | |
332 | /// x: i32, | |
333 | /// y: i32, | |
334 | /// } | |
1a4d82fc | 335 | /// |
9e0c209e SL |
336 | /// impl Sub for Point { |
337 | /// type Output = Point; | |
1a4d82fc | 338 | /// |
9e0c209e SL |
339 | /// fn sub(self, other: Point) -> Point { |
340 | /// Point { | |
341 | /// x: self.x - other.x, | |
342 | /// y: self.y - other.y, | |
343 | /// } | |
344 | /// } | |
345 | /// } | |
346 | /// | |
347 | /// impl PartialEq for Point { | |
348 | /// fn eq(&self, other: &Self) -> bool { | |
349 | /// self.x == other.x && self.y == other.y | |
1a4d82fc JJ |
350 | /// } |
351 | /// } | |
352 | /// | |
353 | /// fn main() { | |
9e0c209e SL |
354 | /// assert_eq!(Point { x: 3, y: 3 } - Point { x: 2, y: 3 }, |
355 | /// Point { x: 1, y: 0 }); | |
1a4d82fc JJ |
356 | /// } |
357 | /// ``` | |
9e0c209e SL |
358 | /// |
359 | /// Note that `RHS = Self` by default, but this is not mandatory. For example, | |
360 | /// [std::time::SystemTime] implements `Sub<Duration>`, which permits | |
361 | /// operations of the form `SystemTime = SystemTime - Duration`. | |
362 | /// | |
363 | /// [std::time::SystemTime]: ../../std/time/struct.SystemTime.html | |
d9579d0f | 364 | #[lang = "sub"] |
85aaf69f | 365 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 366 | pub trait Sub<RHS=Self> { |
c34b1796 | 367 | /// The resulting type after applying the `-` operator |
85aaf69f | 368 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
369 | type Output; |
370 | ||
371 | /// The method for the `-` operator | |
85aaf69f | 372 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
373 | fn sub(self, rhs: RHS) -> Self::Output; |
374 | } | |
375 | ||
376 | macro_rules! sub_impl { | |
377 | ($($t:ty)*) => ($( | |
85aaf69f | 378 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
379 | impl Sub for $t { |
380 | type Output = $t; | |
381 | ||
382 | #[inline] | |
3157f602 | 383 | #[rustc_inherit_overflow_checks] |
1a4d82fc JJ |
384 | fn sub(self, other: $t) -> $t { self - other } |
385 | } | |
85aaf69f SL |
386 | |
387 | forward_ref_binop! { impl Sub, sub for $t, $t } | |
1a4d82fc JJ |
388 | )*) |
389 | } | |
390 | ||
85aaf69f | 391 | sub_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } |
1a4d82fc JJ |
392 | |
393 | /// The `Mul` trait is used to specify the functionality of `*`. | |
394 | /// | |
c34b1796 | 395 | /// # Examples |
1a4d82fc | 396 | /// |
9e0c209e | 397 | /// Implementing a `Mul`tipliable rational number struct: |
1a4d82fc | 398 | /// |
c34b1796 | 399 | /// ``` |
1a4d82fc JJ |
400 | /// use std::ops::Mul; |
401 | /// | |
9e0c209e SL |
402 | /// // The uniqueness of rational numbers in lowest terms is a consequence of |
403 | /// // the fundamental theorem of arithmetic. | |
404 | /// #[derive(Eq)] | |
405 | /// #[derive(PartialEq, Debug)] | |
406 | /// struct Rational { | |
407 | /// nominator: usize, | |
408 | /// denominator: usize, | |
409 | /// } | |
410 | /// | |
411 | /// impl Rational { | |
412 | /// fn new(nominator: usize, denominator: usize) -> Self { | |
413 | /// if denominator == 0 { | |
414 | /// panic!("Zero is an invalid denominator!"); | |
415 | /// } | |
416 | /// | |
417 | /// // Reduce to lowest terms by dividing by the greatest common | |
418 | /// // divisor. | |
419 | /// let gcd = gcd(nominator, denominator); | |
420 | /// Rational { | |
421 | /// nominator: nominator / gcd, | |
422 | /// denominator: denominator / gcd, | |
423 | /// } | |
424 | /// } | |
425 | /// } | |
1a4d82fc | 426 | /// |
9e0c209e SL |
427 | /// impl Mul for Rational { |
428 | /// // The multiplication of rational numbers is a closed operation. | |
429 | /// type Output = Self; | |
1a4d82fc | 430 | /// |
9e0c209e SL |
431 | /// fn mul(self, rhs: Self) -> Self { |
432 | /// let nominator = self.nominator * rhs.nominator; | |
433 | /// let denominator = self.denominator * rhs.denominator; | |
434 | /// Rational::new(nominator, denominator) | |
1a4d82fc JJ |
435 | /// } |
436 | /// } | |
437 | /// | |
9e0c209e SL |
438 | /// // Euclid's two-thousand-year-old algorithm for finding the greatest common |
439 | /// // divisor. | |
440 | /// fn gcd(x: usize, y: usize) -> usize { | |
441 | /// let mut x = x; | |
442 | /// let mut y = y; | |
443 | /// while y != 0 { | |
444 | /// let t = y; | |
445 | /// y = x % y; | |
446 | /// x = t; | |
447 | /// } | |
448 | /// x | |
449 | /// } | |
450 | /// | |
451 | /// assert_eq!(Rational::new(1, 2), Rational::new(2, 4)); | |
452 | /// assert_eq!(Rational::new(2, 3) * Rational::new(3, 4), | |
453 | /// Rational::new(1, 2)); | |
454 | /// ``` | |
455 | /// | |
456 | /// Note that `RHS = Self` by default, but this is not mandatory. Here is an | |
457 | /// implementation which enables multiplication of vectors by scalars, as is | |
458 | /// done in linear algebra. | |
459 | /// | |
460 | /// ``` | |
461 | /// use std::ops::Mul; | |
462 | /// | |
463 | /// struct Scalar {value: usize}; | |
464 | /// | |
465 | /// #[derive(Debug)] | |
466 | /// struct Vector {value: Vec<usize>}; | |
467 | /// | |
468 | /// impl Mul<Vector> for Scalar { | |
469 | /// type Output = Vector; | |
470 | /// | |
471 | /// fn mul(self, rhs: Vector) -> Vector { | |
472 | /// Vector {value: rhs.value.iter().map(|v| self.value * v).collect()} | |
473 | /// } | |
1a4d82fc | 474 | /// } |
9e0c209e SL |
475 | /// |
476 | /// impl PartialEq<Vector> for Vector { | |
477 | /// fn eq(&self, other: &Self) -> bool { | |
478 | /// self.value == other.value | |
479 | /// } | |
480 | /// } | |
481 | /// | |
482 | /// let scalar = Scalar{value: 3}; | |
483 | /// let vector = Vector{value: vec![2, 4, 6]}; | |
484 | /// assert_eq!(scalar * vector, Vector{value: vec![6, 12, 18]}); | |
1a4d82fc | 485 | /// ``` |
d9579d0f | 486 | #[lang = "mul"] |
85aaf69f | 487 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 488 | pub trait Mul<RHS=Self> { |
c34b1796 | 489 | /// The resulting type after applying the `*` operator |
85aaf69f | 490 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
491 | type Output; |
492 | ||
493 | /// The method for the `*` operator | |
85aaf69f | 494 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
495 | fn mul(self, rhs: RHS) -> Self::Output; |
496 | } | |
497 | ||
498 | macro_rules! mul_impl { | |
499 | ($($t:ty)*) => ($( | |
85aaf69f | 500 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
501 | impl Mul for $t { |
502 | type Output = $t; | |
503 | ||
504 | #[inline] | |
3157f602 | 505 | #[rustc_inherit_overflow_checks] |
1a4d82fc JJ |
506 | fn mul(self, other: $t) -> $t { self * other } |
507 | } | |
85aaf69f SL |
508 | |
509 | forward_ref_binop! { impl Mul, mul for $t, $t } | |
1a4d82fc JJ |
510 | )*) |
511 | } | |
512 | ||
85aaf69f | 513 | mul_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } |
1a4d82fc JJ |
514 | |
515 | /// The `Div` trait is used to specify the functionality of `/`. | |
516 | /// | |
c34b1796 | 517 | /// # Examples |
1a4d82fc | 518 | /// |
9e0c209e | 519 | /// Implementing a `Div`idable rational number struct: |
1a4d82fc JJ |
520 | /// |
521 | /// ``` | |
1a4d82fc JJ |
522 | /// use std::ops::Div; |
523 | /// | |
9e0c209e SL |
524 | /// // The uniqueness of rational numbers in lowest terms is a consequence of |
525 | /// // the fundamental theorem of arithmetic. | |
526 | /// #[derive(Eq)] | |
527 | /// #[derive(PartialEq, Debug)] | |
528 | /// struct Rational { | |
529 | /// nominator: usize, | |
530 | /// denominator: usize, | |
531 | /// } | |
532 | /// | |
533 | /// impl Rational { | |
534 | /// fn new(nominator: usize, denominator: usize) -> Self { | |
535 | /// if denominator == 0 { | |
536 | /// panic!("Zero is an invalid denominator!"); | |
537 | /// } | |
538 | /// | |
539 | /// // Reduce to lowest terms by dividing by the greatest common | |
540 | /// // divisor. | |
541 | /// let gcd = gcd(nominator, denominator); | |
542 | /// Rational { | |
543 | /// nominator: nominator / gcd, | |
544 | /// denominator: denominator / gcd, | |
545 | /// } | |
546 | /// } | |
547 | /// } | |
1a4d82fc | 548 | /// |
9e0c209e SL |
549 | /// impl Div for Rational { |
550 | /// // The division of rational numbers is a closed operation. | |
551 | /// type Output = Self; | |
1a4d82fc | 552 | /// |
9e0c209e SL |
553 | /// fn div(self, rhs: Self) -> Self { |
554 | /// if rhs.nominator == 0 { | |
555 | /// panic!("Cannot divide by zero-valued `Rational`!"); | |
556 | /// } | |
557 | /// | |
558 | /// let nominator = self.nominator * rhs.denominator; | |
559 | /// let denominator = self.denominator * rhs.nominator; | |
560 | /// Rational::new(nominator, denominator) | |
1a4d82fc JJ |
561 | /// } |
562 | /// } | |
563 | /// | |
9e0c209e SL |
564 | /// // Euclid's two-thousand-year-old algorithm for finding the greatest common |
565 | /// // divisor. | |
566 | /// fn gcd(x: usize, y: usize) -> usize { | |
567 | /// let mut x = x; | |
568 | /// let mut y = y; | |
569 | /// while y != 0 { | |
570 | /// let t = y; | |
571 | /// y = x % y; | |
572 | /// x = t; | |
573 | /// } | |
574 | /// x | |
575 | /// } | |
576 | /// | |
1a4d82fc | 577 | /// fn main() { |
9e0c209e SL |
578 | /// assert_eq!(Rational::new(1, 2), Rational::new(2, 4)); |
579 | /// assert_eq!(Rational::new(1, 2) / Rational::new(3, 4), | |
580 | /// Rational::new(2, 3)); | |
1a4d82fc JJ |
581 | /// } |
582 | /// ``` | |
9e0c209e SL |
583 | /// |
584 | /// Note that `RHS = Self` by default, but this is not mandatory. Here is an | |
585 | /// implementation which enables division of vectors by scalars, as is done in | |
586 | /// linear algebra. | |
587 | /// | |
588 | /// ``` | |
589 | /// use std::ops::Div; | |
590 | /// | |
591 | /// struct Scalar {value: f32}; | |
592 | /// | |
593 | /// #[derive(Debug)] | |
594 | /// struct Vector {value: Vec<f32>}; | |
595 | /// | |
596 | /// impl Div<Scalar> for Vector { | |
597 | /// type Output = Vector; | |
598 | /// | |
599 | /// fn div(self, rhs: Scalar) -> Vector { | |
600 | /// Vector {value: self.value.iter().map(|v| v / rhs.value).collect()} | |
601 | /// } | |
602 | /// } | |
603 | /// | |
604 | /// impl PartialEq<Vector> for Vector { | |
605 | /// fn eq(&self, other: &Self) -> bool { | |
606 | /// self.value == other.value | |
607 | /// } | |
608 | /// } | |
609 | /// | |
610 | /// let scalar = Scalar{value: 2f32}; | |
611 | /// let vector = Vector{value: vec![2f32, 4f32, 6f32]}; | |
612 | /// assert_eq!(vector / scalar, Vector{value: vec![1f32, 2f32, 3f32]}); | |
613 | /// ``` | |
d9579d0f | 614 | #[lang = "div"] |
85aaf69f | 615 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 616 | pub trait Div<RHS=Self> { |
c34b1796 | 617 | /// The resulting type after applying the `/` operator |
85aaf69f | 618 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
619 | type Output; |
620 | ||
621 | /// The method for the `/` operator | |
85aaf69f | 622 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
623 | fn div(self, rhs: RHS) -> Self::Output; |
624 | } | |
625 | ||
c1a9b12d | 626 | macro_rules! div_impl_integer { |
1a4d82fc | 627 | ($($t:ty)*) => ($( |
c1a9b12d SL |
628 | /// This operation rounds towards zero, truncating any |
629 | /// fractional part of the exact result. | |
85aaf69f | 630 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
631 | impl Div for $t { |
632 | type Output = $t; | |
633 | ||
634 | #[inline] | |
635 | fn div(self, other: $t) -> $t { self / other } | |
636 | } | |
85aaf69f SL |
637 | |
638 | forward_ref_binop! { impl Div, div for $t, $t } | |
1a4d82fc JJ |
639 | )*) |
640 | } | |
641 | ||
c1a9b12d SL |
642 | div_impl_integer! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } |
643 | ||
644 | macro_rules! div_impl_float { | |
645 | ($($t:ty)*) => ($( | |
646 | #[stable(feature = "rust1", since = "1.0.0")] | |
647 | impl Div for $t { | |
648 | type Output = $t; | |
649 | ||
650 | #[inline] | |
651 | fn div(self, other: $t) -> $t { self / other } | |
652 | } | |
653 | ||
654 | forward_ref_binop! { impl Div, div for $t, $t } | |
655 | )*) | |
656 | } | |
657 | ||
658 | div_impl_float! { f32 f64 } | |
1a4d82fc JJ |
659 | |
660 | /// The `Rem` trait is used to specify the functionality of `%`. | |
661 | /// | |
c34b1796 | 662 | /// # Examples |
1a4d82fc | 663 | /// |
9e0c209e SL |
664 | /// This example implements `Rem` on a `SplitSlice` object. After `Rem` is |
665 | /// implemented, one can use the `%` operator to find out what the remaining | |
666 | /// elements of the slice would be after splitting it into equal slices of a | |
667 | /// given length. | |
1a4d82fc JJ |
668 | /// |
669 | /// ``` | |
1a4d82fc JJ |
670 | /// use std::ops::Rem; |
671 | /// | |
9e0c209e SL |
672 | /// #[derive(PartialEq, Debug)] |
673 | /// struct SplitSlice<'a, T: 'a> { | |
674 | /// slice: &'a [T], | |
675 | /// } | |
1a4d82fc | 676 | /// |
9e0c209e SL |
677 | /// impl<'a, T> Rem<usize> for SplitSlice<'a, T> { |
678 | /// type Output = SplitSlice<'a, T>; | |
1a4d82fc | 679 | /// |
9e0c209e SL |
680 | /// fn rem(self, modulus: usize) -> Self { |
681 | /// let len = self.slice.len(); | |
682 | /// let rem = len % modulus; | |
683 | /// let start = len - rem; | |
684 | /// SplitSlice {slice: &self.slice[start..]} | |
1a4d82fc JJ |
685 | /// } |
686 | /// } | |
687 | /// | |
9e0c209e SL |
688 | /// // If we were to divide &[0, 1, 2, 3, 4, 5, 6, 7] into slices of size 3, |
689 | /// // the remainder would be &[6, 7] | |
690 | /// assert_eq!(SplitSlice { slice: &[0, 1, 2, 3, 4, 5, 6, 7] } % 3, | |
691 | /// SplitSlice { slice: &[6, 7] }); | |
1a4d82fc | 692 | /// ``` |
d9579d0f | 693 | #[lang = "rem"] |
85aaf69f | 694 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 695 | pub trait Rem<RHS=Self> { |
c34b1796 | 696 | /// The resulting type after applying the `%` operator |
85aaf69f | 697 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
698 | type Output = Self; |
699 | ||
700 | /// The method for the `%` operator | |
85aaf69f | 701 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
702 | fn rem(self, rhs: RHS) -> Self::Output; |
703 | } | |
704 | ||
e9174d1e | 705 | macro_rules! rem_impl_integer { |
1a4d82fc | 706 | ($($t:ty)*) => ($( |
c1a9b12d SL |
707 | /// This operation satisfies `n % d == n - (n / d) * d`. The |
708 | /// result has the same sign as the left operand. | |
85aaf69f | 709 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
710 | impl Rem for $t { |
711 | type Output = $t; | |
712 | ||
713 | #[inline] | |
714 | fn rem(self, other: $t) -> $t { self % other } | |
715 | } | |
85aaf69f SL |
716 | |
717 | forward_ref_binop! { impl Rem, rem for $t, $t } | |
1a4d82fc JJ |
718 | )*) |
719 | } | |
720 | ||
e9174d1e SL |
721 | rem_impl_integer! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } |
722 | ||
e9174d1e SL |
723 | macro_rules! rem_impl_float { |
724 | ($($t:ty)*) => ($( | |
725 | #[stable(feature = "rust1", since = "1.0.0")] | |
726 | impl Rem for $t { | |
727 | type Output = $t; | |
728 | ||
729 | #[inline] | |
730 | fn rem(self, other: $t) -> $t { self % other } | |
731 | } | |
732 | ||
733 | forward_ref_binop! { impl Rem, rem for $t, $t } | |
734 | )*) | |
735 | } | |
736 | ||
e9174d1e | 737 | rem_impl_float! { f32 f64 } |
1a4d82fc | 738 | |
1a4d82fc JJ |
739 | /// The `Neg` trait is used to specify the functionality of unary `-`. |
740 | /// | |
c34b1796 | 741 | /// # Examples |
1a4d82fc | 742 | /// |
9e0c209e SL |
743 | /// An implementation of `Neg` for `Sign`, which allows the use of `-` to |
744 | /// negate its value. | |
1a4d82fc JJ |
745 | /// |
746 | /// ``` | |
1a4d82fc JJ |
747 | /// use std::ops::Neg; |
748 | /// | |
9e0c209e SL |
749 | /// #[derive(Debug, PartialEq)] |
750 | /// enum Sign { | |
751 | /// Negative, | |
752 | /// Zero, | |
753 | /// Positive, | |
754 | /// } | |
1a4d82fc | 755 | /// |
9e0c209e SL |
756 | /// impl Neg for Sign { |
757 | /// type Output = Sign; | |
1a4d82fc | 758 | /// |
9e0c209e SL |
759 | /// fn neg(self) -> Sign { |
760 | /// match self { | |
761 | /// Sign::Negative => Sign::Positive, | |
762 | /// Sign::Zero => Sign::Zero, | |
763 | /// Sign::Positive => Sign::Negative, | |
764 | /// } | |
1a4d82fc JJ |
765 | /// } |
766 | /// } | |
767 | /// | |
9e0c209e SL |
768 | /// // a negative positive is a negative |
769 | /// assert_eq!(-Sign::Positive, Sign::Negative); | |
770 | /// // a double negative is a positive | |
771 | /// assert_eq!(-Sign::Negative, Sign::Positive); | |
772 | /// // zero is its own negation | |
773 | /// assert_eq!(-Sign::Zero, Sign::Zero); | |
1a4d82fc | 774 | /// ``` |
d9579d0f | 775 | #[lang = "neg"] |
85aaf69f | 776 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 777 | pub trait Neg { |
c34b1796 | 778 | /// The resulting type after applying the `-` operator |
85aaf69f | 779 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
780 | type Output; |
781 | ||
782 | /// The method for the unary `-` operator | |
85aaf69f | 783 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
784 | fn neg(self) -> Self::Output; |
785 | } | |
786 | ||
c34b1796 AL |
787 | |
788 | ||
789 | macro_rules! neg_impl_core { | |
790 | ($id:ident => $body:expr, $($t:ty)*) => ($( | |
85aaf69f | 791 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 792 | impl Neg for $t { |
1a4d82fc JJ |
793 | type Output = $t; |
794 | ||
795 | #[inline] | |
3157f602 | 796 | #[rustc_inherit_overflow_checks] |
c34b1796 | 797 | fn neg(self) -> $t { let $id = self; $body } |
1a4d82fc | 798 | } |
85aaf69f SL |
799 | |
800 | forward_ref_unop! { impl Neg, neg for $t } | |
1a4d82fc JJ |
801 | )*) |
802 | } | |
803 | ||
c34b1796 AL |
804 | macro_rules! neg_impl_numeric { |
805 | ($($t:ty)*) => { neg_impl_core!{ x => -x, $($t)*} } | |
1a4d82fc JJ |
806 | } |
807 | ||
c34b1796 AL |
808 | macro_rules! neg_impl_unsigned { |
809 | ($($t:ty)*) => { | |
810 | neg_impl_core!{ x => { | |
c34b1796 AL |
811 | !x.wrapping_add(1) |
812 | }, $($t)*} } | |
813 | } | |
1a4d82fc | 814 | |
c34b1796 AL |
815 | // neg_impl_unsigned! { usize u8 u16 u32 u64 } |
816 | neg_impl_numeric! { isize i8 i16 i32 i64 f32 f64 } | |
1a4d82fc JJ |
817 | |
818 | /// The `Not` trait is used to specify the functionality of unary `!`. | |
819 | /// | |
c34b1796 | 820 | /// # Examples |
1a4d82fc | 821 | /// |
9e0c209e SL |
822 | /// An implementation of `Not` for `Answer`, which enables the use of `!` to |
823 | /// invert its value. | |
1a4d82fc JJ |
824 | /// |
825 | /// ``` | |
1a4d82fc JJ |
826 | /// use std::ops::Not; |
827 | /// | |
9e0c209e SL |
828 | /// #[derive(Debug, PartialEq)] |
829 | /// enum Answer { | |
830 | /// Yes, | |
831 | /// No, | |
832 | /// } | |
1a4d82fc | 833 | /// |
9e0c209e SL |
834 | /// impl Not for Answer { |
835 | /// type Output = Answer; | |
1a4d82fc | 836 | /// |
9e0c209e SL |
837 | /// fn not(self) -> Answer { |
838 | /// match self { | |
839 | /// Answer::Yes => Answer::No, | |
840 | /// Answer::No => Answer::Yes | |
841 | /// } | |
1a4d82fc JJ |
842 | /// } |
843 | /// } | |
844 | /// | |
9e0c209e SL |
845 | /// assert_eq!(!Answer::Yes, Answer::No); |
846 | /// assert_eq!(!Answer::No, Answer::Yes); | |
1a4d82fc | 847 | /// ``` |
d9579d0f | 848 | #[lang = "not"] |
85aaf69f | 849 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 850 | pub trait Not { |
c34b1796 | 851 | /// The resulting type after applying the `!` operator |
85aaf69f | 852 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
853 | type Output; |
854 | ||
855 | /// The method for the unary `!` operator | |
85aaf69f | 856 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
857 | fn not(self) -> Self::Output; |
858 | } | |
859 | ||
860 | macro_rules! not_impl { | |
861 | ($($t:ty)*) => ($( | |
85aaf69f | 862 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
863 | impl Not for $t { |
864 | type Output = $t; | |
865 | ||
866 | #[inline] | |
867 | fn not(self) -> $t { !self } | |
868 | } | |
85aaf69f SL |
869 | |
870 | forward_ref_unop! { impl Not, not for $t } | |
1a4d82fc JJ |
871 | )*) |
872 | } | |
873 | ||
85aaf69f | 874 | not_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 } |
1a4d82fc JJ |
875 | |
876 | /// The `BitAnd` trait is used to specify the functionality of `&`. | |
877 | /// | |
c34b1796 | 878 | /// # Examples |
1a4d82fc | 879 | /// |
9e0c209e | 880 | /// In this example, the `&` operator is lifted to a trivial `Scalar` type. |
1a4d82fc JJ |
881 | /// |
882 | /// ``` | |
1a4d82fc JJ |
883 | /// use std::ops::BitAnd; |
884 | /// | |
9e0c209e SL |
885 | /// #[derive(Debug, PartialEq)] |
886 | /// struct Scalar(bool); | |
1a4d82fc | 887 | /// |
9e0c209e SL |
888 | /// impl BitAnd for Scalar { |
889 | /// type Output = Self; | |
1a4d82fc | 890 | /// |
9e0c209e SL |
891 | /// // rhs is the "right-hand side" of the expression `a & b` |
892 | /// fn bitand(self, rhs: Self) -> Self { | |
893 | /// Scalar(self.0 & rhs.0) | |
894 | /// } | |
895 | /// } | |
896 | /// | |
897 | /// fn main() { | |
898 | /// assert_eq!(Scalar(true) & Scalar(true), Scalar(true)); | |
899 | /// assert_eq!(Scalar(true) & Scalar(false), Scalar(false)); | |
900 | /// assert_eq!(Scalar(false) & Scalar(true), Scalar(false)); | |
901 | /// assert_eq!(Scalar(false) & Scalar(false), Scalar(false)); | |
902 | /// } | |
903 | /// ``` | |
904 | /// | |
905 | /// In this example, the `BitAnd` trait is implemented for a `BooleanVector` | |
906 | /// struct. | |
907 | /// | |
908 | /// ``` | |
909 | /// use std::ops::BitAnd; | |
910 | /// | |
911 | /// #[derive(Debug, PartialEq)] | |
912 | /// struct BooleanVector(Vec<bool>); | |
913 | /// | |
914 | /// impl BitAnd for BooleanVector { | |
915 | /// type Output = Self; | |
916 | /// | |
917 | /// fn bitand(self, BooleanVector(rhs): Self) -> Self { | |
918 | /// let BooleanVector(lhs) = self; | |
919 | /// assert_eq!(lhs.len(), rhs.len()); | |
920 | /// BooleanVector(lhs.iter().zip(rhs.iter()).map(|(x, y)| *x && *y).collect()) | |
1a4d82fc JJ |
921 | /// } |
922 | /// } | |
923 | /// | |
924 | /// fn main() { | |
9e0c209e SL |
925 | /// let bv1 = BooleanVector(vec![true, true, false, false]); |
926 | /// let bv2 = BooleanVector(vec![true, false, true, false]); | |
927 | /// let expected = BooleanVector(vec![true, false, false, false]); | |
928 | /// assert_eq!(bv1 & bv2, expected); | |
1a4d82fc JJ |
929 | /// } |
930 | /// ``` | |
d9579d0f | 931 | #[lang = "bitand"] |
85aaf69f | 932 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 933 | pub trait BitAnd<RHS=Self> { |
c34b1796 | 934 | /// The resulting type after applying the `&` operator |
85aaf69f | 935 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
936 | type Output; |
937 | ||
938 | /// The method for the `&` operator | |
85aaf69f | 939 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
940 | fn bitand(self, rhs: RHS) -> Self::Output; |
941 | } | |
942 | ||
943 | macro_rules! bitand_impl { | |
944 | ($($t:ty)*) => ($( | |
85aaf69f | 945 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
946 | impl BitAnd for $t { |
947 | type Output = $t; | |
948 | ||
949 | #[inline] | |
950 | fn bitand(self, rhs: $t) -> $t { self & rhs } | |
951 | } | |
85aaf69f SL |
952 | |
953 | forward_ref_binop! { impl BitAnd, bitand for $t, $t } | |
1a4d82fc JJ |
954 | )*) |
955 | } | |
956 | ||
85aaf69f | 957 | bitand_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 } |
1a4d82fc JJ |
958 | |
959 | /// The `BitOr` trait is used to specify the functionality of `|`. | |
960 | /// | |
c34b1796 | 961 | /// # Examples |
1a4d82fc | 962 | /// |
9e0c209e | 963 | /// In this example, the `|` operator is lifted to a trivial `Scalar` type. |
1a4d82fc JJ |
964 | /// |
965 | /// ``` | |
1a4d82fc JJ |
966 | /// use std::ops::BitOr; |
967 | /// | |
9e0c209e SL |
968 | /// #[derive(Debug, PartialEq)] |
969 | /// struct Scalar(bool); | |
1a4d82fc | 970 | /// |
9e0c209e SL |
971 | /// impl BitOr for Scalar { |
972 | /// type Output = Self; | |
1a4d82fc | 973 | /// |
9e0c209e SL |
974 | /// // rhs is the "right-hand side" of the expression `a | b` |
975 | /// fn bitor(self, rhs: Self) -> Self { | |
976 | /// Scalar(self.0 | rhs.0) | |
977 | /// } | |
978 | /// } | |
979 | /// | |
980 | /// fn main() { | |
981 | /// assert_eq!(Scalar(true) | Scalar(true), Scalar(true)); | |
982 | /// assert_eq!(Scalar(true) | Scalar(false), Scalar(true)); | |
983 | /// assert_eq!(Scalar(false) | Scalar(true), Scalar(true)); | |
984 | /// assert_eq!(Scalar(false) | Scalar(false), Scalar(false)); | |
985 | /// } | |
986 | /// ``` | |
987 | /// | |
988 | /// In this example, the `BitOr` trait is implemented for a `BooleanVector` | |
989 | /// struct. | |
990 | /// | |
991 | /// ``` | |
992 | /// use std::ops::BitOr; | |
993 | /// | |
994 | /// #[derive(Debug, PartialEq)] | |
995 | /// struct BooleanVector(Vec<bool>); | |
996 | /// | |
997 | /// impl BitOr for BooleanVector { | |
998 | /// type Output = Self; | |
999 | /// | |
1000 | /// fn bitor(self, BooleanVector(rhs): Self) -> Self { | |
1001 | /// let BooleanVector(lhs) = self; | |
1002 | /// assert_eq!(lhs.len(), rhs.len()); | |
1003 | /// BooleanVector(lhs.iter().zip(rhs.iter()).map(|(x, y)| *x || *y).collect()) | |
1a4d82fc JJ |
1004 | /// } |
1005 | /// } | |
1006 | /// | |
1007 | /// fn main() { | |
9e0c209e SL |
1008 | /// let bv1 = BooleanVector(vec![true, true, false, false]); |
1009 | /// let bv2 = BooleanVector(vec![true, false, true, false]); | |
1010 | /// let expected = BooleanVector(vec![true, true, true, false]); | |
1011 | /// assert_eq!(bv1 | bv2, expected); | |
1a4d82fc JJ |
1012 | /// } |
1013 | /// ``` | |
d9579d0f | 1014 | #[lang = "bitor"] |
85aaf69f | 1015 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 1016 | pub trait BitOr<RHS=Self> { |
c34b1796 | 1017 | /// The resulting type after applying the `|` operator |
85aaf69f | 1018 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
1019 | type Output; |
1020 | ||
1021 | /// The method for the `|` operator | |
85aaf69f | 1022 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
1023 | fn bitor(self, rhs: RHS) -> Self::Output; |
1024 | } | |
1025 | ||
1026 | macro_rules! bitor_impl { | |
1027 | ($($t:ty)*) => ($( | |
85aaf69f | 1028 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
1029 | impl BitOr for $t { |
1030 | type Output = $t; | |
1031 | ||
1032 | #[inline] | |
1033 | fn bitor(self, rhs: $t) -> $t { self | rhs } | |
1034 | } | |
85aaf69f SL |
1035 | |
1036 | forward_ref_binop! { impl BitOr, bitor for $t, $t } | |
1a4d82fc JJ |
1037 | )*) |
1038 | } | |
1039 | ||
85aaf69f | 1040 | bitor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 } |
1a4d82fc JJ |
1041 | |
1042 | /// The `BitXor` trait is used to specify the functionality of `^`. | |
1043 | /// | |
c34b1796 | 1044 | /// # Examples |
1a4d82fc | 1045 | /// |
9e0c209e | 1046 | /// In this example, the `^` operator is lifted to a trivial `Scalar` type. |
1a4d82fc JJ |
1047 | /// |
1048 | /// ``` | |
1a4d82fc JJ |
1049 | /// use std::ops::BitXor; |
1050 | /// | |
9e0c209e SL |
1051 | /// #[derive(Debug, PartialEq)] |
1052 | /// struct Scalar(bool); | |
1a4d82fc | 1053 | /// |
9e0c209e SL |
1054 | /// impl BitXor for Scalar { |
1055 | /// type Output = Self; | |
1a4d82fc | 1056 | /// |
9e0c209e SL |
1057 | /// // rhs is the "right-hand side" of the expression `a ^ b` |
1058 | /// fn bitxor(self, rhs: Self) -> Self { | |
1059 | /// Scalar(self.0 ^ rhs.0) | |
1a4d82fc JJ |
1060 | /// } |
1061 | /// } | |
1062 | /// | |
1063 | /// fn main() { | |
9e0c209e SL |
1064 | /// assert_eq!(Scalar(true) ^ Scalar(true), Scalar(false)); |
1065 | /// assert_eq!(Scalar(true) ^ Scalar(false), Scalar(true)); | |
1066 | /// assert_eq!(Scalar(false) ^ Scalar(true), Scalar(true)); | |
1067 | /// assert_eq!(Scalar(false) ^ Scalar(false), Scalar(false)); | |
1068 | /// } | |
1069 | /// ``` | |
1070 | /// | |
1071 | /// In this example, the `BitXor` trait is implemented for a `BooleanVector` | |
1072 | /// struct. | |
1073 | /// | |
1074 | /// ``` | |
1075 | /// use std::ops::BitXor; | |
1076 | /// | |
1077 | /// #[derive(Debug, PartialEq)] | |
1078 | /// struct BooleanVector(Vec<bool>); | |
1079 | /// | |
1080 | /// impl BitXor for BooleanVector { | |
1081 | /// type Output = Self; | |
1082 | /// | |
1083 | /// fn bitxor(self, BooleanVector(rhs): Self) -> Self { | |
1084 | /// let BooleanVector(lhs) = self; | |
1085 | /// assert_eq!(lhs.len(), rhs.len()); | |
1086 | /// BooleanVector(lhs.iter() | |
1087 | /// .zip(rhs.iter()) | |
1088 | /// .map(|(x, y)| (*x || *y) && !(*x && *y)) | |
1089 | /// .collect()) | |
1090 | /// } | |
1091 | /// } | |
1092 | /// | |
1093 | /// fn main() { | |
1094 | /// let bv1 = BooleanVector(vec![true, true, false, false]); | |
1095 | /// let bv2 = BooleanVector(vec![true, false, true, false]); | |
1096 | /// let expected = BooleanVector(vec![false, true, true, false]); | |
1097 | /// assert_eq!(bv1 ^ bv2, expected); | |
1a4d82fc JJ |
1098 | /// } |
1099 | /// ``` | |
d9579d0f | 1100 | #[lang = "bitxor"] |
85aaf69f | 1101 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 1102 | pub trait BitXor<RHS=Self> { |
c34b1796 | 1103 | /// The resulting type after applying the `^` operator |
85aaf69f | 1104 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
1105 | type Output; |
1106 | ||
1107 | /// The method for the `^` operator | |
85aaf69f | 1108 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
1109 | fn bitxor(self, rhs: RHS) -> Self::Output; |
1110 | } | |
1111 | ||
1112 | macro_rules! bitxor_impl { | |
1113 | ($($t:ty)*) => ($( | |
85aaf69f | 1114 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
1115 | impl BitXor for $t { |
1116 | type Output = $t; | |
1117 | ||
1118 | #[inline] | |
1119 | fn bitxor(self, other: $t) -> $t { self ^ other } | |
1120 | } | |
85aaf69f SL |
1121 | |
1122 | forward_ref_binop! { impl BitXor, bitxor for $t, $t } | |
1a4d82fc JJ |
1123 | )*) |
1124 | } | |
1125 | ||
85aaf69f | 1126 | bitxor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 } |
1a4d82fc JJ |
1127 | |
1128 | /// The `Shl` trait is used to specify the functionality of `<<`. | |
1129 | /// | |
c34b1796 | 1130 | /// # Examples |
1a4d82fc | 1131 | /// |
9e0c209e SL |
1132 | /// An implementation of `Shl` that lifts the `<<` operation on integers to a |
1133 | /// `Scalar` struct. | |
1a4d82fc JJ |
1134 | /// |
1135 | /// ``` | |
1a4d82fc JJ |
1136 | /// use std::ops::Shl; |
1137 | /// | |
9e0c209e SL |
1138 | /// #[derive(PartialEq, Debug)] |
1139 | /// struct Scalar(usize); | |
1a4d82fc | 1140 | /// |
9e0c209e SL |
1141 | /// impl Shl<Scalar> for Scalar { |
1142 | /// type Output = Self; | |
1a4d82fc | 1143 | /// |
9e0c209e SL |
1144 | /// fn shl(self, Scalar(rhs): Self) -> Scalar { |
1145 | /// let Scalar(lhs) = self; | |
1146 | /// Scalar(lhs << rhs) | |
1147 | /// } | |
1148 | /// } | |
1149 | /// fn main() { | |
1150 | /// assert_eq!(Scalar(4) << Scalar(2), Scalar(16)); | |
1151 | /// } | |
1152 | /// ``` | |
1153 | /// | |
1154 | /// An implementation of `Shl` that spins a vector leftward by a given amount. | |
1155 | /// | |
1156 | /// ``` | |
1157 | /// use std::ops::Shl; | |
1158 | /// | |
1159 | /// #[derive(PartialEq, Debug)] | |
1160 | /// struct SpinVector<T: Clone> { | |
1161 | /// vec: Vec<T>, | |
1162 | /// } | |
1163 | /// | |
1164 | /// impl<T: Clone> Shl<usize> for SpinVector<T> { | |
1165 | /// type Output = Self; | |
1166 | /// | |
1167 | /// fn shl(self, rhs: usize) -> SpinVector<T> { | |
1168 | /// // rotate the vector by `rhs` places | |
1169 | /// let (a, b) = self.vec.split_at(rhs); | |
1170 | /// let mut spun_vector: Vec<T> = vec![]; | |
1171 | /// spun_vector.extend_from_slice(b); | |
1172 | /// spun_vector.extend_from_slice(a); | |
1173 | /// SpinVector { vec: spun_vector } | |
1a4d82fc JJ |
1174 | /// } |
1175 | /// } | |
1176 | /// | |
1177 | /// fn main() { | |
9e0c209e SL |
1178 | /// assert_eq!(SpinVector { vec: vec![0, 1, 2, 3, 4] } << 2, |
1179 | /// SpinVector { vec: vec![2, 3, 4, 0, 1] }); | |
1a4d82fc JJ |
1180 | /// } |
1181 | /// ``` | |
d9579d0f | 1182 | #[lang = "shl"] |
85aaf69f | 1183 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 1184 | pub trait Shl<RHS> { |
c34b1796 | 1185 | /// The resulting type after applying the `<<` operator |
85aaf69f | 1186 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
1187 | type Output; |
1188 | ||
1189 | /// The method for the `<<` operator | |
85aaf69f | 1190 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
1191 | fn shl(self, rhs: RHS) -> Self::Output; |
1192 | } | |
1193 | ||
1194 | macro_rules! shl_impl { | |
85aaf69f SL |
1195 | ($t:ty, $f:ty) => ( |
1196 | #[stable(feature = "rust1", since = "1.0.0")] | |
1197 | impl Shl<$f> for $t { | |
1a4d82fc JJ |
1198 | type Output = $t; |
1199 | ||
1200 | #[inline] | |
3157f602 | 1201 | #[rustc_inherit_overflow_checks] |
85aaf69f | 1202 | fn shl(self, other: $f) -> $t { |
1a4d82fc JJ |
1203 | self << other |
1204 | } | |
1205 | } | |
85aaf69f SL |
1206 | |
1207 | forward_ref_binop! { impl Shl, shl for $t, $f } | |
1208 | ) | |
1209 | } | |
1210 | ||
1211 | macro_rules! shl_impl_all { | |
1212 | ($($t:ty)*) => ($( | |
1213 | shl_impl! { $t, u8 } | |
1214 | shl_impl! { $t, u16 } | |
1215 | shl_impl! { $t, u32 } | |
1216 | shl_impl! { $t, u64 } | |
1217 | shl_impl! { $t, usize } | |
1218 | ||
1219 | shl_impl! { $t, i8 } | |
1220 | shl_impl! { $t, i16 } | |
1221 | shl_impl! { $t, i32 } | |
1222 | shl_impl! { $t, i64 } | |
1223 | shl_impl! { $t, isize } | |
1a4d82fc JJ |
1224 | )*) |
1225 | } | |
1226 | ||
85aaf69f | 1227 | shl_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize } |
1a4d82fc JJ |
1228 | |
1229 | /// The `Shr` trait is used to specify the functionality of `>>`. | |
1230 | /// | |
c34b1796 | 1231 | /// # Examples |
1a4d82fc | 1232 | /// |
9e0c209e SL |
1233 | /// An implementation of `Shr` that lifts the `>>` operation on integers to a |
1234 | /// `Scalar` struct. | |
1a4d82fc JJ |
1235 | /// |
1236 | /// ``` | |
1a4d82fc JJ |
1237 | /// use std::ops::Shr; |
1238 | /// | |
9e0c209e SL |
1239 | /// #[derive(PartialEq, Debug)] |
1240 | /// struct Scalar(usize); | |
1a4d82fc | 1241 | /// |
9e0c209e SL |
1242 | /// impl Shr<Scalar> for Scalar { |
1243 | /// type Output = Self; | |
1a4d82fc | 1244 | /// |
9e0c209e SL |
1245 | /// fn shr(self, Scalar(rhs): Self) -> Scalar { |
1246 | /// let Scalar(lhs) = self; | |
1247 | /// Scalar(lhs >> rhs) | |
1248 | /// } | |
1249 | /// } | |
1250 | /// fn main() { | |
1251 | /// assert_eq!(Scalar(16) >> Scalar(2), Scalar(4)); | |
1252 | /// } | |
1253 | /// ``` | |
1254 | /// | |
1255 | /// An implementation of `Shr` that spins a vector rightward by a given amount. | |
1256 | /// | |
1257 | /// ``` | |
1258 | /// use std::ops::Shr; | |
1259 | /// | |
1260 | /// #[derive(PartialEq, Debug)] | |
1261 | /// struct SpinVector<T: Clone> { | |
1262 | /// vec: Vec<T>, | |
1263 | /// } | |
1264 | /// | |
1265 | /// impl<T: Clone> Shr<usize> for SpinVector<T> { | |
1266 | /// type Output = Self; | |
1267 | /// | |
1268 | /// fn shr(self, rhs: usize) -> SpinVector<T> { | |
1269 | /// // rotate the vector by `rhs` places | |
1270 | /// let (a, b) = self.vec.split_at(self.vec.len() - rhs); | |
1271 | /// let mut spun_vector: Vec<T> = vec![]; | |
1272 | /// spun_vector.extend_from_slice(b); | |
1273 | /// spun_vector.extend_from_slice(a); | |
1274 | /// SpinVector { vec: spun_vector } | |
1a4d82fc JJ |
1275 | /// } |
1276 | /// } | |
1277 | /// | |
1278 | /// fn main() { | |
9e0c209e SL |
1279 | /// assert_eq!(SpinVector { vec: vec![0, 1, 2, 3, 4] } >> 2, |
1280 | /// SpinVector { vec: vec![3, 4, 0, 1, 2] }); | |
1a4d82fc JJ |
1281 | /// } |
1282 | /// ``` | |
d9579d0f | 1283 | #[lang = "shr"] |
85aaf69f | 1284 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 1285 | pub trait Shr<RHS> { |
c34b1796 | 1286 | /// The resulting type after applying the `>>` operator |
85aaf69f | 1287 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
1288 | type Output; |
1289 | ||
1290 | /// The method for the `>>` operator | |
85aaf69f | 1291 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
1292 | fn shr(self, rhs: RHS) -> Self::Output; |
1293 | } | |
1294 | ||
1295 | macro_rules! shr_impl { | |
85aaf69f | 1296 | ($t:ty, $f:ty) => ( |
92a42be0 | 1297 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f | 1298 | impl Shr<$f> for $t { |
1a4d82fc JJ |
1299 | type Output = $t; |
1300 | ||
1301 | #[inline] | |
3157f602 | 1302 | #[rustc_inherit_overflow_checks] |
85aaf69f SL |
1303 | fn shr(self, other: $f) -> $t { |
1304 | self >> other | |
1305 | } | |
1a4d82fc | 1306 | } |
85aaf69f SL |
1307 | |
1308 | forward_ref_binop! { impl Shr, shr for $t, $f } | |
1309 | ) | |
1310 | } | |
1311 | ||
1312 | macro_rules! shr_impl_all { | |
1313 | ($($t:ty)*) => ($( | |
1314 | shr_impl! { $t, u8 } | |
1315 | shr_impl! { $t, u16 } | |
1316 | shr_impl! { $t, u32 } | |
1317 | shr_impl! { $t, u64 } | |
1318 | shr_impl! { $t, usize } | |
1319 | ||
1320 | shr_impl! { $t, i8 } | |
1321 | shr_impl! { $t, i16 } | |
1322 | shr_impl! { $t, i32 } | |
1323 | shr_impl! { $t, i64 } | |
1324 | shr_impl! { $t, isize } | |
1a4d82fc JJ |
1325 | )*) |
1326 | } | |
1327 | ||
85aaf69f | 1328 | shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize } |
1a4d82fc | 1329 | |
b039eaaf SL |
1330 | /// The `AddAssign` trait is used to specify the functionality of `+=`. |
1331 | /// | |
1332 | /// # Examples | |
1333 | /// | |
9e0c209e SL |
1334 | /// This example creates a `Point` struct that implements the `AddAssign` |
1335 | /// trait, and then demonstrates add-assigning to a mutable `Point`. | |
b039eaaf SL |
1336 | /// |
1337 | /// ``` | |
b039eaaf SL |
1338 | /// use std::ops::AddAssign; |
1339 | /// | |
9e0c209e SL |
1340 | /// #[derive(Debug)] |
1341 | /// struct Point { | |
1342 | /// x: i32, | |
1343 | /// y: i32, | |
1344 | /// } | |
b039eaaf | 1345 | /// |
9e0c209e SL |
1346 | /// impl AddAssign for Point { |
1347 | /// fn add_assign(&mut self, other: Point) { | |
1348 | /// *self = Point { | |
1349 | /// x: self.x + other.x, | |
1350 | /// y: self.y + other.y, | |
1351 | /// }; | |
b039eaaf SL |
1352 | /// } |
1353 | /// } | |
1354 | /// | |
9e0c209e SL |
1355 | /// impl PartialEq for Point { |
1356 | /// fn eq(&self, other: &Self) -> bool { | |
1357 | /// self.x == other.x && self.y == other.y | |
1358 | /// } | |
b039eaaf | 1359 | /// } |
9e0c209e SL |
1360 | /// |
1361 | /// let mut point = Point { x: 1, y: 0 }; | |
1362 | /// point += Point { x: 2, y: 3 }; | |
1363 | /// assert_eq!(point, Point { x: 3, y: 3 }); | |
b039eaaf | 1364 | /// ``` |
b039eaaf | 1365 | #[lang = "add_assign"] |
7453a54e | 1366 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1367 | pub trait AddAssign<Rhs=Self> { |
1368 | /// The method for the `+=` operator | |
7453a54e | 1369 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1370 | fn add_assign(&mut self, Rhs); |
1371 | } | |
1372 | ||
b039eaaf SL |
1373 | macro_rules! add_assign_impl { |
1374 | ($($t:ty)+) => ($( | |
7453a54e | 1375 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1376 | impl AddAssign for $t { |
1377 | #[inline] | |
3157f602 | 1378 | #[rustc_inherit_overflow_checks] |
b039eaaf SL |
1379 | fn add_assign(&mut self, other: $t) { *self += other } |
1380 | } | |
1381 | )+) | |
1382 | } | |
1383 | ||
b039eaaf SL |
1384 | add_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } |
1385 | ||
1386 | /// The `SubAssign` trait is used to specify the functionality of `-=`. | |
1387 | /// | |
1388 | /// # Examples | |
1389 | /// | |
9e0c209e SL |
1390 | /// This example creates a `Point` struct that implements the `SubAssign` |
1391 | /// trait, and then demonstrates sub-assigning to a mutable `Point`. | |
b039eaaf SL |
1392 | /// |
1393 | /// ``` | |
b039eaaf SL |
1394 | /// use std::ops::SubAssign; |
1395 | /// | |
9e0c209e SL |
1396 | /// #[derive(Debug)] |
1397 | /// struct Point { | |
1398 | /// x: i32, | |
1399 | /// y: i32, | |
1400 | /// } | |
b039eaaf | 1401 | /// |
9e0c209e SL |
1402 | /// impl SubAssign for Point { |
1403 | /// fn sub_assign(&mut self, other: Point) { | |
1404 | /// *self = Point { | |
1405 | /// x: self.x - other.x, | |
1406 | /// y: self.y - other.y, | |
1407 | /// }; | |
b039eaaf SL |
1408 | /// } |
1409 | /// } | |
1410 | /// | |
9e0c209e SL |
1411 | /// impl PartialEq for Point { |
1412 | /// fn eq(&self, other: &Self) -> bool { | |
1413 | /// self.x == other.x && self.y == other.y | |
1414 | /// } | |
b039eaaf | 1415 | /// } |
9e0c209e SL |
1416 | /// |
1417 | /// let mut point = Point { x: 3, y: 3 }; | |
1418 | /// point -= Point { x: 2, y: 3 }; | |
1419 | /// assert_eq!(point, Point {x: 1, y: 0}); | |
b039eaaf | 1420 | /// ``` |
b039eaaf | 1421 | #[lang = "sub_assign"] |
7453a54e | 1422 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1423 | pub trait SubAssign<Rhs=Self> { |
1424 | /// The method for the `-=` operator | |
7453a54e | 1425 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1426 | fn sub_assign(&mut self, Rhs); |
1427 | } | |
1428 | ||
b039eaaf SL |
1429 | macro_rules! sub_assign_impl { |
1430 | ($($t:ty)+) => ($( | |
7453a54e | 1431 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1432 | impl SubAssign for $t { |
1433 | #[inline] | |
3157f602 | 1434 | #[rustc_inherit_overflow_checks] |
b039eaaf SL |
1435 | fn sub_assign(&mut self, other: $t) { *self -= other } |
1436 | } | |
1437 | )+) | |
1438 | } | |
1439 | ||
b039eaaf SL |
1440 | sub_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } |
1441 | ||
1442 | /// The `MulAssign` trait is used to specify the functionality of `*=`. | |
1443 | /// | |
1444 | /// # Examples | |
1445 | /// | |
1446 | /// A trivial implementation of `MulAssign`. When `Foo *= Foo` happens, it ends up | |
1447 | /// calling `mul_assign`, and therefore, `main` prints `Multiplying!`. | |
1448 | /// | |
1449 | /// ``` | |
b039eaaf SL |
1450 | /// use std::ops::MulAssign; |
1451 | /// | |
b039eaaf SL |
1452 | /// struct Foo; |
1453 | /// | |
1454 | /// impl MulAssign for Foo { | |
1455 | /// fn mul_assign(&mut self, _rhs: Foo) { | |
1456 | /// println!("Multiplying!"); | |
1457 | /// } | |
1458 | /// } | |
1459 | /// | |
92a42be0 | 1460 | /// # #[allow(unused_assignments)] |
b039eaaf SL |
1461 | /// fn main() { |
1462 | /// let mut foo = Foo; | |
1463 | /// foo *= Foo; | |
1464 | /// } | |
1465 | /// ``` | |
b039eaaf | 1466 | #[lang = "mul_assign"] |
7453a54e | 1467 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1468 | pub trait MulAssign<Rhs=Self> { |
1469 | /// The method for the `*=` operator | |
7453a54e | 1470 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1471 | fn mul_assign(&mut self, Rhs); |
1472 | } | |
1473 | ||
b039eaaf SL |
1474 | macro_rules! mul_assign_impl { |
1475 | ($($t:ty)+) => ($( | |
7453a54e | 1476 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1477 | impl MulAssign for $t { |
1478 | #[inline] | |
3157f602 | 1479 | #[rustc_inherit_overflow_checks] |
b039eaaf SL |
1480 | fn mul_assign(&mut self, other: $t) { *self *= other } |
1481 | } | |
1482 | )+) | |
1483 | } | |
1484 | ||
b039eaaf SL |
1485 | mul_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } |
1486 | ||
1487 | /// The `DivAssign` trait is used to specify the functionality of `/=`. | |
1488 | /// | |
1489 | /// # Examples | |
1490 | /// | |
1491 | /// A trivial implementation of `DivAssign`. When `Foo /= Foo` happens, it ends up | |
1492 | /// calling `div_assign`, and therefore, `main` prints `Dividing!`. | |
1493 | /// | |
1494 | /// ``` | |
b039eaaf SL |
1495 | /// use std::ops::DivAssign; |
1496 | /// | |
b039eaaf SL |
1497 | /// struct Foo; |
1498 | /// | |
1499 | /// impl DivAssign for Foo { | |
1500 | /// fn div_assign(&mut self, _rhs: Foo) { | |
1501 | /// println!("Dividing!"); | |
1502 | /// } | |
1503 | /// } | |
1504 | /// | |
92a42be0 | 1505 | /// # #[allow(unused_assignments)] |
b039eaaf SL |
1506 | /// fn main() { |
1507 | /// let mut foo = Foo; | |
1508 | /// foo /= Foo; | |
1509 | /// } | |
1510 | /// ``` | |
b039eaaf | 1511 | #[lang = "div_assign"] |
7453a54e | 1512 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1513 | pub trait DivAssign<Rhs=Self> { |
1514 | /// The method for the `/=` operator | |
7453a54e | 1515 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1516 | fn div_assign(&mut self, Rhs); |
1517 | } | |
1518 | ||
b039eaaf SL |
1519 | macro_rules! div_assign_impl { |
1520 | ($($t:ty)+) => ($( | |
7453a54e | 1521 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1522 | impl DivAssign for $t { |
1523 | #[inline] | |
1524 | fn div_assign(&mut self, other: $t) { *self /= other } | |
1525 | } | |
1526 | )+) | |
1527 | } | |
1528 | ||
b039eaaf SL |
1529 | div_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } |
1530 | ||
1531 | /// The `RemAssign` trait is used to specify the functionality of `%=`. | |
1532 | /// | |
1533 | /// # Examples | |
1534 | /// | |
1535 | /// A trivial implementation of `RemAssign`. When `Foo %= Foo` happens, it ends up | |
1536 | /// calling `rem_assign`, and therefore, `main` prints `Remainder-ing!`. | |
1537 | /// | |
1538 | /// ``` | |
b039eaaf SL |
1539 | /// use std::ops::RemAssign; |
1540 | /// | |
b039eaaf SL |
1541 | /// struct Foo; |
1542 | /// | |
1543 | /// impl RemAssign for Foo { | |
1544 | /// fn rem_assign(&mut self, _rhs: Foo) { | |
1545 | /// println!("Remainder-ing!"); | |
1546 | /// } | |
1547 | /// } | |
1548 | /// | |
92a42be0 | 1549 | /// # #[allow(unused_assignments)] |
b039eaaf SL |
1550 | /// fn main() { |
1551 | /// let mut foo = Foo; | |
1552 | /// foo %= Foo; | |
1553 | /// } | |
1554 | /// ``` | |
b039eaaf | 1555 | #[lang = "rem_assign"] |
7453a54e | 1556 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1557 | pub trait RemAssign<Rhs=Self> { |
1558 | /// The method for the `%=` operator | |
7453a54e | 1559 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1560 | fn rem_assign(&mut self, Rhs); |
1561 | } | |
1562 | ||
b039eaaf SL |
1563 | macro_rules! rem_assign_impl { |
1564 | ($($t:ty)+) => ($( | |
7453a54e | 1565 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1566 | impl RemAssign for $t { |
1567 | #[inline] | |
1568 | fn rem_assign(&mut self, other: $t) { *self %= other } | |
1569 | } | |
1570 | )+) | |
1571 | } | |
1572 | ||
b039eaaf SL |
1573 | rem_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } |
1574 | ||
1575 | /// The `BitAndAssign` trait is used to specify the functionality of `&=`. | |
1576 | /// | |
1577 | /// # Examples | |
1578 | /// | |
9e0c209e | 1579 | /// In this example, the `&=` operator is lifted to a trivial `Scalar` type. |
b039eaaf SL |
1580 | /// |
1581 | /// ``` | |
b039eaaf SL |
1582 | /// use std::ops::BitAndAssign; |
1583 | /// | |
9e0c209e SL |
1584 | /// #[derive(Debug, PartialEq)] |
1585 | /// struct Scalar(bool); | |
b039eaaf | 1586 | /// |
9e0c209e SL |
1587 | /// impl BitAndAssign for Scalar { |
1588 | /// // rhs is the "right-hand side" of the expression `a &= b` | |
1589 | /// fn bitand_assign(&mut self, rhs: Self) { | |
1590 | /// *self = Scalar(self.0 & rhs.0) | |
b039eaaf SL |
1591 | /// } |
1592 | /// } | |
1593 | /// | |
1594 | /// fn main() { | |
9e0c209e SL |
1595 | /// let mut scalar = Scalar(true); |
1596 | /// scalar &= Scalar(true); | |
1597 | /// assert_eq!(scalar, Scalar(true)); | |
1598 | /// | |
1599 | /// let mut scalar = Scalar(true); | |
1600 | /// scalar &= Scalar(false); | |
1601 | /// assert_eq!(scalar, Scalar(false)); | |
1602 | /// | |
1603 | /// let mut scalar = Scalar(false); | |
1604 | /// scalar &= Scalar(true); | |
1605 | /// assert_eq!(scalar, Scalar(false)); | |
1606 | /// | |
1607 | /// let mut scalar = Scalar(false); | |
1608 | /// scalar &= Scalar(false); | |
1609 | /// assert_eq!(scalar, Scalar(false)); | |
1610 | /// } | |
1611 | /// ``` | |
1612 | /// | |
1613 | /// In this example, the `BitAndAssign` trait is implemented for a | |
1614 | /// `BooleanVector` struct. | |
1615 | /// | |
1616 | /// ``` | |
1617 | /// use std::ops::BitAndAssign; | |
1618 | /// | |
1619 | /// #[derive(Debug, PartialEq)] | |
1620 | /// struct BooleanVector(Vec<bool>); | |
1621 | /// | |
1622 | /// impl BitAndAssign for BooleanVector { | |
1623 | /// // rhs is the "right-hand side" of the expression `a &= b` | |
1624 | /// fn bitand_assign(&mut self, rhs: Self) { | |
1625 | /// assert_eq!(self.0.len(), rhs.0.len()); | |
1626 | /// *self = BooleanVector(self.0 | |
1627 | /// .iter() | |
1628 | /// .zip(rhs.0.iter()) | |
1629 | /// .map(|(x, y)| *x && *y) | |
1630 | /// .collect()); | |
1631 | /// } | |
1632 | /// } | |
1633 | /// | |
1634 | /// fn main() { | |
1635 | /// let mut bv = BooleanVector(vec![true, true, false, false]); | |
1636 | /// bv &= BooleanVector(vec![true, false, true, false]); | |
1637 | /// let expected = BooleanVector(vec![true, false, false, false]); | |
1638 | /// assert_eq!(bv, expected); | |
b039eaaf SL |
1639 | /// } |
1640 | /// ``` | |
b039eaaf | 1641 | #[lang = "bitand_assign"] |
7453a54e | 1642 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1643 | pub trait BitAndAssign<Rhs=Self> { |
1644 | /// The method for the `&` operator | |
7453a54e | 1645 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1646 | fn bitand_assign(&mut self, Rhs); |
1647 | } | |
1648 | ||
b039eaaf SL |
1649 | macro_rules! bitand_assign_impl { |
1650 | ($($t:ty)+) => ($( | |
7453a54e | 1651 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1652 | impl BitAndAssign for $t { |
1653 | #[inline] | |
1654 | fn bitand_assign(&mut self, other: $t) { *self &= other } | |
1655 | } | |
1656 | )+) | |
1657 | } | |
1658 | ||
b039eaaf SL |
1659 | bitand_assign_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 } |
1660 | ||
1661 | /// The `BitOrAssign` trait is used to specify the functionality of `|=`. | |
1662 | /// | |
1663 | /// # Examples | |
1664 | /// | |
1665 | /// A trivial implementation of `BitOrAssign`. When `Foo |= Foo` happens, it ends up | |
1666 | /// calling `bitor_assign`, and therefore, `main` prints `Bitwise Or-ing!`. | |
1667 | /// | |
1668 | /// ``` | |
b039eaaf SL |
1669 | /// use std::ops::BitOrAssign; |
1670 | /// | |
b039eaaf SL |
1671 | /// struct Foo; |
1672 | /// | |
1673 | /// impl BitOrAssign for Foo { | |
1674 | /// fn bitor_assign(&mut self, _rhs: Foo) { | |
1675 | /// println!("Bitwise Or-ing!"); | |
1676 | /// } | |
1677 | /// } | |
1678 | /// | |
92a42be0 | 1679 | /// # #[allow(unused_assignments)] |
b039eaaf SL |
1680 | /// fn main() { |
1681 | /// let mut foo = Foo; | |
1682 | /// foo |= Foo; | |
1683 | /// } | |
1684 | /// ``` | |
b039eaaf | 1685 | #[lang = "bitor_assign"] |
7453a54e | 1686 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1687 | pub trait BitOrAssign<Rhs=Self> { |
1688 | /// The method for the `|=` operator | |
7453a54e | 1689 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1690 | fn bitor_assign(&mut self, Rhs); |
1691 | } | |
1692 | ||
b039eaaf SL |
1693 | macro_rules! bitor_assign_impl { |
1694 | ($($t:ty)+) => ($( | |
7453a54e | 1695 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1696 | impl BitOrAssign for $t { |
1697 | #[inline] | |
1698 | fn bitor_assign(&mut self, other: $t) { *self |= other } | |
1699 | } | |
1700 | )+) | |
1701 | } | |
1702 | ||
b039eaaf SL |
1703 | bitor_assign_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 } |
1704 | ||
1705 | /// The `BitXorAssign` trait is used to specify the functionality of `^=`. | |
1706 | /// | |
1707 | /// # Examples | |
1708 | /// | |
1709 | /// A trivial implementation of `BitXorAssign`. When `Foo ^= Foo` happens, it ends up | |
1710 | /// calling `bitxor_assign`, and therefore, `main` prints `Bitwise Xor-ing!`. | |
1711 | /// | |
1712 | /// ``` | |
b039eaaf SL |
1713 | /// use std::ops::BitXorAssign; |
1714 | /// | |
b039eaaf SL |
1715 | /// struct Foo; |
1716 | /// | |
1717 | /// impl BitXorAssign for Foo { | |
1718 | /// fn bitxor_assign(&mut self, _rhs: Foo) { | |
1719 | /// println!("Bitwise Xor-ing!"); | |
1720 | /// } | |
1721 | /// } | |
1722 | /// | |
92a42be0 | 1723 | /// # #[allow(unused_assignments)] |
b039eaaf SL |
1724 | /// fn main() { |
1725 | /// let mut foo = Foo; | |
1726 | /// foo ^= Foo; | |
1727 | /// } | |
1728 | /// ``` | |
b039eaaf | 1729 | #[lang = "bitxor_assign"] |
7453a54e | 1730 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1731 | pub trait BitXorAssign<Rhs=Self> { |
1732 | /// The method for the `^=` operator | |
7453a54e | 1733 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1734 | fn bitxor_assign(&mut self, Rhs); |
1735 | } | |
1736 | ||
b039eaaf SL |
1737 | macro_rules! bitxor_assign_impl { |
1738 | ($($t:ty)+) => ($( | |
7453a54e | 1739 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1740 | impl BitXorAssign for $t { |
1741 | #[inline] | |
1742 | fn bitxor_assign(&mut self, other: $t) { *self ^= other } | |
1743 | } | |
1744 | )+) | |
1745 | } | |
1746 | ||
b039eaaf SL |
1747 | bitxor_assign_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 } |
1748 | ||
1749 | /// The `ShlAssign` trait is used to specify the functionality of `<<=`. | |
1750 | /// | |
1751 | /// # Examples | |
1752 | /// | |
1753 | /// A trivial implementation of `ShlAssign`. When `Foo <<= Foo` happens, it ends up | |
1754 | /// calling `shl_assign`, and therefore, `main` prints `Shifting left!`. | |
1755 | /// | |
1756 | /// ``` | |
b039eaaf SL |
1757 | /// use std::ops::ShlAssign; |
1758 | /// | |
b039eaaf SL |
1759 | /// struct Foo; |
1760 | /// | |
1761 | /// impl ShlAssign<Foo> for Foo { | |
1762 | /// fn shl_assign(&mut self, _rhs: Foo) { | |
1763 | /// println!("Shifting left!"); | |
1764 | /// } | |
1765 | /// } | |
1766 | /// | |
92a42be0 | 1767 | /// # #[allow(unused_assignments)] |
b039eaaf SL |
1768 | /// fn main() { |
1769 | /// let mut foo = Foo; | |
1770 | /// foo <<= Foo; | |
1771 | /// } | |
1772 | /// ``` | |
b039eaaf | 1773 | #[lang = "shl_assign"] |
7453a54e | 1774 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1775 | pub trait ShlAssign<Rhs> { |
1776 | /// The method for the `<<=` operator | |
7453a54e | 1777 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1778 | fn shl_assign(&mut self, Rhs); |
1779 | } | |
1780 | ||
b039eaaf SL |
1781 | macro_rules! shl_assign_impl { |
1782 | ($t:ty, $f:ty) => ( | |
7453a54e | 1783 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1784 | impl ShlAssign<$f> for $t { |
1785 | #[inline] | |
3157f602 | 1786 | #[rustc_inherit_overflow_checks] |
b039eaaf SL |
1787 | fn shl_assign(&mut self, other: $f) { |
1788 | *self <<= other | |
1789 | } | |
1790 | } | |
1791 | ) | |
1792 | } | |
1793 | ||
b039eaaf SL |
1794 | macro_rules! shl_assign_impl_all { |
1795 | ($($t:ty)*) => ($( | |
1796 | shl_assign_impl! { $t, u8 } | |
1797 | shl_assign_impl! { $t, u16 } | |
1798 | shl_assign_impl! { $t, u32 } | |
1799 | shl_assign_impl! { $t, u64 } | |
1800 | shl_assign_impl! { $t, usize } | |
1801 | ||
1802 | shl_assign_impl! { $t, i8 } | |
1803 | shl_assign_impl! { $t, i16 } | |
1804 | shl_assign_impl! { $t, i32 } | |
1805 | shl_assign_impl! { $t, i64 } | |
1806 | shl_assign_impl! { $t, isize } | |
1807 | )*) | |
1808 | } | |
1809 | ||
b039eaaf SL |
1810 | shl_assign_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize } |
1811 | ||
1812 | /// The `ShrAssign` trait is used to specify the functionality of `>>=`. | |
1813 | /// | |
1814 | /// # Examples | |
1815 | /// | |
1816 | /// A trivial implementation of `ShrAssign`. When `Foo >>= Foo` happens, it ends up | |
1817 | /// calling `shr_assign`, and therefore, `main` prints `Shifting right!`. | |
1818 | /// | |
1819 | /// ``` | |
b039eaaf SL |
1820 | /// use std::ops::ShrAssign; |
1821 | /// | |
b039eaaf SL |
1822 | /// struct Foo; |
1823 | /// | |
1824 | /// impl ShrAssign<Foo> for Foo { | |
1825 | /// fn shr_assign(&mut self, _rhs: Foo) { | |
1826 | /// println!("Shifting right!"); | |
1827 | /// } | |
1828 | /// } | |
1829 | /// | |
92a42be0 | 1830 | /// # #[allow(unused_assignments)] |
b039eaaf SL |
1831 | /// fn main() { |
1832 | /// let mut foo = Foo; | |
1833 | /// foo >>= Foo; | |
1834 | /// } | |
1835 | /// ``` | |
b039eaaf | 1836 | #[lang = "shr_assign"] |
7453a54e | 1837 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1838 | pub trait ShrAssign<Rhs=Self> { |
1839 | /// The method for the `>>=` operator | |
7453a54e | 1840 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1841 | fn shr_assign(&mut self, Rhs); |
1842 | } | |
1843 | ||
b039eaaf SL |
1844 | macro_rules! shr_assign_impl { |
1845 | ($t:ty, $f:ty) => ( | |
7453a54e | 1846 | #[stable(feature = "op_assign_traits", since = "1.8.0")] |
b039eaaf SL |
1847 | impl ShrAssign<$f> for $t { |
1848 | #[inline] | |
3157f602 | 1849 | #[rustc_inherit_overflow_checks] |
b039eaaf SL |
1850 | fn shr_assign(&mut self, other: $f) { |
1851 | *self >>= other | |
1852 | } | |
1853 | } | |
1854 | ) | |
1855 | } | |
1856 | ||
b039eaaf SL |
1857 | macro_rules! shr_assign_impl_all { |
1858 | ($($t:ty)*) => ($( | |
1859 | shr_assign_impl! { $t, u8 } | |
1860 | shr_assign_impl! { $t, u16 } | |
1861 | shr_assign_impl! { $t, u32 } | |
1862 | shr_assign_impl! { $t, u64 } | |
1863 | shr_assign_impl! { $t, usize } | |
1864 | ||
1865 | shr_assign_impl! { $t, i8 } | |
1866 | shr_assign_impl! { $t, i16 } | |
1867 | shr_assign_impl! { $t, i32 } | |
1868 | shr_assign_impl! { $t, i64 } | |
1869 | shr_assign_impl! { $t, isize } | |
1870 | )*) | |
1871 | } | |
1872 | ||
b039eaaf SL |
1873 | shr_assign_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize } |
1874 | ||
1a4d82fc JJ |
1875 | /// The `Index` trait is used to specify the functionality of indexing operations |
1876 | /// like `arr[idx]` when used in an immutable context. | |
1877 | /// | |
c34b1796 | 1878 | /// # Examples |
1a4d82fc | 1879 | /// |
9e0c209e SL |
1880 | /// This example implements `Index` on a read-only `NucleotideCount` container, |
1881 | /// enabling individual counts to be retrieved with index syntax. | |
1a4d82fc JJ |
1882 | /// |
1883 | /// ``` | |
1a4d82fc JJ |
1884 | /// use std::ops::Index; |
1885 | /// | |
9e0c209e SL |
1886 | /// enum Nucleotide { |
1887 | /// A, | |
1888 | /// C, | |
1889 | /// G, | |
1890 | /// T, | |
1891 | /// } | |
1a4d82fc | 1892 | /// |
9e0c209e SL |
1893 | /// struct NucleotideCount { |
1894 | /// a: usize, | |
1895 | /// c: usize, | |
1896 | /// g: usize, | |
1897 | /// t: usize, | |
1898 | /// } | |
1a4d82fc | 1899 | /// |
9e0c209e SL |
1900 | /// impl Index<Nucleotide> for NucleotideCount { |
1901 | /// type Output = usize; | |
1902 | /// | |
1903 | /// fn index(&self, nucleotide: Nucleotide) -> &usize { | |
1904 | /// match nucleotide { | |
1905 | /// Nucleotide::A => &self.a, | |
1906 | /// Nucleotide::C => &self.c, | |
1907 | /// Nucleotide::G => &self.g, | |
1908 | /// Nucleotide::T => &self.t, | |
1909 | /// } | |
1a4d82fc JJ |
1910 | /// } |
1911 | /// } | |
1912 | /// | |
9e0c209e SL |
1913 | /// let nucleotide_count = NucleotideCount {a: 14, c: 9, g: 10, t: 12}; |
1914 | /// assert_eq!(nucleotide_count[Nucleotide::A], 14); | |
1915 | /// assert_eq!(nucleotide_count[Nucleotide::C], 9); | |
1916 | /// assert_eq!(nucleotide_count[Nucleotide::G], 10); | |
1917 | /// assert_eq!(nucleotide_count[Nucleotide::T], 12); | |
1a4d82fc | 1918 | /// ``` |
d9579d0f | 1919 | #[lang = "index"] |
85aaf69f SL |
1920 | #[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"] |
1921 | #[stable(feature = "rust1", since = "1.0.0")] | |
1922 | pub trait Index<Idx: ?Sized> { | |
c34b1796 AL |
1923 | /// The returned type after indexing |
1924 | #[stable(feature = "rust1", since = "1.0.0")] | |
1a4d82fc JJ |
1925 | type Output: ?Sized; |
1926 | ||
1927 | /// The method for the indexing (`Foo[Bar]`) operation | |
85aaf69f | 1928 | #[stable(feature = "rust1", since = "1.0.0")] |
e9174d1e | 1929 | fn index(&self, index: Idx) -> &Self::Output; |
1a4d82fc JJ |
1930 | } |
1931 | ||
1932 | /// The `IndexMut` trait is used to specify the functionality of indexing | |
1933 | /// operations like `arr[idx]`, when used in a mutable context. | |
1934 | /// | |
c34b1796 | 1935 | /// # Examples |
1a4d82fc | 1936 | /// |
85aaf69f | 1937 | /// A trivial implementation of `IndexMut`. When `Foo[Bar]` happens, it ends up |
1a4d82fc JJ |
1938 | /// calling `index_mut`, and therefore, `main` prints `Indexing!`. |
1939 | /// | |
1940 | /// ``` | |
85aaf69f | 1941 | /// use std::ops::{Index, IndexMut}; |
1a4d82fc | 1942 | /// |
c34b1796 | 1943 | /// #[derive(Copy, Clone)] |
1a4d82fc | 1944 | /// struct Foo; |
85aaf69f | 1945 | /// struct Bar; |
1a4d82fc | 1946 | /// |
85aaf69f | 1947 | /// impl Index<Bar> for Foo { |
1a4d82fc JJ |
1948 | /// type Output = Foo; |
1949 | /// | |
c34b1796 | 1950 | /// fn index<'a>(&'a self, _index: Bar) -> &'a Foo { |
85aaf69f SL |
1951 | /// self |
1952 | /// } | |
1953 | /// } | |
1954 | /// | |
1955 | /// impl IndexMut<Bar> for Foo { | |
c34b1796 | 1956 | /// fn index_mut<'a>(&'a mut self, _index: Bar) -> &'a mut Foo { |
1a4d82fc JJ |
1957 | /// println!("Indexing!"); |
1958 | /// self | |
1959 | /// } | |
1960 | /// } | |
1961 | /// | |
1962 | /// fn main() { | |
85aaf69f | 1963 | /// &mut Foo[Bar]; |
1a4d82fc JJ |
1964 | /// } |
1965 | /// ``` | |
d9579d0f | 1966 | #[lang = "index_mut"] |
85aaf69f SL |
1967 | #[rustc_on_unimplemented = "the type `{Self}` cannot be mutably indexed by `{Idx}`"] |
1968 | #[stable(feature = "rust1", since = "1.0.0")] | |
1969 | pub trait IndexMut<Idx: ?Sized>: Index<Idx> { | |
1a4d82fc | 1970 | /// The method for the indexing (`Foo[Bar]`) operation |
85aaf69f | 1971 | #[stable(feature = "rust1", since = "1.0.0")] |
e9174d1e | 1972 | fn index_mut(&mut self, index: Idx) -> &mut Self::Output; |
1a4d82fc JJ |
1973 | } |
1974 | ||
54a0048b SL |
1975 | /// An unbounded range. Use `..` (two dots) for its shorthand. |
1976 | /// | |
1977 | /// Its primary use case is slicing index. It cannot serve as an iterator | |
1978 | /// because it doesn't have a starting point. | |
1979 | /// | |
1980 | /// # Examples | |
1981 | /// | |
9e0c209e SL |
1982 | /// The `..` syntax is a `RangeFull`: |
1983 | /// | |
1984 | /// ``` | |
1985 | /// assert_eq!((..), std::ops::RangeFull); | |
54a0048b | 1986 | /// ``` |
54a0048b | 1987 | /// |
9e0c209e SL |
1988 | /// It does not have an `IntoIterator` implementation, so you can't use it in a |
1989 | /// `for` loop directly. This won't compile: | |
1990 | /// | |
1991 | /// ```ignore | |
1992 | /// for i in .. { | |
1993 | /// // ... | |
54a0048b SL |
1994 | /// } |
1995 | /// ``` | |
9e0c209e SL |
1996 | /// |
1997 | /// Used as a slicing index, `RangeFull` produces the full array as a slice. | |
1998 | /// | |
1999 | /// ``` | |
2000 | /// let arr = [0, 1, 2, 3]; | |
2001 | /// assert_eq!(arr[ .. ], [0,1,2,3]); // RangeFull | |
2002 | /// assert_eq!(arr[ ..3], [0,1,2 ]); | |
2003 | /// assert_eq!(arr[1.. ], [ 1,2,3]); | |
2004 | /// assert_eq!(arr[1..3], [ 1,2 ]); | |
2005 | /// ``` | |
3157f602 | 2006 | #[derive(Copy, Clone, PartialEq, Eq, Hash)] |
85aaf69f SL |
2007 | #[stable(feature = "rust1", since = "1.0.0")] |
2008 | pub struct RangeFull; | |
1a4d82fc | 2009 | |
85aaf69f SL |
2010 | #[stable(feature = "rust1", since = "1.0.0")] |
2011 | impl fmt::Debug for RangeFull { | |
1a4d82fc | 2012 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
d9579d0f | 2013 | write!(fmt, "..") |
1a4d82fc JJ |
2014 | } |
2015 | } | |
2016 | ||
54a0048b SL |
2017 | /// A (half-open) range which is bounded at both ends: { x | start <= x < end }. |
2018 | /// Use `start..end` (two dots) for its shorthand. | |
2019 | /// | |
2020 | /// See the [`contains()`](#method.contains) method for its characterization. | |
2021 | /// | |
2022 | /// # Examples | |
2023 | /// | |
2024 | /// ``` | |
54a0048b SL |
2025 | /// fn main() { |
2026 | /// assert_eq!((3..5), std::ops::Range{ start: 3, end: 5 }); | |
2027 | /// assert_eq!(3+4+5, (3..6).sum()); | |
2028 | /// | |
2029 | /// let arr = [0, 1, 2, 3]; | |
2030 | /// assert_eq!(arr[ .. ], [0,1,2,3]); | |
2031 | /// assert_eq!(arr[ ..3], [0,1,2 ]); | |
2032 | /// assert_eq!(arr[1.. ], [ 1,2,3]); | |
2033 | /// assert_eq!(arr[1..3], [ 1,2 ]); // Range | |
2034 | /// } | |
2035 | /// ``` | |
3157f602 | 2036 | #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 |
85aaf69f | 2037 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
2038 | pub struct Range<Idx> { |
2039 | /// The lower bound of the range (inclusive). | |
c34b1796 | 2040 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
2041 | pub start: Idx, |
2042 | /// The upper bound of the range (exclusive). | |
c34b1796 | 2043 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
2044 | pub end: Idx, |
2045 | } | |
2046 | ||
85aaf69f SL |
2047 | #[stable(feature = "rust1", since = "1.0.0")] |
2048 | impl<Idx: fmt::Debug> fmt::Debug for Range<Idx> { | |
1a4d82fc JJ |
2049 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
2050 | write!(fmt, "{:?}..{:?}", self.start, self.end) | |
2051 | } | |
2052 | } | |
2053 | ||
54a0048b SL |
2054 | #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] |
2055 | impl<Idx: PartialOrd<Idx>> Range<Idx> { | |
2056 | /// # Examples | |
2057 | /// | |
2058 | /// ``` | |
2059 | /// #![feature(range_contains)] | |
2060 | /// fn main() { | |
2061 | /// assert!( ! (3..5).contains(2)); | |
2062 | /// assert!( (3..5).contains(3)); | |
2063 | /// assert!( (3..5).contains(4)); | |
2064 | /// assert!( ! (3..5).contains(5)); | |
2065 | /// | |
2066 | /// assert!( ! (3..3).contains(3)); | |
2067 | /// assert!( ! (3..2).contains(3)); | |
2068 | /// } | |
2069 | /// ``` | |
2070 | pub fn contains(&self, item: Idx) -> bool { | |
2071 | (self.start <= item) && (item < self.end) | |
2072 | } | |
2073 | } | |
2074 | ||
2075 | /// A range which is only bounded below: { x | start <= x }. | |
2076 | /// Use `start..` for its shorthand. | |
2077 | /// | |
2078 | /// See the [`contains()`](#method.contains) method for its characterization. | |
2079 | /// | |
a7813a04 XL |
2080 | /// Note: Currently, no overflow checking is done for the iterator |
2081 | /// implementation; if you use an integer range and the integer overflows, it | |
2082 | /// might panic in debug mode or create an endless loop in release mode. This | |
2083 | /// overflow behavior might change in the future. | |
2084 | /// | |
54a0048b SL |
2085 | /// # Examples |
2086 | /// | |
2087 | /// ``` | |
54a0048b SL |
2088 | /// fn main() { |
2089 | /// assert_eq!((2..), std::ops::RangeFrom{ start: 2 }); | |
2090 | /// assert_eq!(2+3+4, (2..).take(3).sum()); | |
2091 | /// | |
2092 | /// let arr = [0, 1, 2, 3]; | |
2093 | /// assert_eq!(arr[ .. ], [0,1,2,3]); | |
2094 | /// assert_eq!(arr[ ..3], [0,1,2 ]); | |
2095 | /// assert_eq!(arr[1.. ], [ 1,2,3]); // RangeFrom | |
2096 | /// assert_eq!(arr[1..3], [ 1,2 ]); | |
2097 | /// } | |
2098 | /// ``` | |
3157f602 | 2099 | #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 |
85aaf69f | 2100 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
2101 | pub struct RangeFrom<Idx> { |
2102 | /// The lower bound of the range (inclusive). | |
c34b1796 | 2103 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
2104 | pub start: Idx, |
2105 | } | |
2106 | ||
85aaf69f SL |
2107 | #[stable(feature = "rust1", since = "1.0.0")] |
2108 | impl<Idx: fmt::Debug> fmt::Debug for RangeFrom<Idx> { | |
1a4d82fc JJ |
2109 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
2110 | write!(fmt, "{:?}..", self.start) | |
2111 | } | |
2112 | } | |
2113 | ||
54a0048b SL |
2114 | #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] |
2115 | impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> { | |
2116 | /// # Examples | |
2117 | /// | |
2118 | /// ``` | |
2119 | /// #![feature(range_contains)] | |
2120 | /// fn main() { | |
2121 | /// assert!( ! (3..).contains(2)); | |
2122 | /// assert!( (3..).contains(3)); | |
2123 | /// assert!( (3..).contains(1_000_000_000)); | |
2124 | /// } | |
2125 | /// ``` | |
2126 | pub fn contains(&self, item: Idx) -> bool { | |
2127 | (self.start <= item) | |
2128 | } | |
2129 | } | |
2130 | ||
2131 | /// A range which is only bounded above: { x | x < end }. | |
2132 | /// Use `..end` (two dots) for its shorthand. | |
2133 | /// | |
2134 | /// See the [`contains()`](#method.contains) method for its characterization. | |
2135 | /// | |
2136 | /// It cannot serve as an iterator because it doesn't have a starting point. | |
3157f602 | 2137 | /// |
9e0c209e SL |
2138 | /// # Examples |
2139 | /// | |
2140 | /// The `..{integer}` syntax is a `RangeTo`: | |
2141 | /// | |
2142 | /// ``` | |
2143 | /// assert_eq!((..5), std::ops::RangeTo{ end: 5 }); | |
54a0048b | 2144 | /// ``` |
54a0048b | 2145 | /// |
9e0c209e SL |
2146 | /// It does not have an `IntoIterator` implementation, so you can't use it in a |
2147 | /// `for` loop directly. This won't compile: | |
2148 | /// | |
2149 | /// ```ignore | |
2150 | /// for i in ..5 { | |
2151 | /// // ... | |
54a0048b SL |
2152 | /// } |
2153 | /// ``` | |
9e0c209e SL |
2154 | /// |
2155 | /// When used as a slicing index, `RangeTo` produces a slice of all array | |
2156 | /// elements before the index indicated by `end`. | |
2157 | /// | |
2158 | /// ``` | |
2159 | /// let arr = [0, 1, 2, 3]; | |
2160 | /// assert_eq!(arr[ .. ], [0,1,2,3]); | |
2161 | /// assert_eq!(arr[ ..3], [0,1,2 ]); // RangeTo | |
2162 | /// assert_eq!(arr[1.. ], [ 1,2,3]); | |
2163 | /// assert_eq!(arr[1..3], [ 1,2 ]); | |
2164 | /// ``` | |
3157f602 | 2165 | #[derive(Copy, Clone, PartialEq, Eq, Hash)] |
85aaf69f | 2166 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
2167 | pub struct RangeTo<Idx> { |
2168 | /// The upper bound of the range (exclusive). | |
c34b1796 | 2169 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
2170 | pub end: Idx, |
2171 | } | |
2172 | ||
85aaf69f SL |
2173 | #[stable(feature = "rust1", since = "1.0.0")] |
2174 | impl<Idx: fmt::Debug> fmt::Debug for RangeTo<Idx> { | |
1a4d82fc JJ |
2175 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
2176 | write!(fmt, "..{:?}", self.end) | |
2177 | } | |
2178 | } | |
2179 | ||
54a0048b SL |
2180 | #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] |
2181 | impl<Idx: PartialOrd<Idx>> RangeTo<Idx> { | |
2182 | /// # Examples | |
2183 | /// | |
2184 | /// ``` | |
2185 | /// #![feature(range_contains)] | |
2186 | /// fn main() { | |
2187 | /// assert!( (..5).contains(-1_000_000_000)); | |
2188 | /// assert!( (..5).contains(4)); | |
2189 | /// assert!( ! (..5).contains(5)); | |
2190 | /// } | |
2191 | /// ``` | |
2192 | pub fn contains(&self, item: Idx) -> bool { | |
2193 | (item < self.end) | |
2194 | } | |
2195 | } | |
2196 | ||
2197 | /// An inclusive range which is bounded at both ends: { x | start <= x <= end }. | |
2198 | /// Use `start...end` (three dots) for its shorthand. | |
2199 | /// | |
2200 | /// See the [`contains()`](#method.contains) method for its characterization. | |
2201 | /// | |
2202 | /// # Examples | |
2203 | /// | |
2204 | /// ``` | |
3157f602 | 2205 | /// #![feature(inclusive_range,inclusive_range_syntax)] |
54a0048b SL |
2206 | /// fn main() { |
2207 | /// assert_eq!((3...5), std::ops::RangeInclusive::NonEmpty{ start: 3, end: 5 }); | |
2208 | /// assert_eq!(3+4+5, (3...5).sum()); | |
2209 | /// | |
2210 | /// let arr = [0, 1, 2, 3]; | |
2211 | /// assert_eq!(arr[ ...2], [0,1,2 ]); | |
2212 | /// assert_eq!(arr[1...2], [ 1,2 ]); // RangeInclusive | |
2213 | /// } | |
2214 | /// ``` | |
3157f602 | 2215 | #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 |
54a0048b SL |
2216 | #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] |
2217 | pub enum RangeInclusive<Idx> { | |
2218 | /// Empty range (iteration has finished) | |
2219 | #[unstable(feature = "inclusive_range", | |
2220 | reason = "recently added, follows RFC", | |
2221 | issue = "28237")] | |
2222 | Empty { | |
2223 | /// The point at which iteration finished | |
2224 | #[unstable(feature = "inclusive_range", | |
2225 | reason = "recently added, follows RFC", | |
2226 | issue = "28237")] | |
2227 | at: Idx | |
2228 | }, | |
2229 | /// Non-empty range (iteration will yield value(s)) | |
2230 | #[unstable(feature = "inclusive_range", | |
2231 | reason = "recently added, follows RFC", | |
2232 | issue = "28237")] | |
2233 | NonEmpty { | |
2234 | /// The lower bound of the range (inclusive). | |
2235 | #[unstable(feature = "inclusive_range", | |
2236 | reason = "recently added, follows RFC", | |
2237 | issue = "28237")] | |
2238 | start: Idx, | |
2239 | /// The upper bound of the range (inclusive). | |
2240 | #[unstable(feature = "inclusive_range", | |
2241 | reason = "recently added, follows RFC", | |
2242 | issue = "28237")] | |
2243 | end: Idx, | |
2244 | }, | |
2245 | } | |
2246 | ||
2247 | #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] | |
2248 | impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> { | |
2249 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | |
2250 | use self::RangeInclusive::*; | |
2251 | ||
2252 | match *self { | |
2253 | Empty { ref at } => write!(fmt, "[empty range @ {:?}]", at), | |
2254 | NonEmpty { ref start, ref end } => write!(fmt, "{:?}...{:?}", start, end), | |
2255 | } | |
2256 | } | |
2257 | } | |
2258 | ||
54a0048b SL |
2259 | #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] |
2260 | impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> { | |
2261 | /// # Examples | |
2262 | /// | |
2263 | /// ``` | |
2264 | /// #![feature(range_contains,inclusive_range_syntax)] | |
2265 | /// fn main() { | |
2266 | /// assert!( ! (3...5).contains(2)); | |
2267 | /// assert!( (3...5).contains(3)); | |
2268 | /// assert!( (3...5).contains(4)); | |
2269 | /// assert!( (3...5).contains(5)); | |
2270 | /// assert!( ! (3...5).contains(6)); | |
2271 | /// | |
2272 | /// assert!( (3...3).contains(3)); | |
2273 | /// assert!( ! (3...2).contains(3)); | |
2274 | /// } | |
2275 | /// ``` | |
2276 | pub fn contains(&self, item: Idx) -> bool { | |
2277 | if let &RangeInclusive::NonEmpty{ref start, ref end} = self { | |
2278 | (*start <= item) && (item <= *end) | |
2279 | } else { false } | |
2280 | } | |
2281 | } | |
2282 | ||
2283 | /// An inclusive range which is only bounded above: { x | x <= end }. | |
2284 | /// Use `...end` (three dots) for its shorthand. | |
2285 | /// | |
2286 | /// See the [`contains()`](#method.contains) method for its characterization. | |
2287 | /// | |
2288 | /// It cannot serve as an iterator because it doesn't have a starting point. | |
2289 | /// | |
2290 | /// # Examples | |
2291 | /// | |
9e0c209e SL |
2292 | /// The `...{integer}` syntax is a `RangeToInclusive`: |
2293 | /// | |
54a0048b SL |
2294 | /// ``` |
2295 | /// #![feature(inclusive_range,inclusive_range_syntax)] | |
9e0c209e SL |
2296 | /// assert_eq!((...5), std::ops::RangeToInclusive{ end: 5 }); |
2297 | /// ``` | |
54a0048b | 2298 | /// |
9e0c209e SL |
2299 | /// It does not have an `IntoIterator` implementation, so you can't use it in a |
2300 | /// `for` loop directly. This won't compile: | |
2301 | /// | |
2302 | /// ```ignore | |
2303 | /// for i in ...5 { | |
2304 | /// // ... | |
54a0048b SL |
2305 | /// } |
2306 | /// ``` | |
9e0c209e SL |
2307 | /// |
2308 | /// When used as a slicing index, `RangeToInclusive` produces a slice of all | |
2309 | /// array elements up to and including the index indicated by `end`. | |
2310 | /// | |
2311 | /// ``` | |
2312 | /// #![feature(inclusive_range_syntax)] | |
2313 | /// let arr = [0, 1, 2, 3]; | |
2314 | /// assert_eq!(arr[ ...2], [0,1,2 ]); // RangeToInclusive | |
2315 | /// assert_eq!(arr[1...2], [ 1,2 ]); | |
2316 | /// ``` | |
3157f602 | 2317 | #[derive(Copy, Clone, PartialEq, Eq, Hash)] |
54a0048b SL |
2318 | #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] |
2319 | pub struct RangeToInclusive<Idx> { | |
2320 | /// The upper bound of the range (inclusive) | |
2321 | #[unstable(feature = "inclusive_range", | |
2322 | reason = "recently added, follows RFC", | |
2323 | issue = "28237")] | |
2324 | pub end: Idx, | |
2325 | } | |
2326 | ||
2327 | #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] | |
2328 | impl<Idx: fmt::Debug> fmt::Debug for RangeToInclusive<Idx> { | |
2329 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | |
2330 | write!(fmt, "...{:?}", self.end) | |
2331 | } | |
2332 | } | |
2333 | ||
2334 | #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] | |
2335 | impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> { | |
2336 | /// # Examples | |
2337 | /// | |
2338 | /// ``` | |
2339 | /// #![feature(range_contains,inclusive_range_syntax)] | |
2340 | /// fn main() { | |
2341 | /// assert!( (...5).contains(-1_000_000_000)); | |
2342 | /// assert!( (...5).contains(5)); | |
2343 | /// assert!( ! (...5).contains(6)); | |
2344 | /// } | |
2345 | /// ``` | |
2346 | pub fn contains(&self, item: Idx) -> bool { | |
2347 | (item <= self.end) | |
2348 | } | |
2349 | } | |
2350 | ||
2351 | // RangeToInclusive<Idx> cannot impl From<RangeTo<Idx>> | |
2352 | // because underflow would be possible with (..0).into() | |
2353 | ||
1a4d82fc | 2354 | /// The `Deref` trait is used to specify the functionality of dereferencing |
9cc50fc6 | 2355 | /// operations, like `*v`. |
1a4d82fc | 2356 | /// |
c1a9b12d SL |
2357 | /// `Deref` also enables ['`Deref` coercions'][coercions]. |
2358 | /// | |
2359 | /// [coercions]: ../../book/deref-coercions.html | |
2360 | /// | |
c34b1796 | 2361 | /// # Examples |
1a4d82fc JJ |
2362 | /// |
2363 | /// A struct with a single field which is accessible via dereferencing the | |
2364 | /// struct. | |
2365 | /// | |
2366 | /// ``` | |
1a4d82fc JJ |
2367 | /// use std::ops::Deref; |
2368 | /// | |
2369 | /// struct DerefExample<T> { | |
2370 | /// value: T | |
2371 | /// } | |
2372 | /// | |
2373 | /// impl<T> Deref for DerefExample<T> { | |
2374 | /// type Target = T; | |
2375 | /// | |
b039eaaf | 2376 | /// fn deref(&self) -> &T { |
1a4d82fc JJ |
2377 | /// &self.value |
2378 | /// } | |
2379 | /// } | |
2380 | /// | |
2381 | /// fn main() { | |
2382 | /// let x = DerefExample { value: 'a' }; | |
2383 | /// assert_eq!('a', *x); | |
2384 | /// } | |
2385 | /// ``` | |
d9579d0f | 2386 | #[lang = "deref"] |
85aaf69f | 2387 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 2388 | pub trait Deref { |
c34b1796 | 2389 | /// The resulting type after dereferencing |
85aaf69f | 2390 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
2391 | type Target: ?Sized; |
2392 | ||
2393 | /// The method called to dereference a value | |
85aaf69f | 2394 | #[stable(feature = "rust1", since = "1.0.0")] |
e9174d1e | 2395 | fn deref(&self) -> &Self::Target; |
1a4d82fc JJ |
2396 | } |
2397 | ||
85aaf69f | 2398 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
2399 | impl<'a, T: ?Sized> Deref for &'a T { |
2400 | type Target = T; | |
2401 | ||
2402 | fn deref(&self) -> &T { *self } | |
2403 | } | |
2404 | ||
85aaf69f | 2405 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
2406 | impl<'a, T: ?Sized> Deref for &'a mut T { |
2407 | type Target = T; | |
2408 | ||
2409 | fn deref(&self) -> &T { *self } | |
2410 | } | |
2411 | ||
2412 | /// The `DerefMut` trait is used to specify the functionality of dereferencing | |
2413 | /// mutably like `*v = 1;` | |
2414 | /// | |
c1a9b12d SL |
2415 | /// `DerefMut` also enables ['`Deref` coercions'][coercions]. |
2416 | /// | |
2417 | /// [coercions]: ../../book/deref-coercions.html | |
2418 | /// | |
c34b1796 | 2419 | /// # Examples |
1a4d82fc JJ |
2420 | /// |
2421 | /// A struct with a single field which is modifiable via dereferencing the | |
2422 | /// struct. | |
2423 | /// | |
2424 | /// ``` | |
1a4d82fc JJ |
2425 | /// use std::ops::{Deref, DerefMut}; |
2426 | /// | |
2427 | /// struct DerefMutExample<T> { | |
2428 | /// value: T | |
2429 | /// } | |
2430 | /// | |
2431 | /// impl<T> Deref for DerefMutExample<T> { | |
2432 | /// type Target = T; | |
2433 | /// | |
2434 | /// fn deref<'a>(&'a self) -> &'a T { | |
2435 | /// &self.value | |
2436 | /// } | |
2437 | /// } | |
2438 | /// | |
2439 | /// impl<T> DerefMut for DerefMutExample<T> { | |
2440 | /// fn deref_mut<'a>(&'a mut self) -> &'a mut T { | |
2441 | /// &mut self.value | |
2442 | /// } | |
2443 | /// } | |
2444 | /// | |
2445 | /// fn main() { | |
2446 | /// let mut x = DerefMutExample { value: 'a' }; | |
2447 | /// *x = 'b'; | |
2448 | /// assert_eq!('b', *x); | |
2449 | /// } | |
2450 | /// ``` | |
d9579d0f | 2451 | #[lang = "deref_mut"] |
85aaf69f | 2452 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
2453 | pub trait DerefMut: Deref { |
2454 | /// The method called to mutably dereference a value | |
85aaf69f | 2455 | #[stable(feature = "rust1", since = "1.0.0")] |
e9174d1e | 2456 | fn deref_mut(&mut self) -> &mut Self::Target; |
1a4d82fc JJ |
2457 | } |
2458 | ||
85aaf69f | 2459 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
2460 | impl<'a, T: ?Sized> DerefMut for &'a mut T { |
2461 | fn deref_mut(&mut self) -> &mut T { *self } | |
2462 | } | |
2463 | ||
2464 | /// A version of the call operator that takes an immutable receiver. | |
9e0c209e SL |
2465 | /// |
2466 | /// # Examples | |
2467 | /// | |
2468 | /// Closures automatically implement this trait, which allows them to be | |
2469 | /// invoked. Note, however, that `Fn` takes an immutable reference to any | |
2470 | /// captured variables. To take a mutable capture, implement [`FnMut`], and to | |
2471 | /// consume the capture, implement [`FnOnce`]. | |
2472 | /// | |
2473 | /// [`FnMut`]: trait.FnMut.html | |
2474 | /// [`FnOnce`]: trait.FnOnce.html | |
2475 | /// | |
2476 | /// ``` | |
2477 | /// let square = |x| x * x; | |
2478 | /// assert_eq!(square(5), 25); | |
2479 | /// ``` | |
2480 | /// | |
2481 | /// Closures can also be passed to higher-level functions through a `Fn` | |
2482 | /// parameter (or a `FnMut` or `FnOnce` parameter, which are supertraits of | |
2483 | /// `Fn`). | |
2484 | /// | |
2485 | /// ``` | |
2486 | /// fn call_with_one<F>(func: F) -> usize | |
2487 | /// where F: Fn(usize) -> usize { | |
2488 | /// func(1) | |
2489 | /// } | |
2490 | /// | |
2491 | /// let double = |x| x * 2; | |
2492 | /// assert_eq!(call_with_one(double), 2); | |
2493 | /// ``` | |
d9579d0f | 2494 | #[lang = "fn"] |
85aaf69f SL |
2495 | #[stable(feature = "rust1", since = "1.0.0")] |
2496 | #[rustc_paren_sugar] | |
c34b1796 AL |
2497 | #[fundamental] // so that regex can rely that `&str: !FnMut` |
2498 | pub trait Fn<Args> : FnMut<Args> { | |
1a4d82fc | 2499 | /// This is called when the call operator is used. |
92a42be0 | 2500 | #[unstable(feature = "fn_traits", issue = "29625")] |
85aaf69f | 2501 | extern "rust-call" fn call(&self, args: Args) -> Self::Output; |
1a4d82fc JJ |
2502 | } |
2503 | ||
2504 | /// A version of the call operator that takes a mutable receiver. | |
9e0c209e SL |
2505 | /// |
2506 | /// # Examples | |
2507 | /// | |
2508 | /// Closures that mutably capture variables automatically implement this trait, | |
2509 | /// which allows them to be invoked. | |
2510 | /// | |
2511 | /// ``` | |
2512 | /// let mut x = 5; | |
2513 | /// { | |
2514 | /// let mut square_x = || x *= x; | |
2515 | /// square_x(); | |
2516 | /// } | |
2517 | /// assert_eq!(x, 25); | |
2518 | /// ``` | |
2519 | /// | |
2520 | /// Closures can also be passed to higher-level functions through a `FnMut` | |
2521 | /// parameter (or a `FnOnce` parameter, which is a supertrait of `FnMut`). | |
2522 | /// | |
2523 | /// ``` | |
2524 | /// fn do_twice<F>(mut func: F) | |
2525 | /// where F: FnMut() | |
2526 | /// { | |
2527 | /// func(); | |
2528 | /// func(); | |
2529 | /// } | |
2530 | /// | |
2531 | /// let mut x: usize = 1; | |
2532 | /// { | |
2533 | /// let add_two_to_x = || x += 2; | |
2534 | /// do_twice(add_two_to_x); | |
2535 | /// } | |
2536 | /// | |
2537 | /// assert_eq!(x, 5); | |
2538 | /// ``` | |
d9579d0f | 2539 | #[lang = "fn_mut"] |
85aaf69f SL |
2540 | #[stable(feature = "rust1", since = "1.0.0")] |
2541 | #[rustc_paren_sugar] | |
c34b1796 AL |
2542 | #[fundamental] // so that regex can rely that `&str: !FnMut` |
2543 | pub trait FnMut<Args> : FnOnce<Args> { | |
1a4d82fc | 2544 | /// This is called when the call operator is used. |
92a42be0 | 2545 | #[unstable(feature = "fn_traits", issue = "29625")] |
85aaf69f | 2546 | extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output; |
1a4d82fc JJ |
2547 | } |
2548 | ||
2549 | /// A version of the call operator that takes a by-value receiver. | |
9e0c209e SL |
2550 | /// |
2551 | /// # Examples | |
2552 | /// | |
2553 | /// By-value closures automatically implement this trait, which allows them to | |
2554 | /// be invoked. | |
2555 | /// | |
2556 | /// ``` | |
2557 | /// let x = 5; | |
2558 | /// let square_x = move || x * x; | |
2559 | /// assert_eq!(square_x(), 25); | |
2560 | /// ``` | |
2561 | /// | |
2562 | /// By-value Closures can also be passed to higher-level functions through a | |
2563 | /// `FnOnce` parameter. | |
2564 | /// | |
2565 | /// ``` | |
2566 | /// fn consume_with_relish<F>(func: F) | |
2567 | /// where F: FnOnce() -> String | |
2568 | /// { | |
2569 | /// // `func` consumes its captured variables, so it cannot be run more | |
2570 | /// // than once | |
2571 | /// println!("Consumed: {}", func()); | |
2572 | /// | |
2573 | /// println!("Delicious!"); | |
2574 | /// | |
2575 | /// // Attempting to invoke `func()` again will throw a `use of moved | |
2576 | /// // value` error for `func` | |
2577 | /// } | |
2578 | /// | |
2579 | /// let x = String::from("x"); | |
2580 | /// let consume_and_return_x = move || x; | |
2581 | /// consume_with_relish(consume_and_return_x); | |
2582 | /// | |
2583 | /// // `consume_and_return_x` can no longer be invoked at this point | |
2584 | /// ``` | |
d9579d0f | 2585 | #[lang = "fn_once"] |
85aaf69f SL |
2586 | #[stable(feature = "rust1", since = "1.0.0")] |
2587 | #[rustc_paren_sugar] | |
c34b1796 | 2588 | #[fundamental] // so that regex can rely that `&str: !FnMut` |
85aaf69f | 2589 | pub trait FnOnce<Args> { |
c34b1796 | 2590 | /// The returned type after the call operator is used. |
5bcae85e | 2591 | #[stable(feature = "fn_once_output", since = "1.12.0")] |
85aaf69f SL |
2592 | type Output; |
2593 | ||
1a4d82fc | 2594 | /// This is called when the call operator is used. |
92a42be0 | 2595 | #[unstable(feature = "fn_traits", issue = "29625")] |
85aaf69f | 2596 | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; |
1a4d82fc JJ |
2597 | } |
2598 | ||
c34b1796 | 2599 | mod impls { |
92a42be0 | 2600 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 AL |
2601 | impl<'a,A,F:?Sized> Fn<A> for &'a F |
2602 | where F : Fn<A> | |
2603 | { | |
2604 | extern "rust-call" fn call(&self, args: A) -> F::Output { | |
2605 | (**self).call(args) | |
2606 | } | |
1a4d82fc | 2607 | } |
1a4d82fc | 2608 | |
92a42be0 | 2609 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 AL |
2610 | impl<'a,A,F:?Sized> FnMut<A> for &'a F |
2611 | where F : Fn<A> | |
2612 | { | |
2613 | extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output { | |
2614 | (**self).call(args) | |
2615 | } | |
2616 | } | |
2617 | ||
92a42be0 | 2618 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 AL |
2619 | impl<'a,A,F:?Sized> FnOnce<A> for &'a F |
2620 | where F : Fn<A> | |
2621 | { | |
2622 | type Output = F::Output; | |
2623 | ||
2624 | extern "rust-call" fn call_once(self, args: A) -> F::Output { | |
2625 | (*self).call(args) | |
2626 | } | |
2627 | } | |
85aaf69f | 2628 | |
92a42be0 | 2629 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 AL |
2630 | impl<'a,A,F:?Sized> FnMut<A> for &'a mut F |
2631 | where F : FnMut<A> | |
2632 | { | |
2633 | extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output { | |
2634 | (*self).call_mut(args) | |
2635 | } | |
2636 | } | |
2637 | ||
92a42be0 | 2638 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 AL |
2639 | impl<'a,A,F:?Sized> FnOnce<A> for &'a mut F |
2640 | where F : FnMut<A> | |
2641 | { | |
2642 | type Output = F::Output; | |
2643 | extern "rust-call" fn call_once(mut self, args: A) -> F::Output { | |
2644 | (*self).call_mut(args) | |
2645 | } | |
1a4d82fc JJ |
2646 | } |
2647 | } | |
d9579d0f AL |
2648 | |
2649 | /// Trait that indicates that this is a pointer or a wrapper for one, | |
2650 | /// where unsizing can be performed on the pointee. | |
e9174d1e | 2651 | #[unstable(feature = "coerce_unsized", issue = "27732")] |
d9579d0f AL |
2652 | #[lang="coerce_unsized"] |
2653 | pub trait CoerceUnsized<T> { | |
2654 | // Empty. | |
2655 | } | |
2656 | ||
2657 | // &mut T -> &mut U | |
92a42be0 | 2658 | #[unstable(feature = "coerce_unsized", issue = "27732")] |
d9579d0f AL |
2659 | impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {} |
2660 | // &mut T -> &U | |
92a42be0 | 2661 | #[unstable(feature = "coerce_unsized", issue = "27732")] |
d9579d0f AL |
2662 | impl<'a, 'b: 'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {} |
2663 | // &mut T -> *mut U | |
92a42be0 | 2664 | #[unstable(feature = "coerce_unsized", issue = "27732")] |
d9579d0f AL |
2665 | impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {} |
2666 | // &mut T -> *const U | |
92a42be0 | 2667 | #[unstable(feature = "coerce_unsized", issue = "27732")] |
d9579d0f AL |
2668 | impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {} |
2669 | ||
2670 | // &T -> &U | |
92a42be0 | 2671 | #[unstable(feature = "coerce_unsized", issue = "27732")] |
d9579d0f AL |
2672 | impl<'a, 'b: 'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} |
2673 | // &T -> *const U | |
92a42be0 | 2674 | #[unstable(feature = "coerce_unsized", issue = "27732")] |
d9579d0f AL |
2675 | impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {} |
2676 | ||
2677 | // *mut T -> *mut U | |
92a42be0 | 2678 | #[unstable(feature = "coerce_unsized", issue = "27732")] |
d9579d0f AL |
2679 | impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} |
2680 | // *mut T -> *const U | |
92a42be0 | 2681 | #[unstable(feature = "coerce_unsized", issue = "27732")] |
d9579d0f AL |
2682 | impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {} |
2683 | ||
2684 | // *const T -> *const U | |
92a42be0 | 2685 | #[unstable(feature = "coerce_unsized", issue = "27732")] |
d9579d0f | 2686 | impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {} |
c1a9b12d SL |
2687 | |
2688 | /// Both `in (PLACE) EXPR` and `box EXPR` desugar into expressions | |
2689 | /// that allocate an intermediate "place" that holds uninitialized | |
2690 | /// state. The desugaring evaluates EXPR, and writes the result at | |
2691 | /// the address returned by the `pointer` method of this trait. | |
2692 | /// | |
2693 | /// A `Place` can be thought of as a special representation for a | |
2694 | /// hypothetical `&uninit` reference (which Rust cannot currently | |
2695 | /// express directly). That is, it represents a pointer to | |
2696 | /// uninitialized storage. | |
2697 | /// | |
2698 | /// The client is responsible for two steps: First, initializing the | |
2699 | /// payload (it can access its address via `pointer`). Second, | |
2700 | /// converting the agent to an instance of the owning pointer, via the | |
2701 | /// appropriate `finalize` method (see the `InPlace`. | |
2702 | /// | |
2703 | /// If evaluating EXPR fails, then the destructor for the | |
2704 | /// implementation of Place to clean up any intermediate state | |
2705 | /// (e.g. deallocate box storage, pop a stack, etc). | |
e9174d1e | 2706 | #[unstable(feature = "placement_new_protocol", issue = "27779")] |
c1a9b12d SL |
2707 | pub trait Place<Data: ?Sized> { |
2708 | /// Returns the address where the input value will be written. | |
2709 | /// Note that the data at this address is generally uninitialized, | |
2710 | /// and thus one should use `ptr::write` for initializing it. | |
2711 | fn pointer(&mut self) -> *mut Data; | |
2712 | } | |
2713 | ||
2714 | /// Interface to implementations of `in (PLACE) EXPR`. | |
2715 | /// | |
2716 | /// `in (PLACE) EXPR` effectively desugars into: | |
2717 | /// | |
2718 | /// ```rust,ignore | |
2719 | /// let p = PLACE; | |
2720 | /// let mut place = Placer::make_place(p); | |
2721 | /// let raw_place = Place::pointer(&mut place); | |
2722 | /// let value = EXPR; | |
2723 | /// unsafe { | |
2724 | /// std::ptr::write(raw_place, value); | |
2725 | /// InPlace::finalize(place) | |
2726 | /// } | |
2727 | /// ``` | |
2728 | /// | |
2729 | /// The type of `in (PLACE) EXPR` is derived from the type of `PLACE`; | |
2730 | /// if the type of `PLACE` is `P`, then the final type of the whole | |
2731 | /// expression is `P::Place::Owner` (see the `InPlace` and `Boxed` | |
2732 | /// traits). | |
2733 | /// | |
2734 | /// Values for types implementing this trait usually are transient | |
2735 | /// intermediate values (e.g. the return value of `Vec::emplace_back`) | |
2736 | /// or `Copy`, since the `make_place` method takes `self` by value. | |
e9174d1e | 2737 | #[unstable(feature = "placement_new_protocol", issue = "27779")] |
c1a9b12d SL |
2738 | pub trait Placer<Data: ?Sized> { |
2739 | /// `Place` is the intermedate agent guarding the | |
2740 | /// uninitialized state for `Data`. | |
2741 | type Place: InPlace<Data>; | |
2742 | ||
2743 | /// Creates a fresh place from `self`. | |
2744 | fn make_place(self) -> Self::Place; | |
2745 | } | |
2746 | ||
2747 | /// Specialization of `Place` trait supporting `in (PLACE) EXPR`. | |
e9174d1e | 2748 | #[unstable(feature = "placement_new_protocol", issue = "27779")] |
c1a9b12d SL |
2749 | pub trait InPlace<Data: ?Sized>: Place<Data> { |
2750 | /// `Owner` is the type of the end value of `in (PLACE) EXPR` | |
2751 | /// | |
2752 | /// Note that when `in (PLACE) EXPR` is solely used for | |
2753 | /// side-effecting an existing data-structure, | |
2754 | /// e.g. `Vec::emplace_back`, then `Owner` need not carry any | |
2755 | /// information at all (e.g. it can be the unit type `()` in that | |
2756 | /// case). | |
2757 | type Owner; | |
2758 | ||
2759 | /// Converts self into the final value, shifting | |
2760 | /// deallocation/cleanup responsibilities (if any remain), over to | |
2761 | /// the returned instance of `Owner` and forgetting self. | |
2762 | unsafe fn finalize(self) -> Self::Owner; | |
2763 | } | |
2764 | ||
2765 | /// Core trait for the `box EXPR` form. | |
2766 | /// | |
2767 | /// `box EXPR` effectively desugars into: | |
2768 | /// | |
2769 | /// ```rust,ignore | |
2770 | /// let mut place = BoxPlace::make_place(); | |
2771 | /// let raw_place = Place::pointer(&mut place); | |
2772 | /// let value = EXPR; | |
2773 | /// unsafe { | |
2774 | /// ::std::ptr::write(raw_place, value); | |
2775 | /// Boxed::finalize(place) | |
2776 | /// } | |
2777 | /// ``` | |
2778 | /// | |
2779 | /// The type of `box EXPR` is supplied from its surrounding | |
2780 | /// context; in the above expansion, the result type `T` is used | |
2781 | /// to determine which implementation of `Boxed` to use, and that | |
2782 | /// `<T as Boxed>` in turn dictates determines which | |
2783 | /// implementation of `BoxPlace` to use, namely: | |
2784 | /// `<<T as Boxed>::Place as BoxPlace>`. | |
e9174d1e | 2785 | #[unstable(feature = "placement_new_protocol", issue = "27779")] |
c1a9b12d SL |
2786 | pub trait Boxed { |
2787 | /// The kind of data that is stored in this kind of box. | |
2788 | type Data; /* (`Data` unused b/c cannot yet express below bound.) */ | |
2789 | /// The place that will negotiate the storage of the data. | |
2790 | type Place: BoxPlace<Self::Data>; | |
2791 | ||
2792 | /// Converts filled place into final owning value, shifting | |
2793 | /// deallocation/cleanup responsibilities (if any remain), over to | |
2794 | /// returned instance of `Self` and forgetting `filled`. | |
2795 | unsafe fn finalize(filled: Self::Place) -> Self; | |
2796 | } | |
2797 | ||
2798 | /// Specialization of `Place` trait supporting `box EXPR`. | |
e9174d1e | 2799 | #[unstable(feature = "placement_new_protocol", issue = "27779")] |
c1a9b12d SL |
2800 | pub trait BoxPlace<Data: ?Sized> : Place<Data> { |
2801 | /// Creates a globally fresh place. | |
2802 | fn make_place() -> Self; | |
2803 | } | |
9e0c209e SL |
2804 | |
2805 | /// A trait for types which have success and error states and are meant to work | |
2806 | /// with the question mark operator. | |
2807 | /// When the `?` operator is used with a value, whether the value is in the | |
2808 | /// success or error state is determined by calling `translate`. | |
2809 | /// | |
2810 | /// This trait is **very** experimental, it will probably be iterated on heavily | |
2811 | /// before it is stabilised. Implementors should expect change. Users of `?` | |
2812 | /// should not rely on any implementations of `Carrier` other than `Result`, | |
2813 | /// i.e., you should not expect `?` to continue to work with `Option`, etc. | |
2814 | #[unstable(feature = "question_mark_carrier", issue = "31436")] | |
2815 | pub trait Carrier { | |
2816 | /// The type of the value when computation succeeds. | |
2817 | type Success; | |
2818 | /// The type of the value when computation errors out. | |
2819 | type Error; | |
2820 | ||
2821 | /// Create a `Carrier` from a success value. | |
2822 | fn from_success(Self::Success) -> Self; | |
2823 | ||
2824 | /// Create a `Carrier` from an error value. | |
2825 | fn from_error(Self::Error) -> Self; | |
2826 | ||
2827 | /// Translate this `Carrier` to another implementation of `Carrier` with the | |
2828 | /// same associated types. | |
2829 | fn translate<T>(self) -> T where T: Carrier<Success=Self::Success, Error=Self::Error>; | |
2830 | } | |
2831 | ||
2832 | #[unstable(feature = "question_mark_carrier", issue = "31436")] | |
2833 | impl<U, V> Carrier for Result<U, V> { | |
2834 | type Success = U; | |
2835 | type Error = V; | |
2836 | ||
2837 | fn from_success(u: U) -> Result<U, V> { | |
2838 | Ok(u) | |
2839 | } | |
2840 | ||
2841 | fn from_error(e: V) -> Result<U, V> { | |
2842 | Err(e) | |
2843 | } | |
2844 | ||
2845 | fn translate<T>(self) -> T | |
2846 | where T: Carrier<Success=U, Error=V> | |
2847 | { | |
2848 | match self { | |
2849 | Ok(u) => T::from_success(u), | |
2850 | Err(e) => T::from_error(e), | |
2851 | } | |
2852 | } | |
2853 | } | |
2854 | ||
2855 | struct _DummyErrorType; | |
2856 | ||
2857 | impl Carrier for _DummyErrorType { | |
2858 | type Success = (); | |
2859 | type Error = (); | |
2860 | ||
2861 | fn from_success(_: ()) -> _DummyErrorType { | |
2862 | _DummyErrorType | |
2863 | } | |
2864 | ||
2865 | fn from_error(_: ()) -> _DummyErrorType { | |
2866 | _DummyErrorType | |
2867 | } | |
2868 | ||
2869 | fn translate<T>(self) -> T | |
2870 | where T: Carrier<Success=(), Error=()> | |
2871 | { | |
2872 | T::from_success(()) | |
2873 | } | |
2874 | } |