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