]> git.proxmox.com Git - rustc.git/blame - src/libcore/ops/arith.rs
New upstream version 1.22.1+dfsg1
[rustc.git] / src / libcore / ops / arith.rs
CommitLineData
041b39d2
XL
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
11/// The addition operator `+`.
12///
3b2f2976
XL
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`.
16///
17/// [`std::time::SystemTime`]: ../../std/time/struct.SystemTime.html
18///
041b39d2
XL
19/// # Examples
20///
3b2f2976 21/// ## `Add`able points
041b39d2
XL
22///
23/// ```
24/// use std::ops::Add;
25///
3b2f2976 26/// #[derive(Debug, PartialEq)]
041b39d2
XL
27/// struct Point {
28/// x: i32,
29/// y: i32,
30/// }
31///
32/// impl Add for Point {
33/// type Output = Point;
34///
35/// fn add(self, other: Point) -> Point {
36/// Point {
37/// x: self.x + other.x,
38/// y: self.y + other.y,
39/// }
40/// }
41/// }
42///
3b2f2976
XL
43/// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
44/// Point { x: 3, y: 3 });
041b39d2
XL
45/// ```
46///
3b2f2976
XL
47/// ## Implementing `Add` with generics
48///
041b39d2
XL
49/// Here is an example of the same `Point` struct implementing the `Add` trait
50/// using generics.
51///
52/// ```
53/// use std::ops::Add;
54///
3b2f2976 55/// #[derive(Debug, PartialEq)]
041b39d2
XL
56/// struct Point<T> {
57/// x: T,
58/// y: T,
59/// }
60///
3b2f2976 61/// // Notice that the implementation uses the associated type `Output`.
041b39d2
XL
62/// impl<T: Add<Output=T>> Add for Point<T> {
63/// type Output = Point<T>;
64///
65/// fn add(self, other: Point<T>) -> Point<T> {
66/// Point {
67/// x: self.x + other.x,
68/// y: self.y + other.y,
69/// }
70/// }
71/// }
72///
3b2f2976
XL
73/// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
74/// Point { x: 3, y: 3 });
041b39d2 75/// ```
041b39d2
XL
76#[lang = "add"]
77#[stable(feature = "rust1", since = "1.0.0")]
78#[rustc_on_unimplemented = "no implementation for `{Self} + {RHS}`"]
79pub trait Add<RHS=Self> {
3b2f2976 80 /// The resulting type after applying the `+` operator.
041b39d2
XL
81 #[stable(feature = "rust1", since = "1.0.0")]
82 type Output;
83
3b2f2976 84 /// Performs the `+` operation.
041b39d2
XL
85 #[stable(feature = "rust1", since = "1.0.0")]
86 fn add(self, rhs: RHS) -> Self::Output;
87}
88
89macro_rules! add_impl {
90 ($($t:ty)*) => ($(
91 #[stable(feature = "rust1", since = "1.0.0")]
92 impl Add for $t {
93 type Output = $t;
94
95 #[inline]
96 #[rustc_inherit_overflow_checks]
97 fn add(self, other: $t) -> $t { self + other }
98 }
99
100 forward_ref_binop! { impl Add, add for $t, $t }
101 )*)
102}
103
104add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
105
106/// The subtraction operator `-`.
107///
3b2f2976
XL
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`.
111///
112/// [`std::time::SystemTime`]: ../../std/time/struct.SystemTime.html
113///
041b39d2
XL
114/// # Examples
115///
3b2f2976 116/// ## `Sub`tractable points
041b39d2
XL
117///
118/// ```
119/// use std::ops::Sub;
120///
3b2f2976 121/// #[derive(Debug, PartialEq)]
041b39d2
XL
122/// struct Point {
123/// x: i32,
124/// y: i32,
125/// }
126///
127/// impl Sub for Point {
128/// type Output = Point;
129///
130/// fn sub(self, other: Point) -> Point {
131/// Point {
132/// x: self.x - other.x,
133/// y: self.y - other.y,
134/// }
135/// }
136/// }
137///
3b2f2976
XL
138/// assert_eq!(Point { x: 3, y: 3 } - Point { x: 2, y: 3 },
139/// Point { x: 1, y: 0 });
140/// ```
141///
142/// ## Implementing `Sub` with generics
143///
144/// Here is an example of the same `Point` struct implementing the `Sub` trait
145/// using generics.
041b39d2 146///
041b39d2 147/// ```
3b2f2976 148/// use std::ops::Sub;
041b39d2 149///
3b2f2976
XL
150/// #[derive(Debug, PartialEq)]
151/// struct Point<T> {
152/// x: T,
153/// y: T,
154/// }
041b39d2 155///
3b2f2976
XL
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>;
159///
160/// fn sub(self, other: Point<T>) -> Point<T> {
161/// Point {
162/// x: self.x - other.x,
163/// y: self.y - other.y,
164/// }
165/// }
166/// }
167///
168/// assert_eq!(Point { x: 2, y: 3 } - Point { x: 1, y: 0 },
169/// Point { x: 1, y: 3 });
170/// ```
041b39d2
XL
171#[lang = "sub"]
172#[stable(feature = "rust1", since = "1.0.0")]
173#[rustc_on_unimplemented = "no implementation for `{Self} - {RHS}`"]
174pub trait Sub<RHS=Self> {
3b2f2976 175 /// The resulting type after applying the `-` operator.
041b39d2
XL
176 #[stable(feature = "rust1", since = "1.0.0")]
177 type Output;
178
3b2f2976 179 /// Performs the `-` operation.
041b39d2
XL
180 #[stable(feature = "rust1", since = "1.0.0")]
181 fn sub(self, rhs: RHS) -> Self::Output;
182}
183
184macro_rules! sub_impl {
185 ($($t:ty)*) => ($(
186 #[stable(feature = "rust1", since = "1.0.0")]
187 impl Sub for $t {
188 type Output = $t;
189
190 #[inline]
191 #[rustc_inherit_overflow_checks]
192 fn sub(self, other: $t) -> $t { self - other }
193 }
194
195 forward_ref_binop! { impl Sub, sub for $t, $t }
196 )*)
197}
198
199sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
200
201/// The multiplication operator `*`.
202///
3b2f2976
XL
203/// Note that `RHS` is `Self` by default, but this is not mandatory.
204///
041b39d2
XL
205/// # Examples
206///
3b2f2976 207/// ## `Mul`tipliable rational numbers
041b39d2
XL
208///
209/// ```
210/// use std::ops::Mul;
211///
3b2f2976
XL
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)]
041b39d2
XL
216/// struct Rational {
217/// nominator: usize,
218/// denominator: usize,
219/// }
220///
221/// impl Rational {
222/// fn new(nominator: usize, denominator: usize) -> Self {
223/// if denominator == 0 {
224/// panic!("Zero is an invalid denominator!");
225/// }
226///
227/// // Reduce to lowest terms by dividing by the greatest common
228/// // divisor.
229/// let gcd = gcd(nominator, denominator);
230/// Rational {
231/// nominator: nominator / gcd,
232/// denominator: denominator / gcd,
233/// }
234/// }
235/// }
236///
237/// impl Mul for Rational {
238/// // The multiplication of rational numbers is a closed operation.
239/// type Output = Self;
240///
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)
245/// }
246/// }
247///
248/// // Euclid's two-thousand-year-old algorithm for finding the greatest common
249/// // divisor.
250/// fn gcd(x: usize, y: usize) -> usize {
251/// let mut x = x;
252/// let mut y = y;
253/// while y != 0 {
254/// let t = y;
255/// y = x % y;
256/// x = t;
257/// }
258/// x
259/// }
260///
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));
264/// ```
265///
3b2f2976 266/// ## Multiplying vectors by scalars as in linear algebra
041b39d2
XL
267///
268/// ```
269/// use std::ops::Mul;
270///
3b2f2976 271/// struct Scalar { value: usize }
041b39d2 272///
3b2f2976
XL
273/// #[derive(Debug, PartialEq)]
274/// struct Vector { value: Vec<usize> }
041b39d2 275///
3b2f2976 276/// impl Mul<Scalar> for Vector {
041b39d2
XL
277/// type Output = Vector;
278///
3b2f2976
XL
279/// fn mul(self, rhs: Scalar) -> Vector {
280/// Vector { value: self.value.iter().map(|v| v * rhs.value).collect() }
041b39d2
XL
281/// }
282/// }
283///
3b2f2976
XL
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] });
041b39d2
XL
287/// ```
288#[lang = "mul"]
289#[stable(feature = "rust1", since = "1.0.0")]
290#[rustc_on_unimplemented = "no implementation for `{Self} * {RHS}`"]
291pub trait Mul<RHS=Self> {
3b2f2976 292 /// The resulting type after applying the `*` operator.
041b39d2
XL
293 #[stable(feature = "rust1", since = "1.0.0")]
294 type Output;
295
3b2f2976 296 /// Performs the `*` operation.
041b39d2
XL
297 #[stable(feature = "rust1", since = "1.0.0")]
298 fn mul(self, rhs: RHS) -> Self::Output;
299}
300
301macro_rules! mul_impl {
302 ($($t:ty)*) => ($(
303 #[stable(feature = "rust1", since = "1.0.0")]
304 impl Mul for $t {
305 type Output = $t;
306
307 #[inline]
308 #[rustc_inherit_overflow_checks]
309 fn mul(self, other: $t) -> $t { self * other }
310 }
311
312 forward_ref_binop! { impl Mul, mul for $t, $t }
313 )*)
314}
315
316mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
317
318/// The division operator `/`.
319///
3b2f2976
XL
320/// Note that `RHS` is `Self` by default, but this is not mandatory.
321///
041b39d2
XL
322/// # Examples
323///
3b2f2976 324/// ## `Div`idable rational numbers
041b39d2
XL
325///
326/// ```
327/// use std::ops::Div;
328///
3b2f2976
XL
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)]
041b39d2
XL
333/// struct Rational {
334/// nominator: usize,
335/// denominator: usize,
336/// }
337///
338/// impl Rational {
339/// fn new(nominator: usize, denominator: usize) -> Self {
340/// if denominator == 0 {
341/// panic!("Zero is an invalid denominator!");
342/// }
343///
344/// // Reduce to lowest terms by dividing by the greatest common
345/// // divisor.
346/// let gcd = gcd(nominator, denominator);
347/// Rational {
348/// nominator: nominator / gcd,
349/// denominator: denominator / gcd,
350/// }
351/// }
352/// }
353///
354/// impl Div for Rational {
355/// // The division of rational numbers is a closed operation.
356/// type Output = Self;
357///
358/// fn div(self, rhs: Self) -> Self {
359/// if rhs.nominator == 0 {
360/// panic!("Cannot divide by zero-valued `Rational`!");
361/// }
362///
363/// let nominator = self.nominator * rhs.denominator;
364/// let denominator = self.denominator * rhs.nominator;
365/// Rational::new(nominator, denominator)
366/// }
367/// }
368///
369/// // Euclid's two-thousand-year-old algorithm for finding the greatest common
370/// // divisor.
371/// fn gcd(x: usize, y: usize) -> usize {
372/// let mut x = x;
373/// let mut y = y;
374/// while y != 0 {
375/// let t = y;
376/// y = x % y;
377/// x = t;
378/// }
379/// x
380/// }
381///
3b2f2976
XL
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));
041b39d2
XL
385/// ```
386///
3b2f2976 387/// ## Dividing vectors by scalars as in linear algebra
041b39d2
XL
388///
389/// ```
390/// use std::ops::Div;
391///
3b2f2976 392/// struct Scalar { value: f32 }
041b39d2 393///
3b2f2976
XL
394/// #[derive(Debug, PartialEq)]
395/// struct Vector { value: Vec<f32> }
041b39d2
XL
396///
397/// impl Div<Scalar> for Vector {
398/// type Output = Vector;
399///
400/// fn div(self, rhs: Scalar) -> Vector {
3b2f2976 401/// Vector { value: self.value.iter().map(|v| v / rhs.value).collect() }
041b39d2
XL
402/// }
403/// }
404///
3b2f2976
XL
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] });
041b39d2
XL
408/// ```
409#[lang = "div"]
410#[stable(feature = "rust1", since = "1.0.0")]
411#[rustc_on_unimplemented = "no implementation for `{Self} / {RHS}`"]
412pub trait Div<RHS=Self> {
3b2f2976 413 /// The resulting type after applying the `/` operator.
041b39d2
XL
414 #[stable(feature = "rust1", since = "1.0.0")]
415 type Output;
416
3b2f2976 417 /// Performs the `/` operation.
041b39d2
XL
418 #[stable(feature = "rust1", since = "1.0.0")]
419 fn div(self, rhs: RHS) -> Self::Output;
420}
421
422macro_rules! div_impl_integer {
423 ($($t:ty)*) => ($(
424 /// This operation rounds towards zero, truncating any
425 /// fractional part of the exact result.
426 #[stable(feature = "rust1", since = "1.0.0")]
427 impl Div for $t {
428 type Output = $t;
429
430 #[inline]
431 fn div(self, other: $t) -> $t { self / other }
432 }
433
434 forward_ref_binop! { impl Div, div for $t, $t }
435 )*)
436}
437
438div_impl_integer! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
439
440macro_rules! div_impl_float {
441 ($($t:ty)*) => ($(
442 #[stable(feature = "rust1", since = "1.0.0")]
443 impl Div for $t {
444 type Output = $t;
445
446 #[inline]
447 fn div(self, other: $t) -> $t { self / other }
448 }
449
450 forward_ref_binop! { impl Div, div for $t, $t }
451 )*)
452}
453
454div_impl_float! { f32 f64 }
455
456/// The remainder operator `%`.
457///
3b2f2976
XL
458/// Note that `RHS` is `Self` by default, but this is not mandatory.
459///
041b39d2
XL
460/// # Examples
461///
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
465/// given length.
466///
467/// ```
468/// use std::ops::Rem;
469///
470/// #[derive(PartialEq, Debug)]
471/// struct SplitSlice<'a, T: 'a> {
472/// slice: &'a [T],
473/// }
474///
475/// impl<'a, T> Rem<usize> for SplitSlice<'a, T> {
476/// type Output = SplitSlice<'a, T>;
477///
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..]}
483/// }
484/// }
485///
486/// // If we were to divide &[0, 1, 2, 3, 4, 5, 6, 7] into slices of size 3,
3b2f2976 487/// // the remainder would be &[6, 7].
041b39d2
XL
488/// assert_eq!(SplitSlice { slice: &[0, 1, 2, 3, 4, 5, 6, 7] } % 3,
489/// SplitSlice { slice: &[6, 7] });
490/// ```
491#[lang = "rem"]
492#[stable(feature = "rust1", since = "1.0.0")]
493#[rustc_on_unimplemented = "no implementation for `{Self} % {RHS}`"]
494pub trait Rem<RHS=Self> {
3b2f2976 495 /// The resulting type after applying the `%` operator.
041b39d2
XL
496 #[stable(feature = "rust1", since = "1.0.0")]
497 type Output = Self;
498
3b2f2976 499 /// Performs the `%` operation.
041b39d2
XL
500 #[stable(feature = "rust1", since = "1.0.0")]
501 fn rem(self, rhs: RHS) -> Self::Output;
502}
503
504macro_rules! rem_impl_integer {
505 ($($t:ty)*) => ($(
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")]
509 impl Rem for $t {
510 type Output = $t;
511
512 #[inline]
513 fn rem(self, other: $t) -> $t { self % other }
514 }
515
516 forward_ref_binop! { impl Rem, rem for $t, $t }
517 )*)
518}
519
520rem_impl_integer! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
521
522
523macro_rules! rem_impl_float {
524 ($($t:ty)*) => ($(
525 #[stable(feature = "rust1", since = "1.0.0")]
526 impl Rem for $t {
527 type Output = $t;
528
529 #[inline]
530 fn rem(self, other: $t) -> $t { self % other }
531 }
532
533 forward_ref_binop! { impl Rem, rem for $t, $t }
534 )*)
535}
536
537rem_impl_float! { f32 f64 }
538
539/// The unary negation operator `-`.
540///
541/// # Examples
542///
543/// An implementation of `Neg` for `Sign`, which allows the use of `-` to
544/// negate its value.
545///
546/// ```
547/// use std::ops::Neg;
548///
549/// #[derive(Debug, PartialEq)]
550/// enum Sign {
551/// Negative,
552/// Zero,
553/// Positive,
554/// }
555///
556/// impl Neg for Sign {
557/// type Output = Sign;
558///
559/// fn neg(self) -> Sign {
560/// match self {
561/// Sign::Negative => Sign::Positive,
562/// Sign::Zero => Sign::Zero,
563/// Sign::Positive => Sign::Negative,
564/// }
565/// }
566/// }
567///
3b2f2976 568/// // A negative positive is a negative.
041b39d2 569/// assert_eq!(-Sign::Positive, Sign::Negative);
3b2f2976 570/// // A double negative is a positive.
041b39d2 571/// assert_eq!(-Sign::Negative, Sign::Positive);
3b2f2976 572/// // Zero is its own negation.
041b39d2
XL
573/// assert_eq!(-Sign::Zero, Sign::Zero);
574/// ```
575#[lang = "neg"]
576#[stable(feature = "rust1", since = "1.0.0")]
577pub trait Neg {
3b2f2976 578 /// The resulting type after applying the `-` operator.
041b39d2
XL
579 #[stable(feature = "rust1", since = "1.0.0")]
580 type Output;
581
3b2f2976 582 /// Performs the unary `-` operation.
041b39d2
XL
583 #[stable(feature = "rust1", since = "1.0.0")]
584 fn neg(self) -> Self::Output;
585}
586
587
588
589macro_rules! neg_impl_core {
590 ($id:ident => $body:expr, $($t:ty)*) => ($(
591 #[stable(feature = "rust1", since = "1.0.0")]
592 impl Neg for $t {
593 type Output = $t;
594
595 #[inline]
596 #[rustc_inherit_overflow_checks]
597 fn neg(self) -> $t { let $id = self; $body }
598 }
599
600 forward_ref_unop! { impl Neg, neg for $t }
601 )*)
602}
603
604macro_rules! neg_impl_numeric {
605 ($($t:ty)*) => { neg_impl_core!{ x => -x, $($t)*} }
606}
607
608#[allow(unused_macros)]
609macro_rules! neg_impl_unsigned {
610 ($($t:ty)*) => {
611 neg_impl_core!{ x => {
612 !x.wrapping_add(1)
613 }, $($t)*} }
614}
615
616// neg_impl_unsigned! { usize u8 u16 u32 u64 }
617neg_impl_numeric! { isize i8 i16 i32 i64 i128 f32 f64 }
618
619/// The addition assignment operator `+=`.
620///
621/// # Examples
622///
623/// This example creates a `Point` struct that implements the `AddAssign`
624/// trait, and then demonstrates add-assigning to a mutable `Point`.
625///
626/// ```
627/// use std::ops::AddAssign;
628///
3b2f2976 629/// #[derive(Debug, PartialEq)]
041b39d2
XL
630/// struct Point {
631/// x: i32,
632/// y: i32,
633/// }
634///
635/// impl AddAssign for Point {
636/// fn add_assign(&mut self, other: Point) {
637/// *self = Point {
638/// x: self.x + other.x,
639/// y: self.y + other.y,
640/// };
641/// }
642/// }
643///
041b39d2
XL
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 });
647/// ```
648#[lang = "add_assign"]
649#[stable(feature = "op_assign_traits", since = "1.8.0")]
650#[rustc_on_unimplemented = "no implementation for `{Self} += {Rhs}`"]
651pub trait AddAssign<Rhs=Self> {
3b2f2976 652 /// Performs the `+=` operation.
041b39d2
XL
653 #[stable(feature = "op_assign_traits", since = "1.8.0")]
654 fn add_assign(&mut self, rhs: Rhs);
655}
656
657macro_rules! add_assign_impl {
658 ($($t:ty)+) => ($(
659 #[stable(feature = "op_assign_traits", since = "1.8.0")]
660 impl AddAssign for $t {
661 #[inline]
662 #[rustc_inherit_overflow_checks]
663 fn add_assign(&mut self, other: $t) { *self += other }
664 }
ea8adc8c
XL
665
666 forward_ref_op_assign! { impl AddAssign, add_assign for $t, $t }
041b39d2
XL
667 )+)
668}
669
670add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
671
672/// The subtraction assignment operator `-=`.
673///
674/// # Examples
675///
676/// This example creates a `Point` struct that implements the `SubAssign`
677/// trait, and then demonstrates sub-assigning to a mutable `Point`.
678///
679/// ```
680/// use std::ops::SubAssign;
681///
3b2f2976 682/// #[derive(Debug, PartialEq)]
041b39d2
XL
683/// struct Point {
684/// x: i32,
685/// y: i32,
686/// }
687///
688/// impl SubAssign for Point {
689/// fn sub_assign(&mut self, other: Point) {
690/// *self = Point {
691/// x: self.x - other.x,
692/// y: self.y - other.y,
693/// };
694/// }
695/// }
696///
041b39d2
XL
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});
700/// ```
701#[lang = "sub_assign"]
702#[stable(feature = "op_assign_traits", since = "1.8.0")]
703#[rustc_on_unimplemented = "no implementation for `{Self} -= {Rhs}`"]
704pub trait SubAssign<Rhs=Self> {
3b2f2976 705 /// Performs the `-=` operation.
041b39d2
XL
706 #[stable(feature = "op_assign_traits", since = "1.8.0")]
707 fn sub_assign(&mut self, rhs: Rhs);
708}
709
710macro_rules! sub_assign_impl {
711 ($($t:ty)+) => ($(
712 #[stable(feature = "op_assign_traits", since = "1.8.0")]
713 impl SubAssign for $t {
714 #[inline]
715 #[rustc_inherit_overflow_checks]
716 fn sub_assign(&mut self, other: $t) { *self -= other }
717 }
ea8adc8c
XL
718
719 forward_ref_op_assign! { impl SubAssign, sub_assign for $t, $t }
041b39d2
XL
720 )+)
721}
722
723sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
724
725/// The multiplication assignment operator `*=`.
726///
727/// # Examples
728///
041b39d2
XL
729/// ```
730/// use std::ops::MulAssign;
731///
3b2f2976
XL
732/// #[derive(Debug, PartialEq)]
733/// struct Frequency { hertz: f64 }
041b39d2 734///
3b2f2976
XL
735/// impl MulAssign<f64> for Frequency {
736/// fn mul_assign(&mut self, rhs: f64) {
737/// self.hertz *= rhs;
041b39d2
XL
738/// }
739/// }
740///
3b2f2976
XL
741/// let mut frequency = Frequency { hertz: 50.0 };
742/// frequency *= 4.0;
743/// assert_eq!(Frequency { hertz: 200.0 }, frequency);
041b39d2
XL
744/// ```
745#[lang = "mul_assign"]
746#[stable(feature = "op_assign_traits", since = "1.8.0")]
747#[rustc_on_unimplemented = "no implementation for `{Self} *= {Rhs}`"]
748pub trait MulAssign<Rhs=Self> {
3b2f2976 749 /// Performs the `*=` operation.
041b39d2
XL
750 #[stable(feature = "op_assign_traits", since = "1.8.0")]
751 fn mul_assign(&mut self, rhs: Rhs);
752}
753
754macro_rules! mul_assign_impl {
755 ($($t:ty)+) => ($(
756 #[stable(feature = "op_assign_traits", since = "1.8.0")]
757 impl MulAssign for $t {
758 #[inline]
759 #[rustc_inherit_overflow_checks]
760 fn mul_assign(&mut self, other: $t) { *self *= other }
761 }
ea8adc8c
XL
762
763 forward_ref_op_assign! { impl MulAssign, mul_assign for $t, $t }
041b39d2
XL
764 )+)
765}
766
767mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
768
769/// The division assignment operator `/=`.
770///
771/// # Examples
772///
041b39d2
XL
773/// ```
774/// use std::ops::DivAssign;
775///
3b2f2976
XL
776/// #[derive(Debug, PartialEq)]
777/// struct Frequency { hertz: f64 }
041b39d2 778///
3b2f2976
XL
779/// impl DivAssign<f64> for Frequency {
780/// fn div_assign(&mut self, rhs: f64) {
781/// self.hertz /= rhs;
041b39d2
XL
782/// }
783/// }
784///
3b2f2976
XL
785/// let mut frequency = Frequency { hertz: 200.0 };
786/// frequency /= 4.0;
787/// assert_eq!(Frequency { hertz: 50.0 }, frequency);
041b39d2
XL
788/// ```
789#[lang = "div_assign"]
790#[stable(feature = "op_assign_traits", since = "1.8.0")]
791#[rustc_on_unimplemented = "no implementation for `{Self} /= {Rhs}`"]
792pub trait DivAssign<Rhs=Self> {
3b2f2976 793 /// Performs the `/=` operation.
041b39d2
XL
794 #[stable(feature = "op_assign_traits", since = "1.8.0")]
795 fn div_assign(&mut self, rhs: Rhs);
796}
797
798macro_rules! div_assign_impl {
799 ($($t:ty)+) => ($(
800 #[stable(feature = "op_assign_traits", since = "1.8.0")]
801 impl DivAssign for $t {
802 #[inline]
803 fn div_assign(&mut self, other: $t) { *self /= other }
804 }
ea8adc8c
XL
805
806 forward_ref_op_assign! { impl DivAssign, div_assign for $t, $t }
041b39d2
XL
807 )+)
808}
809
810div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
811
812/// The remainder assignment operator `%=`.
813///
814/// # Examples
815///
041b39d2
XL
816/// ```
817/// use std::ops::RemAssign;
818///
3b2f2976 819/// struct CookieJar { cookies: u32 }
041b39d2 820///
3b2f2976
XL
821/// impl RemAssign<u32> for CookieJar {
822/// fn rem_assign(&mut self, piles: u32) {
823/// self.cookies %= piles;
041b39d2
XL
824/// }
825/// }
826///
3b2f2976
XL
827/// let mut jar = CookieJar { cookies: 31 };
828/// let piles = 4;
829///
830/// println!("Splitting up {} cookies into {} even piles!", jar.cookies, piles);
831///
832/// jar %= piles;
833///
834/// println!("{} cookies remain in the cookie jar!", jar.cookies);
041b39d2
XL
835/// ```
836#[lang = "rem_assign"]
837#[stable(feature = "op_assign_traits", since = "1.8.0")]
838#[rustc_on_unimplemented = "no implementation for `{Self} %= {Rhs}`"]
839pub trait RemAssign<Rhs=Self> {
3b2f2976 840 /// Performs the `%=` operation.
041b39d2
XL
841 #[stable(feature = "op_assign_traits", since = "1.8.0")]
842 fn rem_assign(&mut self, rhs: Rhs);
843}
844
845macro_rules! rem_assign_impl {
846 ($($t:ty)+) => ($(
847 #[stable(feature = "op_assign_traits", since = "1.8.0")]
848 impl RemAssign for $t {
849 #[inline]
850 fn rem_assign(&mut self, other: $t) { *self %= other }
851 }
ea8adc8c
XL
852
853 forward_ref_op_assign! { impl RemAssign, rem_assign for $t, $t }
041b39d2
XL
854 )+)
855}
856
857rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }