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 = "no implementation for `{Self} + {RHS}`"]
79 pub trait Add<RHS=Self> {
80 /// The resulting type after applying the `+` operator.
81 #[stable(feature = "rust1", since = "1.0.0")]
84 /// Performs the `+` operation.
85 #[stable(feature = "rust1", since = "1.0.0")]
86 fn add(self, rhs: RHS) -> Self::Output;
89 macro_rules! add_impl {
91 #[stable(feature = "rust1", since = "1.0.0")]
96 #[rustc_inherit_overflow_checks]
97 fn add(self, other: $t) -> $t { self + other }
100 forward_ref_binop! { impl Add, add for $t, $t }
104 add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
106 /// The subtraction operator `-`.
108 /// Note that `RHS` is `Self` by default, but this is not mandatory. For
109 /// example, [`std::time::SystemTime`] implements `Sub<Duration>`, which permits
110 /// operations of the form `SystemTime = SystemTime - Duration`.
112 /// [`std::time::SystemTime`]: ../../std/time/struct.SystemTime.html
116 /// ## `Sub`tractable points
119 /// use std::ops::Sub;
121 /// #[derive(Debug, PartialEq)]
127 /// impl Sub for Point {
128 /// type Output = Point;
130 /// fn sub(self, other: Point) -> Point {
132 /// x: self.x - other.x,
133 /// y: self.y - other.y,
138 /// assert_eq!(Point { x: 3, y: 3 } - Point { x: 2, y: 3 },
139 /// Point { x: 1, y: 0 });
142 /// ## Implementing `Sub` with generics
144 /// Here is an example of the same `Point` struct implementing the `Sub` trait
148 /// use std::ops::Sub;
150 /// #[derive(Debug, PartialEq)]
151 /// struct Point<T> {
156 /// // Notice that the implementation uses the associated type `Output`.
157 /// impl<T: Sub<Output=T>> Sub for Point<T> {
158 /// type Output = Point<T>;
160 /// fn sub(self, other: Point<T>) -> Point<T> {
162 /// x: self.x - other.x,
163 /// y: self.y - other.y,
168 /// assert_eq!(Point { x: 2, y: 3 } - Point { x: 1, y: 0 },
169 /// Point { x: 1, y: 3 });
172 #[stable(feature = "rust1", since = "1.0.0")]
173 #[rustc_on_unimplemented = "no implementation for `{Self} - {RHS}`"]
174 pub trait Sub<RHS=Self> {
175 /// The resulting type after applying the `-` operator.
176 #[stable(feature = "rust1", since = "1.0.0")]
179 /// Performs the `-` operation.
180 #[stable(feature = "rust1", since = "1.0.0")]
181 fn sub(self, rhs: RHS) -> Self::Output;
184 macro_rules! sub_impl {
186 #[stable(feature = "rust1", since = "1.0.0")]
191 #[rustc_inherit_overflow_checks]
192 fn sub(self, other: $t) -> $t { self - other }
195 forward_ref_binop! { impl Sub, sub for $t, $t }
199 sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
201 /// The multiplication operator `*`.
203 /// Note that `RHS` is `Self` by default, but this is not mandatory.
207 /// ## `Mul`tipliable rational numbers
210 /// use std::ops::Mul;
212 /// // By the fundamental theorem of arithmetic, rational numbers in lowest
213 /// // terms are unique. So, by keeping `Rational`s in reduced form, we can
214 /// // derive `Eq` and `PartialEq`.
215 /// #[derive(Debug, Eq, PartialEq)]
216 /// struct Rational {
217 /// nominator: usize,
218 /// denominator: usize,
222 /// fn new(nominator: usize, denominator: usize) -> Self {
223 /// if denominator == 0 {
224 /// panic!("Zero is an invalid denominator!");
227 /// // Reduce to lowest terms by dividing by the greatest common
229 /// let gcd = gcd(nominator, denominator);
231 /// nominator: nominator / gcd,
232 /// denominator: denominator / gcd,
237 /// impl Mul for Rational {
238 /// // The multiplication of rational numbers is a closed operation.
239 /// type Output = Self;
241 /// fn mul(self, rhs: Self) -> Self {
242 /// let nominator = self.nominator * rhs.nominator;
243 /// let denominator = self.denominator * rhs.denominator;
244 /// Rational::new(nominator, denominator)
248 /// // Euclid's two-thousand-year-old algorithm for finding the greatest common
250 /// fn gcd(x: usize, y: usize) -> usize {
261 /// assert_eq!(Rational::new(1, 2), Rational::new(2, 4));
262 /// assert_eq!(Rational::new(2, 3) * Rational::new(3, 4),
263 /// Rational::new(1, 2));
266 /// ## Multiplying vectors by scalars as in linear algebra
269 /// use std::ops::Mul;
271 /// struct Scalar { value: usize }
273 /// #[derive(Debug, PartialEq)]
274 /// struct Vector { value: Vec<usize> }
276 /// impl Mul<Scalar> for Vector {
277 /// type Output = Vector;
279 /// fn mul(self, rhs: Scalar) -> Vector {
280 /// Vector { value: self.value.iter().map(|v| v * rhs.value).collect() }
284 /// let vector = Vector { value: vec![2, 4, 6] };
285 /// let scalar = Scalar { value: 3 };
286 /// assert_eq!(vector * scalar, Vector { value: vec![6, 12, 18] });
289 #[stable(feature = "rust1", since = "1.0.0")]
290 #[rustc_on_unimplemented = "no implementation for `{Self} * {RHS}`"]
291 pub trait Mul<RHS=Self> {
292 /// The resulting type after applying the `*` operator.
293 #[stable(feature = "rust1", since = "1.0.0")]
296 /// Performs the `*` operation.
297 #[stable(feature = "rust1", since = "1.0.0")]
298 fn mul(self, rhs: RHS) -> Self::Output;
301 macro_rules! mul_impl {
303 #[stable(feature = "rust1", since = "1.0.0")]
308 #[rustc_inherit_overflow_checks]
309 fn mul(self, other: $t) -> $t { self * other }
312 forward_ref_binop! { impl Mul, mul for $t, $t }
316 mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
318 /// The division operator `/`.
320 /// Note that `RHS` is `Self` by default, but this is not mandatory.
324 /// ## `Div`idable rational numbers
327 /// use std::ops::Div;
329 /// // By the fundamental theorem of arithmetic, rational numbers in lowest
330 /// // terms are unique. So, by keeping `Rational`s in reduced form, we can
331 /// // derive `Eq` and `PartialEq`.
332 /// #[derive(Debug, Eq, PartialEq)]
333 /// struct Rational {
334 /// nominator: usize,
335 /// denominator: usize,
339 /// fn new(nominator: usize, denominator: usize) -> Self {
340 /// if denominator == 0 {
341 /// panic!("Zero is an invalid denominator!");
344 /// // Reduce to lowest terms by dividing by the greatest common
346 /// let gcd = gcd(nominator, denominator);
348 /// nominator: nominator / gcd,
349 /// denominator: denominator / gcd,
354 /// impl Div for Rational {
355 /// // The division of rational numbers is a closed operation.
356 /// type Output = Self;
358 /// fn div(self, rhs: Self) -> Self {
359 /// if rhs.nominator == 0 {
360 /// panic!("Cannot divide by zero-valued `Rational`!");
363 /// let nominator = self.nominator * rhs.denominator;
364 /// let denominator = self.denominator * rhs.nominator;
365 /// Rational::new(nominator, denominator)
369 /// // Euclid's two-thousand-year-old algorithm for finding the greatest common
371 /// fn gcd(x: usize, y: usize) -> usize {
382 /// assert_eq!(Rational::new(1, 2), Rational::new(2, 4));
383 /// assert_eq!(Rational::new(1, 2) / Rational::new(3, 4),
384 /// Rational::new(2, 3));
387 /// ## Dividing vectors by scalars as in linear algebra
390 /// use std::ops::Div;
392 /// struct Scalar { value: f32 }
394 /// #[derive(Debug, PartialEq)]
395 /// struct Vector { value: Vec<f32> }
397 /// impl Div<Scalar> for Vector {
398 /// type Output = Vector;
400 /// fn div(self, rhs: Scalar) -> Vector {
401 /// Vector { value: self.value.iter().map(|v| v / rhs.value).collect() }
405 /// let scalar = Scalar { value: 2f32 };
406 /// let vector = Vector { value: vec![2f32, 4f32, 6f32] };
407 /// assert_eq!(vector / scalar, Vector { value: vec![1f32, 2f32, 3f32] });
410 #[stable(feature = "rust1", since = "1.0.0")]
411 #[rustc_on_unimplemented = "no implementation for `{Self} / {RHS}`"]
412 pub trait Div<RHS=Self> {
413 /// The resulting type after applying the `/` operator.
414 #[stable(feature = "rust1", since = "1.0.0")]
417 /// Performs the `/` operation.
418 #[stable(feature = "rust1", since = "1.0.0")]
419 fn div(self, rhs: RHS) -> Self::Output;
422 macro_rules! div_impl_integer {
424 /// This operation rounds towards zero, truncating any
425 /// fractional part of the exact result.
426 #[stable(feature = "rust1", since = "1.0.0")]
431 fn div(self, other: $t) -> $t { self / other }
434 forward_ref_binop! { impl Div, div for $t, $t }
438 div_impl_integer! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
440 macro_rules! div_impl_float {
442 #[stable(feature = "rust1", since = "1.0.0")]
447 fn div(self, other: $t) -> $t { self / other }
450 forward_ref_binop! { impl Div, div for $t, $t }
454 div_impl_float! { f32 f64 }
456 /// The remainder operator `%`.
458 /// Note that `RHS` is `Self` by default, but this is not mandatory.
462 /// This example implements `Rem` on a `SplitSlice` object. After `Rem` is
463 /// implemented, one can use the `%` operator to find out what the remaining
464 /// elements of the slice would be after splitting it into equal slices of a
468 /// use std::ops::Rem;
470 /// #[derive(PartialEq, Debug)]
471 /// struct SplitSlice<'a, T: 'a> {
475 /// impl<'a, T> Rem<usize> for SplitSlice<'a, T> {
476 /// type Output = SplitSlice<'a, T>;
478 /// fn rem(self, modulus: usize) -> Self {
479 /// let len = self.slice.len();
480 /// let rem = len % modulus;
481 /// let start = len - rem;
482 /// SplitSlice {slice: &self.slice[start..]}
486 /// // If we were to divide &[0, 1, 2, 3, 4, 5, 6, 7] into slices of size 3,
487 /// // the remainder would be &[6, 7].
488 /// assert_eq!(SplitSlice { slice: &[0, 1, 2, 3, 4, 5, 6, 7] } % 3,
489 /// SplitSlice { slice: &[6, 7] });
492 #[stable(feature = "rust1", since = "1.0.0")]
493 #[rustc_on_unimplemented = "no implementation for `{Self} % {RHS}`"]
494 pub trait Rem<RHS=Self> {
495 /// The resulting type after applying the `%` operator.
496 #[stable(feature = "rust1", since = "1.0.0")]
499 /// Performs the `%` operation.
500 #[stable(feature = "rust1", since = "1.0.0")]
501 fn rem(self, rhs: RHS) -> Self::Output;
504 macro_rules! rem_impl_integer {
506 /// This operation satisfies `n % d == n - (n / d) * d`. The
507 /// result has the same sign as the left operand.
508 #[stable(feature = "rust1", since = "1.0.0")]
513 fn rem(self, other: $t) -> $t { self % other }
516 forward_ref_binop! { impl Rem, rem for $t, $t }
520 rem_impl_integer! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
523 macro_rules! rem_impl_float {
525 #[stable(feature = "rust1", since = "1.0.0")]
530 fn rem(self, other: $t) -> $t { self % other }
533 forward_ref_binop! { impl Rem, rem for $t, $t }
537 rem_impl_float! { f32 f64 }
539 /// The unary negation operator `-`.
543 /// An implementation of `Neg` for `Sign`, which allows the use of `-` to
544 /// negate its value.
547 /// use std::ops::Neg;
549 /// #[derive(Debug, PartialEq)]
556 /// impl Neg for Sign {
557 /// type Output = Sign;
559 /// fn neg(self) -> Sign {
561 /// Sign::Negative => Sign::Positive,
562 /// Sign::Zero => Sign::Zero,
563 /// Sign::Positive => Sign::Negative,
568 /// // A negative positive is a negative.
569 /// assert_eq!(-Sign::Positive, Sign::Negative);
570 /// // A double negative is a positive.
571 /// assert_eq!(-Sign::Negative, Sign::Positive);
572 /// // Zero is its own negation.
573 /// assert_eq!(-Sign::Zero, Sign::Zero);
576 #[stable(feature = "rust1", since = "1.0.0")]
578 /// The resulting type after applying the `-` operator.
579 #[stable(feature = "rust1", since = "1.0.0")]
582 /// Performs the unary `-` operation.
583 #[stable(feature = "rust1", since = "1.0.0")]
584 fn neg(self) -> Self::Output;
589 macro_rules! neg_impl_core {
590 ($id:ident => $body:expr, $($t:ty)*) => ($(
591 #[stable(feature = "rust1", since = "1.0.0")]
596 #[rustc_inherit_overflow_checks]
597 fn neg(self) -> $t { let $id = self; $body }
600 forward_ref_unop! { impl Neg, neg for $t }
604 macro_rules! neg_impl_numeric {
605 ($($t:ty)*) => { neg_impl_core!{ x => -x, $($t)*} }
608 #[allow(unused_macros)]
609 macro_rules! neg_impl_unsigned {
611 neg_impl_core!{ x => {
616 // neg_impl_unsigned! { usize u8 u16 u32 u64 }
617 neg_impl_numeric! { isize i8 i16 i32 i64 i128 f32 f64 }
619 /// The addition assignment operator `+=`.
623 /// This example creates a `Point` struct that implements the `AddAssign`
624 /// trait, and then demonstrates add-assigning to a mutable `Point`.
627 /// use std::ops::AddAssign;
629 /// #[derive(Debug, PartialEq)]
635 /// impl AddAssign for Point {
636 /// fn add_assign(&mut self, other: Point) {
638 /// x: self.x + other.x,
639 /// y: self.y + other.y,
644 /// let mut point = Point { x: 1, y: 0 };
645 /// point += Point { x: 2, y: 3 };
646 /// assert_eq!(point, Point { x: 3, y: 3 });
648 #[lang = "add_assign"]
649 #[stable(feature = "op_assign_traits", since = "1.8.0")]
650 #[rustc_on_unimplemented = "no implementation for `{Self} += {Rhs}`"]
651 pub trait AddAssign<Rhs=Self> {
652 /// Performs the `+=` operation.
653 #[stable(feature = "op_assign_traits", since = "1.8.0")]
654 fn add_assign(&mut self, rhs: Rhs);
657 macro_rules! add_assign_impl {
659 #[stable(feature = "op_assign_traits", since = "1.8.0")]
660 impl AddAssign for $t {
662 #[rustc_inherit_overflow_checks]
663 fn add_assign(&mut self, other: $t) { *self += other }
666 forward_ref_op_assign! { impl AddAssign, add_assign for $t, $t }
670 add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
672 /// The subtraction assignment operator `-=`.
676 /// This example creates a `Point` struct that implements the `SubAssign`
677 /// trait, and then demonstrates sub-assigning to a mutable `Point`.
680 /// use std::ops::SubAssign;
682 /// #[derive(Debug, PartialEq)]
688 /// impl SubAssign for Point {
689 /// fn sub_assign(&mut self, other: Point) {
691 /// x: self.x - other.x,
692 /// y: self.y - other.y,
697 /// let mut point = Point { x: 3, y: 3 };
698 /// point -= Point { x: 2, y: 3 };
699 /// assert_eq!(point, Point {x: 1, y: 0});
701 #[lang = "sub_assign"]
702 #[stable(feature = "op_assign_traits", since = "1.8.0")]
703 #[rustc_on_unimplemented = "no implementation for `{Self} -= {Rhs}`"]
704 pub trait SubAssign<Rhs=Self> {
705 /// Performs the `-=` operation.
706 #[stable(feature = "op_assign_traits", since = "1.8.0")]
707 fn sub_assign(&mut self, rhs: Rhs);
710 macro_rules! sub_assign_impl {
712 #[stable(feature = "op_assign_traits", since = "1.8.0")]
713 impl SubAssign for $t {
715 #[rustc_inherit_overflow_checks]
716 fn sub_assign(&mut self, other: $t) { *self -= other }
719 forward_ref_op_assign! { impl SubAssign, sub_assign for $t, $t }
723 sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
725 /// The multiplication assignment operator `*=`.
730 /// use std::ops::MulAssign;
732 /// #[derive(Debug, PartialEq)]
733 /// struct Frequency { hertz: f64 }
735 /// impl MulAssign<f64> for Frequency {
736 /// fn mul_assign(&mut self, rhs: f64) {
737 /// self.hertz *= rhs;
741 /// let mut frequency = Frequency { hertz: 50.0 };
742 /// frequency *= 4.0;
743 /// assert_eq!(Frequency { hertz: 200.0 }, frequency);
745 #[lang = "mul_assign"]
746 #[stable(feature = "op_assign_traits", since = "1.8.0")]
747 #[rustc_on_unimplemented = "no implementation for `{Self} *= {Rhs}`"]
748 pub trait MulAssign<Rhs=Self> {
749 /// Performs the `*=` operation.
750 #[stable(feature = "op_assign_traits", since = "1.8.0")]
751 fn mul_assign(&mut self, rhs: Rhs);
754 macro_rules! mul_assign_impl {
756 #[stable(feature = "op_assign_traits", since = "1.8.0")]
757 impl MulAssign for $t {
759 #[rustc_inherit_overflow_checks]
760 fn mul_assign(&mut self, other: $t) { *self *= other }
763 forward_ref_op_assign! { impl MulAssign, mul_assign for $t, $t }
767 mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
769 /// The division assignment operator `/=`.
774 /// use std::ops::DivAssign;
776 /// #[derive(Debug, PartialEq)]
777 /// struct Frequency { hertz: f64 }
779 /// impl DivAssign<f64> for Frequency {
780 /// fn div_assign(&mut self, rhs: f64) {
781 /// self.hertz /= rhs;
785 /// let mut frequency = Frequency { hertz: 200.0 };
786 /// frequency /= 4.0;
787 /// assert_eq!(Frequency { hertz: 50.0 }, frequency);
789 #[lang = "div_assign"]
790 #[stable(feature = "op_assign_traits", since = "1.8.0")]
791 #[rustc_on_unimplemented = "no implementation for `{Self} /= {Rhs}`"]
792 pub trait DivAssign<Rhs=Self> {
793 /// Performs the `/=` operation.
794 #[stable(feature = "op_assign_traits", since = "1.8.0")]
795 fn div_assign(&mut self, rhs: Rhs);
798 macro_rules! div_assign_impl {
800 #[stable(feature = "op_assign_traits", since = "1.8.0")]
801 impl DivAssign for $t {
803 fn div_assign(&mut self, other: $t) { *self /= other }
806 forward_ref_op_assign! { impl DivAssign, div_assign for $t, $t }
810 div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
812 /// The remainder assignment operator `%=`.
817 /// use std::ops::RemAssign;
819 /// struct CookieJar { cookies: u32 }
821 /// impl RemAssign<u32> for CookieJar {
822 /// fn rem_assign(&mut self, piles: u32) {
823 /// self.cookies %= piles;
827 /// let mut jar = CookieJar { cookies: 31 };
830 /// println!("Splitting up {} cookies into {} even piles!", jar.cookies, piles);
834 /// println!("{} cookies remain in the cookie jar!", jar.cookies);
836 #[lang = "rem_assign"]
837 #[stable(feature = "op_assign_traits", since = "1.8.0")]
838 #[rustc_on_unimplemented = "no implementation for `{Self} %= {Rhs}`"]
839 pub trait RemAssign<Rhs=Self> {
840 /// Performs the `%=` operation.
841 #[stable(feature = "op_assign_traits", since = "1.8.0")]
842 fn rem_assign(&mut self, rhs: Rhs);
845 macro_rules! rem_assign_impl {
847 #[stable(feature = "op_assign_traits", since = "1.8.0")]
848 impl RemAssign for $t {
850 fn rem_assign(&mut self, other: $t) { *self %= other }
853 forward_ref_op_assign! { impl RemAssign, rem_assign for $t, $t }
857 rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }