1 /// The addition operator `+`.
2 ///
3 /// Note that `Rhs` is `Self` by default, but this is not mandatory. For
4 /// example, [`std::time::SystemTime`] implements `Add<Duration>`, which permits
5 /// operations of the form `SystemTime = SystemTime + Duration`.
6 ///
7 /// [`std::time::SystemTime`]: ../../std/time/struct.SystemTime.html
8 ///
9 /// # Examples
10 ///
11 /// ## `Add`able points
12 ///
13 /// ```
14 /// use std::ops::Add;
15 ///
16 /// #[derive(Debug, Copy, Clone, PartialEq)]
17 /// struct Point {
18 ///     x: i32,
19 ///     y: i32,
20 /// }
21 ///
22 /// impl Add for Point {
23 ///     type Output = Self;
24 ///
25 ///     fn add(self, other: Self) -> Self {
26 ///         Self {
27 ///             x: self.x + other.x,
28 ///             y: self.y + other.y,
29 ///         }
30 ///     }
31 /// }
32 ///
33 /// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
34 ///            Point { x: 3, y: 3 });
35 /// ```
36 ///
37 /// ## Implementing `Add` with generics
38 ///
39 /// Here is an example of the same `Point` struct implementing the `Add` trait
40 /// using generics.
41 ///
42 /// ```
43 /// use std::ops::Add;
44 ///
45 /// #[derive(Debug, Copy, Clone, PartialEq)]
46 /// struct Point<T> {
47 ///     x: T,
48 ///     y: T,
49 /// }
50 ///
51 /// // Notice that the implementation uses the associated type `Output`.
52 /// impl<T: Add<Output = T>> Add for Point<T> {
53 ///     type Output = Self;
54 ///
55 ///     fn add(self, other: Self) -> Self::Output {
56 ///         Self {
57 ///             x: self.x + other.x,
58 ///             y: self.y + other.y,
59 ///         }
60 ///     }
61 /// }
62 ///
63 /// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
64 ///            Point { x: 3, y: 3 });
65 /// ```
66 #[lang = "add"]
67 #[stable(feature = "rust1", since = "1.0.0")]
68 #[rustc_on_unimplemented(
69     on(all(_Self = "{integer}", Rhs = "{float}"), message = "cannot add a float to an integer",),
70     on(all(_Self = "{float}", Rhs = "{integer}"), message = "cannot add an integer to a float",),
71     message = "cannot add `{Rhs}` to `{Self}`",
72     label = "no implementation for `{Self} + {Rhs}`"
73 )]
74 #[doc(alias = "+")]
75 pub trait Add<Rhs = Self> {
76     /// The resulting type after applying the `+` operator.
77     #[stable(feature = "rust1", since = "1.0.0")]
78     type Output;
79 
80     /// Performs the `+` operation.
81     ///
82     /// # Example
83     ///
84     /// ```
85     /// assert_eq!(12 + 1, 13);
86     /// ```
87     #[must_use]
88     #[stable(feature = "rust1", since = "1.0.0")]
add(self, rhs: Rhs) -> Self::Output89     fn add(self, rhs: Rhs) -> Self::Output;
90 }
91 
92 macro_rules! add_impl {
93     ($($t:ty)*) => ($(
94         #[stable(feature = "rust1", since = "1.0.0")]
95         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
96         impl const Add for $t {
97             type Output = $t;
98 
99             #[inline]
100             #[rustc_inherit_overflow_checks]
101             fn add(self, other: $t) -> $t { self + other }
102         }
103 
104         forward_ref_binop! { impl const Add, add for $t, $t }
105     )*)
106 }
107 
108 add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
109 
110 /// The subtraction operator `-`.
111 ///
112 /// Note that `Rhs` is `Self` by default, but this is not mandatory. For
113 /// example, [`std::time::SystemTime`] implements `Sub<Duration>`, which permits
114 /// operations of the form `SystemTime = SystemTime - Duration`.
115 ///
116 /// [`std::time::SystemTime`]: ../../std/time/struct.SystemTime.html
117 ///
118 /// # Examples
119 ///
120 /// ## `Sub`tractable points
121 ///
122 /// ```
123 /// use std::ops::Sub;
124 ///
125 /// #[derive(Debug, Copy, Clone, PartialEq)]
126 /// struct Point {
127 ///     x: i32,
128 ///     y: i32,
129 /// }
130 ///
131 /// impl Sub for Point {
132 ///     type Output = Self;
133 ///
134 ///     fn sub(self, other: Self) -> Self::Output {
135 ///         Self {
136 ///             x: self.x - other.x,
137 ///             y: self.y - other.y,
138 ///         }
139 ///     }
140 /// }
141 ///
142 /// assert_eq!(Point { x: 3, y: 3 } - Point { x: 2, y: 3 },
143 ///            Point { x: 1, y: 0 });
144 /// ```
145 ///
146 /// ## Implementing `Sub` with generics
147 ///
148 /// Here is an example of the same `Point` struct implementing the `Sub` trait
149 /// using generics.
150 ///
151 /// ```
152 /// use std::ops::Sub;
153 ///
154 /// #[derive(Debug, PartialEq)]
155 /// struct Point<T> {
156 ///     x: T,
157 ///     y: T,
158 /// }
159 ///
160 /// // Notice that the implementation uses the associated type `Output`.
161 /// impl<T: Sub<Output = T>> Sub for Point<T> {
162 ///     type Output = Self;
163 ///
164 ///     fn sub(self, other: Self) -> Self::Output {
165 ///         Point {
166 ///             x: self.x - other.x,
167 ///             y: self.y - other.y,
168 ///         }
169 ///     }
170 /// }
171 ///
172 /// assert_eq!(Point { x: 2, y: 3 } - Point { x: 1, y: 0 },
173 ///            Point { x: 1, y: 3 });
174 /// ```
175 #[lang = "sub"]
176 #[stable(feature = "rust1", since = "1.0.0")]
177 #[rustc_on_unimplemented(
178     message = "cannot subtract `{Rhs}` from `{Self}`",
179     label = "no implementation for `{Self} - {Rhs}`"
180 )]
181 #[doc(alias = "-")]
182 pub trait Sub<Rhs = Self> {
183     /// The resulting type after applying the `-` operator.
184     #[stable(feature = "rust1", since = "1.0.0")]
185     type Output;
186 
187     /// Performs the `-` operation.
188     ///
189     /// # Example
190     ///
191     /// ```
192     /// assert_eq!(12 - 1, 11);
193     /// ```
194     #[must_use]
195     #[stable(feature = "rust1", since = "1.0.0")]
sub(self, rhs: Rhs) -> Self::Output196     fn sub(self, rhs: Rhs) -> Self::Output;
197 }
198 
199 macro_rules! sub_impl {
200     ($($t:ty)*) => ($(
201         #[stable(feature = "rust1", since = "1.0.0")]
202         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
203         impl const Sub for $t {
204             type Output = $t;
205 
206             #[inline]
207             #[rustc_inherit_overflow_checks]
208             fn sub(self, other: $t) -> $t { self - other }
209         }
210 
211         forward_ref_binop! { impl const Sub, sub for $t, $t }
212     )*)
213 }
214 
215 sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
216 
217 /// The multiplication operator `*`.
218 ///
219 /// Note that `Rhs` is `Self` by default, but this is not mandatory.
220 ///
221 /// # Examples
222 ///
223 /// ## `Mul`tipliable rational numbers
224 ///
225 /// ```
226 /// use std::ops::Mul;
227 ///
228 /// // By the fundamental theorem of arithmetic, rational numbers in lowest
229 /// // terms are unique. So, by keeping `Rational`s in reduced form, we can
230 /// // derive `Eq` and `PartialEq`.
231 /// #[derive(Debug, Eq, PartialEq)]
232 /// struct Rational {
233 ///     numerator: usize,
234 ///     denominator: usize,
235 /// }
236 ///
237 /// impl Rational {
238 ///     fn new(numerator: usize, denominator: usize) -> Self {
239 ///         if denominator == 0 {
240 ///             panic!("Zero is an invalid denominator!");
241 ///         }
242 ///
243 ///         // Reduce to lowest terms by dividing by the greatest common
244 ///         // divisor.
245 ///         let gcd = gcd(numerator, denominator);
246 ///         Self {
247 ///             numerator: numerator / gcd,
248 ///             denominator: denominator / gcd,
249 ///         }
250 ///     }
251 /// }
252 ///
253 /// impl Mul for Rational {
254 ///     // The multiplication of rational numbers is a closed operation.
255 ///     type Output = Self;
256 ///
257 ///     fn mul(self, rhs: Self) -> Self {
258 ///         let numerator = self.numerator * rhs.numerator;
259 ///         let denominator = self.denominator * rhs.denominator;
260 ///         Self::new(numerator, denominator)
261 ///     }
262 /// }
263 ///
264 /// // Euclid's two-thousand-year-old algorithm for finding the greatest common
265 /// // divisor.
266 /// fn gcd(x: usize, y: usize) -> usize {
267 ///     let mut x = x;
268 ///     let mut y = y;
269 ///     while y != 0 {
270 ///         let t = y;
271 ///         y = x % y;
272 ///         x = t;
273 ///     }
274 ///     x
275 /// }
276 ///
277 /// assert_eq!(Rational::new(1, 2), Rational::new(2, 4));
278 /// assert_eq!(Rational::new(2, 3) * Rational::new(3, 4),
279 ///            Rational::new(1, 2));
280 /// ```
281 ///
282 /// ## Multiplying vectors by scalars as in linear algebra
283 ///
284 /// ```
285 /// use std::ops::Mul;
286 ///
287 /// struct Scalar { value: usize }
288 ///
289 /// #[derive(Debug, PartialEq)]
290 /// struct Vector { value: Vec<usize> }
291 ///
292 /// impl Mul<Scalar> for Vector {
293 ///     type Output = Self;
294 ///
295 ///     fn mul(self, rhs: Scalar) -> Self::Output {
296 ///         Self { value: self.value.iter().map(|v| v * rhs.value).collect() }
297 ///     }
298 /// }
299 ///
300 /// let vector = Vector { value: vec![2, 4, 6] };
301 /// let scalar = Scalar { value: 3 };
302 /// assert_eq!(vector * scalar, Vector { value: vec![6, 12, 18] });
303 /// ```
304 #[lang = "mul"]
305 #[stable(feature = "rust1", since = "1.0.0")]
306 #[rustc_on_unimplemented(
307     message = "cannot multiply `{Self}` by `{Rhs}`",
308     label = "no implementation for `{Self} * {Rhs}`"
309 )]
310 #[doc(alias = "*")]
311 pub trait Mul<Rhs = Self> {
312     /// The resulting type after applying the `*` operator.
313     #[stable(feature = "rust1", since = "1.0.0")]
314     type Output;
315 
316     /// Performs the `*` operation.
317     ///
318     /// # Example
319     ///
320     /// ```
321     /// assert_eq!(12 * 2, 24);
322     /// ```
323     #[must_use]
324     #[stable(feature = "rust1", since = "1.0.0")]
mul(self, rhs: Rhs) -> Self::Output325     fn mul(self, rhs: Rhs) -> Self::Output;
326 }
327 
328 macro_rules! mul_impl {
329     ($($t:ty)*) => ($(
330         #[stable(feature = "rust1", since = "1.0.0")]
331         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
332         impl const Mul for $t {
333             type Output = $t;
334 
335             #[inline]
336             #[rustc_inherit_overflow_checks]
337             fn mul(self, other: $t) -> $t { self * other }
338         }
339 
340         forward_ref_binop! { impl const Mul, mul for $t, $t }
341     )*)
342 }
343 
344 mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
345 
346 /// The division operator `/`.
347 ///
348 /// Note that `Rhs` is `Self` by default, but this is not mandatory.
349 ///
350 /// # Examples
351 ///
352 /// ## `Div`idable rational numbers
353 ///
354 /// ```
355 /// use std::ops::Div;
356 ///
357 /// // By the fundamental theorem of arithmetic, rational numbers in lowest
358 /// // terms are unique. So, by keeping `Rational`s in reduced form, we can
359 /// // derive `Eq` and `PartialEq`.
360 /// #[derive(Debug, Eq, PartialEq)]
361 /// struct Rational {
362 ///     numerator: usize,
363 ///     denominator: usize,
364 /// }
365 ///
366 /// impl Rational {
367 ///     fn new(numerator: usize, denominator: usize) -> Self {
368 ///         if denominator == 0 {
369 ///             panic!("Zero is an invalid denominator!");
370 ///         }
371 ///
372 ///         // Reduce to lowest terms by dividing by the greatest common
373 ///         // divisor.
374 ///         let gcd = gcd(numerator, denominator);
375 ///         Self {
376 ///             numerator: numerator / gcd,
377 ///             denominator: denominator / gcd,
378 ///         }
379 ///     }
380 /// }
381 ///
382 /// impl Div for Rational {
383 ///     // The division of rational numbers is a closed operation.
384 ///     type Output = Self;
385 ///
386 ///     fn div(self, rhs: Self) -> Self::Output {
387 ///         if rhs.numerator == 0 {
388 ///             panic!("Cannot divide by zero-valued `Rational`!");
389 ///         }
390 ///
391 ///         let numerator = self.numerator * rhs.denominator;
392 ///         let denominator = self.denominator * rhs.numerator;
393 ///         Self::new(numerator, denominator)
394 ///     }
395 /// }
396 ///
397 /// // Euclid's two-thousand-year-old algorithm for finding the greatest common
398 /// // divisor.
399 /// fn gcd(x: usize, y: usize) -> usize {
400 ///     let mut x = x;
401 ///     let mut y = y;
402 ///     while y != 0 {
403 ///         let t = y;
404 ///         y = x % y;
405 ///         x = t;
406 ///     }
407 ///     x
408 /// }
409 ///
410 /// assert_eq!(Rational::new(1, 2), Rational::new(2, 4));
411 /// assert_eq!(Rational::new(1, 2) / Rational::new(3, 4),
412 ///            Rational::new(2, 3));
413 /// ```
414 ///
415 /// ## Dividing vectors by scalars as in linear algebra
416 ///
417 /// ```
418 /// use std::ops::Div;
419 ///
420 /// struct Scalar { value: f32 }
421 ///
422 /// #[derive(Debug, PartialEq)]
423 /// struct Vector { value: Vec<f32> }
424 ///
425 /// impl Div<Scalar> for Vector {
426 ///     type Output = Self;
427 ///
428 ///     fn div(self, rhs: Scalar) -> Self::Output {
429 ///         Self { value: self.value.iter().map(|v| v / rhs.value).collect() }
430 ///     }
431 /// }
432 ///
433 /// let scalar = Scalar { value: 2f32 };
434 /// let vector = Vector { value: vec![2f32, 4f32, 6f32] };
435 /// assert_eq!(vector / scalar, Vector { value: vec![1f32, 2f32, 3f32] });
436 /// ```
437 #[lang = "div"]
438 #[stable(feature = "rust1", since = "1.0.0")]
439 #[rustc_on_unimplemented(
440     message = "cannot divide `{Self}` by `{Rhs}`",
441     label = "no implementation for `{Self} / {Rhs}`"
442 )]
443 #[doc(alias = "/")]
444 pub trait Div<Rhs = Self> {
445     /// The resulting type after applying the `/` operator.
446     #[stable(feature = "rust1", since = "1.0.0")]
447     type Output;
448 
449     /// Performs the `/` operation.
450     ///
451     /// # Example
452     ///
453     /// ```
454     /// assert_eq!(12 / 2, 6);
455     /// ```
456     #[must_use]
457     #[stable(feature = "rust1", since = "1.0.0")]
div(self, rhs: Rhs) -> Self::Output458     fn div(self, rhs: Rhs) -> Self::Output;
459 }
460 
461 macro_rules! div_impl_integer {
462     ($(($($t:ty)*) => $panic:expr),*) => ($($(
463         /// This operation rounds towards zero, truncating any
464         /// fractional part of the exact result.
465         ///
466         /// # Panics
467         ///
468         #[doc = $panic]
469         #[stable(feature = "rust1", since = "1.0.0")]
470         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
471         impl const Div for $t {
472             type Output = $t;
473 
474             #[inline]
475             fn div(self, other: $t) -> $t { self / other }
476         }
477 
478         forward_ref_binop! { impl const Div, div for $t, $t }
479     )*)*)
480 }
481 
482 div_impl_integer! {
483     (usize u8 u16 u32 u64 u128) => "This operation will panic if `other == 0`.",
484     (isize i8 i16 i32 i64 i128) => "This operation will panic if `other == 0` or the division results in overflow."
485 }
486 
487 macro_rules! div_impl_float {
488     ($($t:ty)*) => ($(
489         #[stable(feature = "rust1", since = "1.0.0")]
490         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
491         impl const Div for $t {
492             type Output = $t;
493 
494             #[inline]
495             fn div(self, other: $t) -> $t { self / other }
496         }
497 
498         forward_ref_binop! { impl const Div, div for $t, $t }
499     )*)
500 }
501 
502 div_impl_float! { f32 f64 }
503 
504 /// The remainder operator `%`.
505 ///
506 /// Note that `Rhs` is `Self` by default, but this is not mandatory.
507 ///
508 /// # Examples
509 ///
510 /// This example implements `Rem` on a `SplitSlice` object. After `Rem` is
511 /// implemented, one can use the `%` operator to find out what the remaining
512 /// elements of the slice would be after splitting it into equal slices of a
513 /// given length.
514 ///
515 /// ```
516 /// use std::ops::Rem;
517 ///
518 /// #[derive(PartialEq, Debug)]
519 /// struct SplitSlice<'a, T: 'a> {
520 ///     slice: &'a [T],
521 /// }
522 ///
523 /// impl<'a, T> Rem<usize> for SplitSlice<'a, T> {
524 ///     type Output = Self;
525 ///
526 ///     fn rem(self, modulus: usize) -> Self::Output {
527 ///         let len = self.slice.len();
528 ///         let rem = len % modulus;
529 ///         let start = len - rem;
530 ///         Self {slice: &self.slice[start..]}
531 ///     }
532 /// }
533 ///
534 /// // If we were to divide &[0, 1, 2, 3, 4, 5, 6, 7] into slices of size 3,
535 /// // the remainder would be &[6, 7].
536 /// assert_eq!(SplitSlice { slice: &[0, 1, 2, 3, 4, 5, 6, 7] } % 3,
537 ///            SplitSlice { slice: &[6, 7] });
538 /// ```
539 #[lang = "rem"]
540 #[stable(feature = "rust1", since = "1.0.0")]
541 #[rustc_on_unimplemented(
542     message = "cannot mod `{Self}` by `{Rhs}`",
543     label = "no implementation for `{Self} % {Rhs}`"
544 )]
545 #[doc(alias = "%")]
546 pub trait Rem<Rhs = Self> {
547     /// The resulting type after applying the `%` operator.
548     #[stable(feature = "rust1", since = "1.0.0")]
549     type Output;
550 
551     /// Performs the `%` operation.
552     ///
553     /// # Example
554     ///
555     /// ```
556     /// assert_eq!(12 % 10, 2);
557     /// ```
558     #[must_use]
559     #[stable(feature = "rust1", since = "1.0.0")]
rem(self, rhs: Rhs) -> Self::Output560     fn rem(self, rhs: Rhs) -> Self::Output;
561 }
562 
563 macro_rules! rem_impl_integer {
564     ($(($($t:ty)*) => $panic:expr),*) => ($($(
565         /// This operation satisfies `n % d == n - (n / d) * d`. The
566         /// result has the same sign as the left operand.
567         ///
568         /// # Panics
569         ///
570         #[doc = $panic]
571         #[stable(feature = "rust1", since = "1.0.0")]
572         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
573         impl const Rem for $t {
574             type Output = $t;
575 
576             #[inline]
577             fn rem(self, other: $t) -> $t { self % other }
578         }
579 
580         forward_ref_binop! { impl const Rem, rem for $t, $t }
581     )*)*)
582 }
583 
584 rem_impl_integer! {
585     (usize u8 u16 u32 u64 u128) => "This operation will panic if `other == 0`.",
586     (isize i8 i16 i32 i64 i128) => "This operation will panic if `other == 0` or if `self / other` results in overflow."
587 }
588 
589 macro_rules! rem_impl_float {
590     ($($t:ty)*) => ($(
591 
592         /// The remainder from the division of two floats.
593         ///
594         /// The remainder has the same sign as the dividend and is computed as:
595         /// `x - (x / y).trunc() * y`.
596         ///
597         /// # Examples
598         /// ```
599         /// let x: f32 = 50.50;
600         /// let y: f32 = 8.125;
601         /// let remainder = x - (x / y).trunc() * y;
602         ///
603         /// // The answer to both operations is 1.75
604         /// assert_eq!(x % y, remainder);
605         /// ```
606         #[stable(feature = "rust1", since = "1.0.0")]
607         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
608         impl const Rem for $t {
609             type Output = $t;
610 
611             #[inline]
612             fn rem(self, other: $t) -> $t { self % other }
613         }
614 
615         forward_ref_binop! { impl const Rem, rem for $t, $t }
616     )*)
617 }
618 
619 rem_impl_float! { f32 f64 }
620 
621 /// The unary negation operator `-`.
622 ///
623 /// # Examples
624 ///
625 /// An implementation of `Neg` for `Sign`, which allows the use of `-` to
626 /// negate its value.
627 ///
628 /// ```
629 /// use std::ops::Neg;
630 ///
631 /// #[derive(Debug, PartialEq)]
632 /// enum Sign {
633 ///     Negative,
634 ///     Zero,
635 ///     Positive,
636 /// }
637 ///
638 /// impl Neg for Sign {
639 ///     type Output = Self;
640 ///
641 ///     fn neg(self) -> Self::Output {
642 ///         match self {
643 ///             Sign::Negative => Sign::Positive,
644 ///             Sign::Zero => Sign::Zero,
645 ///             Sign::Positive => Sign::Negative,
646 ///         }
647 ///     }
648 /// }
649 ///
650 /// // A negative positive is a negative.
651 /// assert_eq!(-Sign::Positive, Sign::Negative);
652 /// // A double negative is a positive.
653 /// assert_eq!(-Sign::Negative, Sign::Positive);
654 /// // Zero is its own negation.
655 /// assert_eq!(-Sign::Zero, Sign::Zero);
656 /// ```
657 #[lang = "neg"]
658 #[stable(feature = "rust1", since = "1.0.0")]
659 #[doc(alias = "-")]
660 pub trait Neg {
661     /// The resulting type after applying the `-` operator.
662     #[stable(feature = "rust1", since = "1.0.0")]
663     type Output;
664 
665     /// Performs the unary `-` operation.
666     ///
667     /// # Example
668     ///
669     /// ```
670     /// let x: i32 = 12;
671     /// assert_eq!(-x, -12);
672     /// ```
673     #[must_use]
674     #[stable(feature = "rust1", since = "1.0.0")]
neg(self) -> Self::Output675     fn neg(self) -> Self::Output;
676 }
677 
678 macro_rules! neg_impl {
679     ($($t:ty)*) => ($(
680         #[stable(feature = "rust1", since = "1.0.0")]
681         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
682         impl const Neg for $t {
683             type Output = $t;
684 
685             #[inline]
686             #[rustc_inherit_overflow_checks]
687             fn neg(self) -> $t { -self }
688         }
689 
690         forward_ref_unop! { impl const Neg, neg for $t }
691     )*)
692 }
693 
694 neg_impl! { isize i8 i16 i32 i64 i128 f32 f64 }
695 
696 /// The addition assignment operator `+=`.
697 ///
698 /// # Examples
699 ///
700 /// This example creates a `Point` struct that implements the `AddAssign`
701 /// trait, and then demonstrates add-assigning to a mutable `Point`.
702 ///
703 /// ```
704 /// use std::ops::AddAssign;
705 ///
706 /// #[derive(Debug, Copy, Clone, PartialEq)]
707 /// struct Point {
708 ///     x: i32,
709 ///     y: i32,
710 /// }
711 ///
712 /// impl AddAssign for Point {
713 ///     fn add_assign(&mut self, other: Self) {
714 ///         *self = Self {
715 ///             x: self.x + other.x,
716 ///             y: self.y + other.y,
717 ///         };
718 ///     }
719 /// }
720 ///
721 /// let mut point = Point { x: 1, y: 0 };
722 /// point += Point { x: 2, y: 3 };
723 /// assert_eq!(point, Point { x: 3, y: 3 });
724 /// ```
725 #[lang = "add_assign"]
726 #[stable(feature = "op_assign_traits", since = "1.8.0")]
727 #[rustc_on_unimplemented(
728     message = "cannot add-assign `{Rhs}` to `{Self}`",
729     label = "no implementation for `{Self} += {Rhs}`"
730 )]
731 #[doc(alias = "+")]
732 #[doc(alias = "+=")]
733 pub trait AddAssign<Rhs = Self> {
734     /// Performs the `+=` operation.
735     ///
736     /// # Example
737     ///
738     /// ```
739     /// let mut x: u32 = 12;
740     /// x += 1;
741     /// assert_eq!(x, 13);
742     /// ```
743     #[stable(feature = "op_assign_traits", since = "1.8.0")]
add_assign(&mut self, rhs: Rhs)744     fn add_assign(&mut self, rhs: Rhs);
745 }
746 
747 macro_rules! add_assign_impl {
748     ($($t:ty)+) => ($(
749         #[stable(feature = "op_assign_traits", since = "1.8.0")]
750         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
751         impl const AddAssign for $t {
752             #[inline]
753             #[rustc_inherit_overflow_checks]
754             fn add_assign(&mut self, other: $t) { *self += other }
755         }
756 
757         forward_ref_op_assign! { impl const AddAssign, add_assign for $t, $t }
758     )+)
759 }
760 
761 add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
762 
763 /// The subtraction assignment operator `-=`.
764 ///
765 /// # Examples
766 ///
767 /// This example creates a `Point` struct that implements the `SubAssign`
768 /// trait, and then demonstrates sub-assigning to a mutable `Point`.
769 ///
770 /// ```
771 /// use std::ops::SubAssign;
772 ///
773 /// #[derive(Debug, Copy, Clone, PartialEq)]
774 /// struct Point {
775 ///     x: i32,
776 ///     y: i32,
777 /// }
778 ///
779 /// impl SubAssign for Point {
780 ///     fn sub_assign(&mut self, other: Self) {
781 ///         *self = Self {
782 ///             x: self.x - other.x,
783 ///             y: self.y - other.y,
784 ///         };
785 ///     }
786 /// }
787 ///
788 /// let mut point = Point { x: 3, y: 3 };
789 /// point -= Point { x: 2, y: 3 };
790 /// assert_eq!(point, Point {x: 1, y: 0});
791 /// ```
792 #[lang = "sub_assign"]
793 #[stable(feature = "op_assign_traits", since = "1.8.0")]
794 #[rustc_on_unimplemented(
795     message = "cannot subtract-assign `{Rhs}` from `{Self}`",
796     label = "no implementation for `{Self} -= {Rhs}`"
797 )]
798 #[doc(alias = "-")]
799 #[doc(alias = "-=")]
800 pub trait SubAssign<Rhs = Self> {
801     /// Performs the `-=` operation.
802     ///
803     /// # Example
804     ///
805     /// ```
806     /// let mut x: u32 = 12;
807     /// x -= 1;
808     /// assert_eq!(x, 11);
809     /// ```
810     #[stable(feature = "op_assign_traits", since = "1.8.0")]
sub_assign(&mut self, rhs: Rhs)811     fn sub_assign(&mut self, rhs: Rhs);
812 }
813 
814 macro_rules! sub_assign_impl {
815     ($($t:ty)+) => ($(
816         #[stable(feature = "op_assign_traits", since = "1.8.0")]
817         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
818         impl const SubAssign for $t {
819             #[inline]
820             #[rustc_inherit_overflow_checks]
821             fn sub_assign(&mut self, other: $t) { *self -= other }
822         }
823 
824         forward_ref_op_assign! { impl const SubAssign, sub_assign for $t, $t }
825     )+)
826 }
827 
828 sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
829 
830 /// The multiplication assignment operator `*=`.
831 ///
832 /// # Examples
833 ///
834 /// ```
835 /// use std::ops::MulAssign;
836 ///
837 /// #[derive(Debug, PartialEq)]
838 /// struct Frequency { hertz: f64 }
839 ///
840 /// impl MulAssign<f64> for Frequency {
841 ///     fn mul_assign(&mut self, rhs: f64) {
842 ///         self.hertz *= rhs;
843 ///     }
844 /// }
845 ///
846 /// let mut frequency = Frequency { hertz: 50.0 };
847 /// frequency *= 4.0;
848 /// assert_eq!(Frequency { hertz: 200.0 }, frequency);
849 /// ```
850 #[lang = "mul_assign"]
851 #[stable(feature = "op_assign_traits", since = "1.8.0")]
852 #[rustc_on_unimplemented(
853     message = "cannot multiply-assign `{Self}` by `{Rhs}`",
854     label = "no implementation for `{Self} *= {Rhs}`"
855 )]
856 #[doc(alias = "*")]
857 #[doc(alias = "*=")]
858 pub trait MulAssign<Rhs = Self> {
859     /// Performs the `*=` operation.
860     ///
861     /// # Example
862     ///
863     /// ```
864     /// let mut x: u32 = 12;
865     /// x *= 2;
866     /// assert_eq!(x, 24);
867     /// ```
868     #[stable(feature = "op_assign_traits", since = "1.8.0")]
mul_assign(&mut self, rhs: Rhs)869     fn mul_assign(&mut self, rhs: Rhs);
870 }
871 
872 macro_rules! mul_assign_impl {
873     ($($t:ty)+) => ($(
874         #[stable(feature = "op_assign_traits", since = "1.8.0")]
875         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
876         impl const MulAssign for $t {
877             #[inline]
878             #[rustc_inherit_overflow_checks]
879             fn mul_assign(&mut self, other: $t) { *self *= other }
880         }
881 
882         forward_ref_op_assign! { impl const MulAssign, mul_assign for $t, $t }
883     )+)
884 }
885 
886 mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
887 
888 /// The division assignment operator `/=`.
889 ///
890 /// # Examples
891 ///
892 /// ```
893 /// use std::ops::DivAssign;
894 ///
895 /// #[derive(Debug, PartialEq)]
896 /// struct Frequency { hertz: f64 }
897 ///
898 /// impl DivAssign<f64> for Frequency {
899 ///     fn div_assign(&mut self, rhs: f64) {
900 ///         self.hertz /= rhs;
901 ///     }
902 /// }
903 ///
904 /// let mut frequency = Frequency { hertz: 200.0 };
905 /// frequency /= 4.0;
906 /// assert_eq!(Frequency { hertz: 50.0 }, frequency);
907 /// ```
908 #[lang = "div_assign"]
909 #[stable(feature = "op_assign_traits", since = "1.8.0")]
910 #[rustc_on_unimplemented(
911     message = "cannot divide-assign `{Self}` by `{Rhs}`",
912     label = "no implementation for `{Self} /= {Rhs}`"
913 )]
914 #[doc(alias = "/")]
915 #[doc(alias = "/=")]
916 pub trait DivAssign<Rhs = Self> {
917     /// Performs the `/=` operation.
918     ///
919     /// # Example
920     ///
921     /// ```
922     /// let mut x: u32 = 12;
923     /// x /= 2;
924     /// assert_eq!(x, 6);
925     /// ```
926     #[stable(feature = "op_assign_traits", since = "1.8.0")]
div_assign(&mut self, rhs: Rhs)927     fn div_assign(&mut self, rhs: Rhs);
928 }
929 
930 macro_rules! div_assign_impl {
931     ($($t:ty)+) => ($(
932         #[stable(feature = "op_assign_traits", since = "1.8.0")]
933         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
934         impl const DivAssign for $t {
935             #[inline]
936             fn div_assign(&mut self, other: $t) { *self /= other }
937         }
938 
939         forward_ref_op_assign! { impl const DivAssign, div_assign for $t, $t }
940     )+)
941 }
942 
943 div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
944 
945 /// The remainder assignment operator `%=`.
946 ///
947 /// # Examples
948 ///
949 /// ```
950 /// use std::ops::RemAssign;
951 ///
952 /// struct CookieJar { cookies: u32 }
953 ///
954 /// impl RemAssign<u32> for CookieJar {
955 ///     fn rem_assign(&mut self, piles: u32) {
956 ///         self.cookies %= piles;
957 ///     }
958 /// }
959 ///
960 /// let mut jar = CookieJar { cookies: 31 };
961 /// let piles = 4;
962 ///
963 /// println!("Splitting up {} cookies into {} even piles!", jar.cookies, piles);
964 ///
965 /// jar %= piles;
966 ///
967 /// println!("{} cookies remain in the cookie jar!", jar.cookies);
968 /// ```
969 #[lang = "rem_assign"]
970 #[stable(feature = "op_assign_traits", since = "1.8.0")]
971 #[rustc_on_unimplemented(
972     message = "cannot mod-assign `{Self}` by `{Rhs}``",
973     label = "no implementation for `{Self} %= {Rhs}`"
974 )]
975 #[doc(alias = "%")]
976 #[doc(alias = "%=")]
977 pub trait RemAssign<Rhs = Self> {
978     /// Performs the `%=` operation.
979     ///
980     /// # Example
981     ///
982     /// ```
983     /// let mut x: u32 = 12;
984     /// x %= 10;
985     /// assert_eq!(x, 2);
986     /// ```
987     #[stable(feature = "op_assign_traits", since = "1.8.0")]
rem_assign(&mut self, rhs: Rhs)988     fn rem_assign(&mut self, rhs: Rhs);
989 }
990 
991 macro_rules! rem_assign_impl {
992     ($($t:ty)+) => ($(
993         #[stable(feature = "op_assign_traits", since = "1.8.0")]
994         #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
995         impl const RemAssign for $t {
996             #[inline]
997             fn rem_assign(&mut self, other: $t) { *self %= other }
998         }
999 
1000         forward_ref_op_assign! { impl const RemAssign, rem_assign for $t, $t }
1001     )+)
1002 }
1003 
1004 rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
1005