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.
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.
11 /// The addition operator `+`.
13 /// Note that `RHS` is `Self` by default, but this is not mandatory. For
14 /// example, [`std::time::SystemTime`] implements `Add<Duration>`, which permits
15 /// operations of the form `SystemTime = SystemTime + Duration`.
17 /// [`std::time::SystemTime`]: ../../std/time/struct.SystemTime.html
21 /// ## `Add`able points
24 /// use std::ops::Add;
26 /// #[derive(Debug, PartialEq)]
32 /// impl Add for Point {
33 /// type Output = Point;
35 /// fn add(self, other: Point) -> Point {
37 /// x: self.x + other.x,
38 /// y: self.y + other.y,
43 /// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
44 /// Point { x: 3, y: 3 });
47 /// ## Implementing `Add` with generics
49 /// Here is an example of the same `Point` struct implementing the `Add` trait
53 /// use std::ops::Add;
55 /// #[derive(Debug, PartialEq)]
61 /// // Notice that the implementation uses the associated type `Output`.
62 /// impl<T: Add<Output=T>> Add for Point<T> {
63 /// type Output = Point<T>;
65 /// fn add(self, other: Point<T>) -> Point<T> {
67 /// x: self.x + other.x,
68 /// y: self.y + other.y,
73 /// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
74 /// Point { x: 3, y: 3 });
77 #[stable(feature = "rust1", since = "1.0.0")]
78 #[rustc_on_unimplemented(
80 all(_Self="{integer}", RHS="{float}"),
81 message="cannot add a float to an integer",
84 all(_Self="{float}", RHS="{integer}"),
85 message="cannot add an integer to a float",
87 message="cannot add `{RHS}` to `{Self}`",
88 label="no implementation for `{Self} + {RHS}`",
90 pub trait Add<RHS=Self> {
91 /// The resulting type after applying the `+` operator.
92 #[stable(feature = "rust1", since = "1.0.0")]
95 /// Performs the `+` operation.
96 #[stable(feature = "rust1", since = "1.0.0")]
97 fn add(self, rhs: RHS) -> Self::Output;
100 macro_rules! add_impl {
102 #[stable(feature = "rust1", since = "1.0.0")]
107 #[rustc_inherit_overflow_checks]
108 fn add(self, other: $t) -> $t { self + other }
111 forward_ref_binop! { impl Add, add for $t, $t }
115 add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
117 /// The subtraction operator `-`.
119 /// Note that `RHS` is `Self` by default, but this is not mandatory. For
120 /// example, [`std::time::SystemTime`] implements `Sub<Duration>`, which permits
121 /// operations of the form `SystemTime = SystemTime - Duration`.
123 /// [`std::time::SystemTime`]: ../../std/time/struct.SystemTime.html
127 /// ## `Sub`tractable points
130 /// use std::ops::Sub;
132 /// #[derive(Debug, PartialEq)]
138 /// impl Sub for Point {
139 /// type Output = Point;
141 /// fn sub(self, other: Point) -> Point {
143 /// x: self.x - other.x,
144 /// y: self.y - other.y,
149 /// assert_eq!(Point { x: 3, y: 3 } - Point { x: 2, y: 3 },
150 /// Point { x: 1, y: 0 });
153 /// ## Implementing `Sub` with generics
155 /// Here is an example of the same `Point` struct implementing the `Sub` trait
159 /// use std::ops::Sub;
161 /// #[derive(Debug, PartialEq)]
162 /// struct Point<T> {
167 /// // Notice that the implementation uses the associated type `Output`.
168 /// impl<T: Sub<Output=T>> Sub for Point<T> {
169 /// type Output = Point<T>;
171 /// fn sub(self, other: Point<T>) -> Point<T> {
173 /// x: self.x - other.x,
174 /// y: self.y - other.y,
179 /// assert_eq!(Point { x: 2, y: 3 } - Point { x: 1, y: 0 },
180 /// Point { x: 1, y: 3 });
183 #[stable(feature = "rust1", since = "1.0.0")]
184 #[rustc_on_unimplemented(message="cannot subtract `{RHS}` from `{Self}`",
185 label="no implementation for `{Self} - {RHS}`")]
186 pub trait Sub<RHS=Self> {
187 /// The resulting type after applying the `-` operator.
188 #[stable(feature = "rust1", since = "1.0.0")]
191 /// Performs the `-` operation.
192 #[stable(feature = "rust1", since = "1.0.0")]
193 fn sub(self, rhs: RHS) -> Self::Output;
196 macro_rules! sub_impl {
198 #[stable(feature = "rust1", since = "1.0.0")]
203 #[rustc_inherit_overflow_checks]
204 fn sub(self, other: $t) -> $t { self - other }
207 forward_ref_binop! { impl Sub, sub for $t, $t }
211 sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
213 /// The multiplication operator `*`.
215 /// Note that `RHS` is `Self` by default, but this is not mandatory.
219 /// ## `Mul`tipliable rational numbers
222 /// use std::ops::Mul;
224 /// // By the fundamental theorem of arithmetic, rational numbers in lowest
225 /// // terms are unique. So, by keeping `Rational`s in reduced form, we can
226 /// // derive `Eq` and `PartialEq`.
227 /// #[derive(Debug, Eq, PartialEq)]
228 /// struct Rational {
229 /// nominator: usize,
230 /// denominator: usize,
234 /// fn new(nominator: usize, denominator: usize) -> Self {
235 /// if denominator == 0 {
236 /// panic!("Zero is an invalid denominator!");
239 /// // Reduce to lowest terms by dividing by the greatest common
241 /// let gcd = gcd(nominator, denominator);
243 /// nominator: nominator / gcd,
244 /// denominator: denominator / gcd,
249 /// impl Mul for Rational {
250 /// // The multiplication of rational numbers is a closed operation.
251 /// type Output = Self;
253 /// fn mul(self, rhs: Self) -> Self {
254 /// let nominator = self.nominator * rhs.nominator;
255 /// let denominator = self.denominator * rhs.denominator;
256 /// Rational::new(nominator, denominator)
260 /// // Euclid's two-thousand-year-old algorithm for finding the greatest common
262 /// fn gcd(x: usize, y: usize) -> usize {
273 /// assert_eq!(Rational::new(1, 2), Rational::new(2, 4));
274 /// assert_eq!(Rational::new(2, 3) * Rational::new(3, 4),
275 /// Rational::new(1, 2));
278 /// ## Multiplying vectors by scalars as in linear algebra
281 /// use std::ops::Mul;
283 /// struct Scalar { value: usize }
285 /// #[derive(Debug, PartialEq)]
286 /// struct Vector { value: Vec<usize> }
288 /// impl Mul<Scalar> for Vector {
289 /// type Output = Vector;
291 /// fn mul(self, rhs: Scalar) -> Vector {
292 /// Vector { value: self.value.iter().map(|v| v * rhs.value).collect() }
296 /// let vector = Vector { value: vec![2, 4, 6] };
297 /// let scalar = Scalar { value: 3 };
298 /// assert_eq!(vector * scalar, Vector { value: vec![6, 12, 18] });
301 #[stable(feature = "rust1", since = "1.0.0")]
302 #[rustc_on_unimplemented(message="cannot multiply `{RHS}` to `{Self}`",
303 label="no implementation for `{Self} * {RHS}`")]
304 pub trait Mul<RHS=Self> {
305 /// The resulting type after applying the `*` operator.
306 #[stable(feature = "rust1", since = "1.0.0")]
309 /// Performs the `*` operation.
310 #[stable(feature = "rust1", since = "1.0.0")]
311 fn mul(self, rhs: RHS) -> Self::Output;
314 macro_rules! mul_impl {
316 #[stable(feature = "rust1", since = "1.0.0")]
321 #[rustc_inherit_overflow_checks]
322 fn mul(self, other: $t) -> $t { self * other }
325 forward_ref_binop! { impl Mul, mul for $t, $t }
329 mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
331 /// The division operator `/`.
333 /// Note that `RHS` is `Self` by default, but this is not mandatory.
337 /// ## `Div`idable rational numbers
340 /// use std::ops::Div;
342 /// // By the fundamental theorem of arithmetic, rational numbers in lowest
343 /// // terms are unique. So, by keeping `Rational`s in reduced form, we can
344 /// // derive `Eq` and `PartialEq`.
345 /// #[derive(Debug, Eq, PartialEq)]
346 /// struct Rational {
347 /// nominator: usize,
348 /// denominator: usize,
352 /// fn new(nominator: usize, denominator: usize) -> Self {
353 /// if denominator == 0 {
354 /// panic!("Zero is an invalid denominator!");
357 /// // Reduce to lowest terms by dividing by the greatest common
359 /// let gcd = gcd(nominator, denominator);
361 /// nominator: nominator / gcd,
362 /// denominator: denominator / gcd,
367 /// impl Div for Rational {
368 /// // The division of rational numbers is a closed operation.
369 /// type Output = Self;
371 /// fn div(self, rhs: Self) -> Self {
372 /// if rhs.nominator == 0 {
373 /// panic!("Cannot divide by zero-valued `Rational`!");
376 /// let nominator = self.nominator * rhs.denominator;
377 /// let denominator = self.denominator * rhs.nominator;
378 /// Rational::new(nominator, denominator)
382 /// // Euclid's two-thousand-year-old algorithm for finding the greatest common
384 /// fn gcd(x: usize, y: usize) -> usize {
395 /// assert_eq!(Rational::new(1, 2), Rational::new(2, 4));
396 /// assert_eq!(Rational::new(1, 2) / Rational::new(3, 4),
397 /// Rational::new(2, 3));
400 /// ## Dividing vectors by scalars as in linear algebra
403 /// use std::ops::Div;
405 /// struct Scalar { value: f32 }
407 /// #[derive(Debug, PartialEq)]
408 /// struct Vector { value: Vec<f32> }
410 /// impl Div<Scalar> for Vector {
411 /// type Output = Vector;
413 /// fn div(self, rhs: Scalar) -> Vector {
414 /// Vector { value: self.value.iter().map(|v| v / rhs.value).collect() }
418 /// let scalar = Scalar { value: 2f32 };
419 /// let vector = Vector { value: vec![2f32, 4f32, 6f32] };
420 /// assert_eq!(vector / scalar, Vector { value: vec![1f32, 2f32, 3f32] });
423 #[stable(feature = "rust1", since = "1.0.0")]
424 #[rustc_on_unimplemented(message="cannot divide `{Self}` by `{RHS}`",
425 label="no implementation for `{Self} / {RHS}`")]
426 pub trait Div<RHS=Self> {
427 /// The resulting type after applying the `/` operator.
428 #[stable(feature = "rust1", since = "1.0.0")]
431 /// Performs the `/` operation.
432 #[stable(feature = "rust1", since = "1.0.0")]
433 fn div(self, rhs: RHS) -> Self::Output;
436 macro_rules! div_impl_integer {
438 /// This operation rounds towards zero, truncating any
439 /// fractional part of the exact result.
440 #[stable(feature = "rust1", since = "1.0.0")]
445 fn div(self, other: $t) -> $t { self / other }
448 forward_ref_binop! { impl Div, div for $t, $t }
452 div_impl_integer! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
454 macro_rules! div_impl_float {
456 #[stable(feature = "rust1", since = "1.0.0")]
461 fn div(self, other: $t) -> $t { self / other }
464 forward_ref_binop! { impl Div, div for $t, $t }
468 div_impl_float! { f32 f64 }
470 /// The remainder operator `%`.
472 /// Note that `RHS` is `Self` by default, but this is not mandatory.
476 /// This example implements `Rem` on a `SplitSlice` object. After `Rem` is
477 /// implemented, one can use the `%` operator to find out what the remaining
478 /// elements of the slice would be after splitting it into equal slices of a
482 /// use std::ops::Rem;
484 /// #[derive(PartialEq, Debug)]
485 /// struct SplitSlice<'a, T: 'a> {
489 /// impl<'a, T> Rem<usize> for SplitSlice<'a, T> {
490 /// type Output = SplitSlice<'a, T>;
492 /// fn rem(self, modulus: usize) -> Self {
493 /// let len = self.slice.len();
494 /// let rem = len % modulus;
495 /// let start = len - rem;
496 /// SplitSlice {slice: &self.slice[start..]}
500 /// // If we were to divide &[0, 1, 2, 3, 4, 5, 6, 7] into slices of size 3,
501 /// // the remainder would be &[6, 7].
502 /// assert_eq!(SplitSlice { slice: &[0, 1, 2, 3, 4, 5, 6, 7] } % 3,
503 /// SplitSlice { slice: &[6, 7] });
506 #[stable(feature = "rust1", since = "1.0.0")]
507 #[rustc_on_unimplemented(message="cannot mod `{Self}` by `{RHS}`",
508 label="no implementation for `{Self} % {RHS}`")]
509 pub trait Rem<RHS=Self> {
510 /// The resulting type after applying the `%` operator.
511 #[stable(feature = "rust1", since = "1.0.0")]
514 /// Performs the `%` operation.
515 #[stable(feature = "rust1", since = "1.0.0")]
516 fn rem(self, rhs: RHS) -> Self::Output;
519 macro_rules! rem_impl_integer {
521 /// This operation satisfies `n % d == n - (n / d) * d`. The
522 /// result has the same sign as the left operand.
523 #[stable(feature = "rust1", since = "1.0.0")]
528 fn rem(self, other: $t) -> $t { self % other }
531 forward_ref_binop! { impl Rem, rem for $t, $t }
535 rem_impl_integer! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
538 macro_rules! rem_impl_float {
540 #[stable(feature = "rust1", since = "1.0.0")]
545 fn rem(self, other: $t) -> $t { self % other }
548 forward_ref_binop! { impl Rem, rem for $t, $t }
552 rem_impl_float! { f32 f64 }
554 /// The unary negation operator `-`.
558 /// An implementation of `Neg` for `Sign`, which allows the use of `-` to
559 /// negate its value.
562 /// use std::ops::Neg;
564 /// #[derive(Debug, PartialEq)]
571 /// impl Neg for Sign {
572 /// type Output = Sign;
574 /// fn neg(self) -> Sign {
576 /// Sign::Negative => Sign::Positive,
577 /// Sign::Zero => Sign::Zero,
578 /// Sign::Positive => Sign::Negative,
583 /// // A negative positive is a negative.
584 /// assert_eq!(-Sign::Positive, Sign::Negative);
585 /// // A double negative is a positive.
586 /// assert_eq!(-Sign::Negative, Sign::Positive);
587 /// // Zero is its own negation.
588 /// assert_eq!(-Sign::Zero, Sign::Zero);
591 #[stable(feature = "rust1", since = "1.0.0")]
593 /// The resulting type after applying the `-` operator.
594 #[stable(feature = "rust1", since = "1.0.0")]
597 /// Performs the unary `-` operation.
598 #[stable(feature = "rust1", since = "1.0.0")]
599 fn neg(self) -> Self::Output;
604 macro_rules! neg_impl_core {
605 ($id:ident => $body:expr, $($t:ty)*) => ($(
606 #[stable(feature = "rust1", since = "1.0.0")]
611 #[rustc_inherit_overflow_checks]
612 fn neg(self) -> $t { let $id = self; $body }
615 forward_ref_unop! { impl Neg, neg for $t }
619 macro_rules! neg_impl_numeric {
620 ($($t:ty)*) => { neg_impl_core!{ x => -x, $($t)*} }
623 #[allow(unused_macros)]
624 macro_rules! neg_impl_unsigned {
626 neg_impl_core!{ x => {
631 // neg_impl_unsigned! { usize u8 u16 u32 u64 }
632 neg_impl_numeric! { isize i8 i16 i32 i64 i128 f32 f64 }
634 /// The addition assignment operator `+=`.
638 /// This example creates a `Point` struct that implements the `AddAssign`
639 /// trait, and then demonstrates add-assigning to a mutable `Point`.
642 /// use std::ops::AddAssign;
644 /// #[derive(Debug, PartialEq)]
650 /// impl AddAssign for Point {
651 /// fn add_assign(&mut self, other: Point) {
653 /// x: self.x + other.x,
654 /// y: self.y + other.y,
659 /// let mut point = Point { x: 1, y: 0 };
660 /// point += Point { x: 2, y: 3 };
661 /// assert_eq!(point, Point { x: 3, y: 3 });
663 #[lang = "add_assign"]
664 #[stable(feature = "op_assign_traits", since = "1.8.0")]
665 #[rustc_on_unimplemented(message="cannot add-assign `{Rhs}` to `{Self}`",
666 label="no implementation for `{Self} += {Rhs}`")]
667 pub trait AddAssign<Rhs=Self> {
668 /// Performs the `+=` operation.
669 #[stable(feature = "op_assign_traits", since = "1.8.0")]
670 fn add_assign(&mut self, rhs: Rhs);
673 macro_rules! add_assign_impl {
675 #[stable(feature = "op_assign_traits", since = "1.8.0")]
676 impl AddAssign for $t {
678 #[rustc_inherit_overflow_checks]
679 fn add_assign(&mut self, other: $t) { *self += other }
682 forward_ref_op_assign! { impl AddAssign, add_assign for $t, $t }
686 add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
688 /// The subtraction assignment operator `-=`.
692 /// This example creates a `Point` struct that implements the `SubAssign`
693 /// trait, and then demonstrates sub-assigning to a mutable `Point`.
696 /// use std::ops::SubAssign;
698 /// #[derive(Debug, PartialEq)]
704 /// impl SubAssign for Point {
705 /// fn sub_assign(&mut self, other: Point) {
707 /// x: self.x - other.x,
708 /// y: self.y - other.y,
713 /// let mut point = Point { x: 3, y: 3 };
714 /// point -= Point { x: 2, y: 3 };
715 /// assert_eq!(point, Point {x: 1, y: 0});
717 #[lang = "sub_assign"]
718 #[stable(feature = "op_assign_traits", since = "1.8.0")]
719 #[rustc_on_unimplemented(message="cannot subtract-assign `{Rhs}` from `{Self}`",
720 label="no implementation for `{Self} -= {Rhs}`")]
721 pub trait SubAssign<Rhs=Self> {
722 /// Performs the `-=` operation.
723 #[stable(feature = "op_assign_traits", since = "1.8.0")]
724 fn sub_assign(&mut self, rhs: Rhs);
727 macro_rules! sub_assign_impl {
729 #[stable(feature = "op_assign_traits", since = "1.8.0")]
730 impl SubAssign for $t {
732 #[rustc_inherit_overflow_checks]
733 fn sub_assign(&mut self, other: $t) { *self -= other }
736 forward_ref_op_assign! { impl SubAssign, sub_assign for $t, $t }
740 sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
742 /// The multiplication assignment operator `*=`.
747 /// use std::ops::MulAssign;
749 /// #[derive(Debug, PartialEq)]
750 /// struct Frequency { hertz: f64 }
752 /// impl MulAssign<f64> for Frequency {
753 /// fn mul_assign(&mut self, rhs: f64) {
754 /// self.hertz *= rhs;
758 /// let mut frequency = Frequency { hertz: 50.0 };
759 /// frequency *= 4.0;
760 /// assert_eq!(Frequency { hertz: 200.0 }, frequency);
762 #[lang = "mul_assign"]
763 #[stable(feature = "op_assign_traits", since = "1.8.0")]
764 #[rustc_on_unimplemented(message="cannot multiply-assign `{Rhs}` to `{Self}`",
765 label="no implementation for `{Self} *= {Rhs}`")]
766 pub trait MulAssign<Rhs=Self> {
767 /// Performs the `*=` operation.
768 #[stable(feature = "op_assign_traits", since = "1.8.0")]
769 fn mul_assign(&mut self, rhs: Rhs);
772 macro_rules! mul_assign_impl {
774 #[stable(feature = "op_assign_traits", since = "1.8.0")]
775 impl MulAssign for $t {
777 #[rustc_inherit_overflow_checks]
778 fn mul_assign(&mut self, other: $t) { *self *= other }
781 forward_ref_op_assign! { impl MulAssign, mul_assign for $t, $t }
785 mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
787 /// The division assignment operator `/=`.
792 /// use std::ops::DivAssign;
794 /// #[derive(Debug, PartialEq)]
795 /// struct Frequency { hertz: f64 }
797 /// impl DivAssign<f64> for Frequency {
798 /// fn div_assign(&mut self, rhs: f64) {
799 /// self.hertz /= rhs;
803 /// let mut frequency = Frequency { hertz: 200.0 };
804 /// frequency /= 4.0;
805 /// assert_eq!(Frequency { hertz: 50.0 }, frequency);
807 #[lang = "div_assign"]
808 #[stable(feature = "op_assign_traits", since = "1.8.0")]
809 #[rustc_on_unimplemented(message="cannot divide-assign `{Self}` by `{Rhs}`",
810 label="no implementation for `{Self} /= {Rhs}`")]
811 pub trait DivAssign<Rhs=Self> {
812 /// Performs the `/=` operation.
813 #[stable(feature = "op_assign_traits", since = "1.8.0")]
814 fn div_assign(&mut self, rhs: Rhs);
817 macro_rules! div_assign_impl {
819 #[stable(feature = "op_assign_traits", since = "1.8.0")]
820 impl DivAssign for $t {
822 fn div_assign(&mut self, other: $t) { *self /= other }
825 forward_ref_op_assign! { impl DivAssign, div_assign for $t, $t }
829 div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
831 /// The remainder assignment operator `%=`.
836 /// use std::ops::RemAssign;
838 /// struct CookieJar { cookies: u32 }
840 /// impl RemAssign<u32> for CookieJar {
841 /// fn rem_assign(&mut self, piles: u32) {
842 /// self.cookies %= piles;
846 /// let mut jar = CookieJar { cookies: 31 };
849 /// println!("Splitting up {} cookies into {} even piles!", jar.cookies, piles);
853 /// println!("{} cookies remain in the cookie jar!", jar.cookies);
855 #[lang = "rem_assign"]
856 #[stable(feature = "op_assign_traits", since = "1.8.0")]
857 #[rustc_on_unimplemented(message="cannot mod-assign `{Self}` by `{Rhs}``",
858 label="no implementation for `{Self} %= {Rhs}`")]
859 pub trait RemAssign<Rhs=Self> {
860 /// Performs the `%=` operation.
861 #[stable(feature = "op_assign_traits", since = "1.8.0")]
862 fn rem_assign(&mut self, rhs: Rhs);
865 macro_rules! rem_assign_impl {
867 #[stable(feature = "op_assign_traits", since = "1.8.0")]
868 impl RemAssign for $t {
870 fn rem_assign(&mut self, other: $t) { *self %= other }
873 forward_ref_op_assign! { impl RemAssign, rem_assign for $t, $t }
877 rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }