]> git.proxmox.com Git - rustc.git/blame - src/libcore/ops.rs
New upstream version 1.13.0+dfsg1
[rustc.git] / src / libcore / ops.rs
CommitLineData
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 146use fmt;
9e0c209e 147use 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 172pub 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
197macro_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
213macro_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 293pub 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
303macro_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 318add_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 366pub 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
376macro_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 391sub_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 488pub 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
498macro_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 513mul_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 616pub 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 626macro_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
642div_impl_integer! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
643
644macro_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
658div_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 695pub 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 705macro_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
721rem_impl_integer! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
722
e9174d1e
SL
723macro_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 737rem_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 777pub 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
789macro_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
804macro_rules! neg_impl_numeric {
805 ($($t:ty)*) => { neg_impl_core!{ x => -x, $($t)*} }
1a4d82fc
JJ
806}
807
c34b1796
AL
808macro_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 }
816neg_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 850pub 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
860macro_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 874not_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 933pub 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
943macro_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 957bitand_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 1016pub 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
1026macro_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 1040bitor_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 1102pub 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
1112macro_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 1126bitxor_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 1184pub 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
1194macro_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
1211macro_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 1227shl_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 1285pub 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
1295macro_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
1312macro_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 1328shr_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
1367pub 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
1373macro_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
1384add_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
1423pub 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
1429macro_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
1440sub_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
1468pub 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
1474macro_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
1485mul_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
1513pub 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
1519macro_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
1529div_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
1557pub 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
1563macro_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
1573rem_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
1643pub 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
1649macro_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
1659bitand_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
1687pub 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
1693macro_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
1703bitor_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
1731pub 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
1737macro_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
1747bitxor_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
1775pub 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
1781macro_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
1794macro_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
1810shl_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
1838pub 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
1844macro_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
1857macro_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
1873shr_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")]
1922pub 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")]
1969pub 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")]
2008pub struct RangeFull;
1a4d82fc 2009
85aaf69f
SL
2010#[stable(feature = "rust1", since = "1.0.0")]
2011impl 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
2038pub 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")]
2048impl<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")]
2055impl<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
2101pub 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")]
2108impl<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")]
2115impl<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
2167pub 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")]
2174impl<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")]
2181impl<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")]
2217pub 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")]
2248impl<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")]
2260impl<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")]
2319pub 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")]
2328impl<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")]
2335impl<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 2388pub 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
2399impl<'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
2406impl<'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
2453pub 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
2460impl<'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`
2498pub 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`
2543pub 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 2589pub 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 2599mod 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"]
2653pub trait CoerceUnsized<T> {
2654 // Empty.
2655}
2656
2657// &mut T -> &mut U
92a42be0 2658#[unstable(feature = "coerce_unsized", issue = "27732")]
d9579d0f
AL
2659impl<'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
2662impl<'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
2665impl<'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
2668impl<'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
2672impl<'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
2675impl<'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
2679impl<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
2682impl<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 2686impl<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
2707pub 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
2738pub 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
2749pub 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
2786pub 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
2800pub 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")]
2815pub 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")]
2833impl<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
2855struct _DummyErrorType;
2856
2857impl 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}