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