]> git.lizzy.rs Git - rust.git/blob - src/libcore/ops/arith.rs
Unimplement Send/Sync for ::env::{Args,ArgsOs,Vars,VarsOs}
[rust.git] / src / libcore / ops / arith.rs
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 ///
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 ///
19 /// # Examples
20 ///
21 /// ## `Add`able points
22 ///
23 /// ```
24 /// use std::ops::Add;
25 ///
26 /// #[derive(Debug, PartialEq)]
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 ///
43 /// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
44 ///            Point { x: 3, y: 3 });
45 /// ```
46 ///
47 /// ## Implementing `Add` with generics
48 ///
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 ///
55 /// #[derive(Debug, PartialEq)]
56 /// struct Point<T> {
57 ///     x: T,
58 ///     y: T,
59 /// }
60 ///
61 /// // Notice that the implementation uses the associated type `Output`.
62 /// impl<T: Add<Output=T>> Add for Point<T> {
63 ///     type Output = Point<T>;
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 ///
73 /// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
74 ///            Point { x: 3, y: 3 });
75 /// ```
76 #[lang = "add"]
77 #[stable(feature = "rust1", since = "1.0.0")]
78 #[rustc_on_unimplemented = "no implementation for `{Self} + {RHS}`"]
79 pub trait Add<RHS=Self> {
80     /// The resulting type after applying the `+` operator.
81     #[stable(feature = "rust1", since = "1.0.0")]
82     type Output;
83
84     /// Performs the `+` operation.
85     #[stable(feature = "rust1", since = "1.0.0")]
86     fn add(self, rhs: RHS) -> Self::Output;
87 }
88
89 macro_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
104 add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
105
106 /// The subtraction operator `-`.
107 ///
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 ///
114 /// # Examples
115 ///
116 /// ## `Sub`tractable points
117 ///
118 /// ```
119 /// use std::ops::Sub;
120 ///
121 /// #[derive(Debug, PartialEq)]
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 ///
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.
146 ///
147 /// ```
148 /// use std::ops::Sub;
149 ///
150 /// #[derive(Debug, PartialEq)]
151 /// struct Point<T> {
152 ///     x: T,
153 ///     y: T,
154 /// }
155 ///
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 /// ```
171 #[lang = "sub"]
172 #[stable(feature = "rust1", since = "1.0.0")]
173 #[rustc_on_unimplemented = "no implementation for `{Self} - {RHS}`"]
174 pub trait Sub<RHS=Self> {
175     /// The resulting type after applying the `-` operator.
176     #[stable(feature = "rust1", since = "1.0.0")]
177     type Output;
178
179     /// Performs the `-` operation.
180     #[stable(feature = "rust1", since = "1.0.0")]
181     fn sub(self, rhs: RHS) -> Self::Output;
182 }
183
184 macro_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
199 sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
200
201 /// The multiplication operator `*`.
202 ///
203 /// Note that `RHS` is `Self` by default, but this is not mandatory.
204 ///
205 /// # Examples
206 ///
207 /// ## `Mul`tipliable rational numbers
208 ///
209 /// ```
210 /// use std::ops::Mul;
211 ///
212 /// // By the fundamental theorem of arithmetic, rational numbers in lowest
213 /// // terms are unique. So, by keeping `Rational`s in reduced form, we can
214 /// // derive `Eq` and `PartialEq`.
215 /// #[derive(Debug, Eq, PartialEq)]
216 /// struct Rational {
217 ///     nominator: usize,
218 ///     denominator: usize,
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 ///
266 /// ## Multiplying vectors by scalars as in linear algebra
267 ///
268 /// ```
269 /// use std::ops::Mul;
270 ///
271 /// struct Scalar { value: usize }
272 ///
273 /// #[derive(Debug, PartialEq)]
274 /// struct Vector { value: Vec<usize> }
275 ///
276 /// impl Mul<Scalar> for Vector {
277 ///     type Output = Vector;
278 ///
279 ///     fn mul(self, rhs: Scalar) -> Vector {
280 ///         Vector { value: self.value.iter().map(|v| v * rhs.value).collect() }
281 ///     }
282 /// }
283 ///
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] });
287 /// ```
288 #[lang = "mul"]
289 #[stable(feature = "rust1", since = "1.0.0")]
290 #[rustc_on_unimplemented = "no implementation for `{Self} * {RHS}`"]
291 pub trait Mul<RHS=Self> {
292     /// The resulting type after applying the `*` operator.
293     #[stable(feature = "rust1", since = "1.0.0")]
294     type Output;
295
296     /// Performs the `*` operation.
297     #[stable(feature = "rust1", since = "1.0.0")]
298     fn mul(self, rhs: RHS) -> Self::Output;
299 }
300
301 macro_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
316 mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
317
318 /// The division operator `/`.
319 ///
320 /// Note that `RHS` is `Self` by default, but this is not mandatory.
321 ///
322 /// # Examples
323 ///
324 /// ## `Div`idable rational numbers
325 ///
326 /// ```
327 /// use std::ops::Div;
328 ///
329 /// // By the fundamental theorem of arithmetic, rational numbers in lowest
330 /// // terms are unique. So, by keeping `Rational`s in reduced form, we can
331 /// // derive `Eq` and `PartialEq`.
332 /// #[derive(Debug, Eq, PartialEq)]
333 /// struct Rational {
334 ///     nominator: usize,
335 ///     denominator: usize,
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 ///
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));
385 /// ```
386 ///
387 /// ## Dividing vectors by scalars as in linear algebra
388 ///
389 /// ```
390 /// use std::ops::Div;
391 ///
392 /// struct Scalar { value: f32 }
393 ///
394 /// #[derive(Debug, PartialEq)]
395 /// struct Vector { value: Vec<f32> }
396 ///
397 /// impl Div<Scalar> for Vector {
398 ///     type Output = Vector;
399 ///
400 ///     fn div(self, rhs: Scalar) -> Vector {
401 ///         Vector { value: self.value.iter().map(|v| v / rhs.value).collect() }
402 ///     }
403 /// }
404 ///
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] });
408 /// ```
409 #[lang = "div"]
410 #[stable(feature = "rust1", since = "1.0.0")]
411 #[rustc_on_unimplemented = "no implementation for `{Self} / {RHS}`"]
412 pub trait Div<RHS=Self> {
413     /// The resulting type after applying the `/` operator.
414     #[stable(feature = "rust1", since = "1.0.0")]
415     type Output;
416
417     /// Performs the `/` operation.
418     #[stable(feature = "rust1", since = "1.0.0")]
419     fn div(self, rhs: RHS) -> Self::Output;
420 }
421
422 macro_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
438 div_impl_integer! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
439
440 macro_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
454 div_impl_float! { f32 f64 }
455
456 /// The remainder operator `%`.
457 ///
458 /// Note that `RHS` is `Self` by default, but this is not mandatory.
459 ///
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,
487 /// // the remainder would be &[6, 7].
488 /// assert_eq!(SplitSlice { slice: &[0, 1, 2, 3, 4, 5, 6, 7] } % 3,
489 ///            SplitSlice { slice: &[6, 7] });
490 /// ```
491 #[lang = "rem"]
492 #[stable(feature = "rust1", since = "1.0.0")]
493 #[rustc_on_unimplemented = "no implementation for `{Self} % {RHS}`"]
494 pub trait Rem<RHS=Self> {
495     /// The resulting type after applying the `%` operator.
496     #[stable(feature = "rust1", since = "1.0.0")]
497     type Output = Self;
498
499     /// Performs the `%` operation.
500     #[stable(feature = "rust1", since = "1.0.0")]
501     fn rem(self, rhs: RHS) -> Self::Output;
502 }
503
504 macro_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
520 rem_impl_integer! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
521
522
523 macro_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
537 rem_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 ///
568 /// // A negative positive is a negative.
569 /// assert_eq!(-Sign::Positive, Sign::Negative);
570 /// // A double negative is a positive.
571 /// assert_eq!(-Sign::Negative, Sign::Positive);
572 /// // Zero is its own negation.
573 /// assert_eq!(-Sign::Zero, Sign::Zero);
574 /// ```
575 #[lang = "neg"]
576 #[stable(feature = "rust1", since = "1.0.0")]
577 pub trait Neg {
578     /// The resulting type after applying the `-` operator.
579     #[stable(feature = "rust1", since = "1.0.0")]
580     type Output;
581
582     /// Performs the unary `-` operation.
583     #[stable(feature = "rust1", since = "1.0.0")]
584     fn neg(self) -> Self::Output;
585 }
586
587
588
589 macro_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
604 macro_rules! neg_impl_numeric {
605     ($($t:ty)*) => { neg_impl_core!{ x => -x, $($t)*} }
606 }
607
608 #[allow(unused_macros)]
609 macro_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 }
617 neg_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 ///
629 /// #[derive(Debug, PartialEq)]
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 ///
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}`"]
651 pub trait AddAssign<Rhs=Self> {
652     /// Performs the `+=` operation.
653     #[stable(feature = "op_assign_traits", since = "1.8.0")]
654     fn add_assign(&mut self, rhs: Rhs);
655 }
656
657 macro_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         }
665
666         forward_ref_op_assign! { impl AddAssign, add_assign for $t, $t }
667     )+)
668 }
669
670 add_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 ///
682 /// #[derive(Debug, PartialEq)]
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 ///
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}`"]
704 pub trait SubAssign<Rhs=Self> {
705     /// Performs the `-=` operation.
706     #[stable(feature = "op_assign_traits", since = "1.8.0")]
707     fn sub_assign(&mut self, rhs: Rhs);
708 }
709
710 macro_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         }
718
719         forward_ref_op_assign! { impl SubAssign, sub_assign for $t, $t }
720     )+)
721 }
722
723 sub_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 ///
729 /// ```
730 /// use std::ops::MulAssign;
731 ///
732 /// #[derive(Debug, PartialEq)]
733 /// struct Frequency { hertz: f64 }
734 ///
735 /// impl MulAssign<f64> for Frequency {
736 ///     fn mul_assign(&mut self, rhs: f64) {
737 ///         self.hertz *= rhs;
738 ///     }
739 /// }
740 ///
741 /// let mut frequency = Frequency { hertz: 50.0 };
742 /// frequency *= 4.0;
743 /// assert_eq!(Frequency { hertz: 200.0 }, frequency);
744 /// ```
745 #[lang = "mul_assign"]
746 #[stable(feature = "op_assign_traits", since = "1.8.0")]
747 #[rustc_on_unimplemented = "no implementation for `{Self} *= {Rhs}`"]
748 pub trait MulAssign<Rhs=Self> {
749     /// Performs the `*=` operation.
750     #[stable(feature = "op_assign_traits", since = "1.8.0")]
751     fn mul_assign(&mut self, rhs: Rhs);
752 }
753
754 macro_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         }
762
763         forward_ref_op_assign! { impl MulAssign, mul_assign for $t, $t }
764     )+)
765 }
766
767 mul_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 ///
773 /// ```
774 /// use std::ops::DivAssign;
775 ///
776 /// #[derive(Debug, PartialEq)]
777 /// struct Frequency { hertz: f64 }
778 ///
779 /// impl DivAssign<f64> for Frequency {
780 ///     fn div_assign(&mut self, rhs: f64) {
781 ///         self.hertz /= rhs;
782 ///     }
783 /// }
784 ///
785 /// let mut frequency = Frequency { hertz: 200.0 };
786 /// frequency /= 4.0;
787 /// assert_eq!(Frequency { hertz: 50.0 }, frequency);
788 /// ```
789 #[lang = "div_assign"]
790 #[stable(feature = "op_assign_traits", since = "1.8.0")]
791 #[rustc_on_unimplemented = "no implementation for `{Self} /= {Rhs}`"]
792 pub trait DivAssign<Rhs=Self> {
793     /// Performs the `/=` operation.
794     #[stable(feature = "op_assign_traits", since = "1.8.0")]
795     fn div_assign(&mut self, rhs: Rhs);
796 }
797
798 macro_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         }
805
806         forward_ref_op_assign! { impl DivAssign, div_assign for $t, $t }
807     )+)
808 }
809
810 div_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 ///
816 /// ```
817 /// use std::ops::RemAssign;
818 ///
819 /// struct CookieJar { cookies: u32 }
820 ///
821 /// impl RemAssign<u32> for CookieJar {
822 ///     fn rem_assign(&mut self, piles: u32) {
823 ///         self.cookies %= piles;
824 ///     }
825 /// }
826 ///
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);
835 /// ```
836 #[lang = "rem_assign"]
837 #[stable(feature = "op_assign_traits", since = "1.8.0")]
838 #[rustc_on_unimplemented = "no implementation for `{Self} %= {Rhs}`"]
839 pub trait RemAssign<Rhs=Self> {
840     /// Performs the `%=` operation.
841     #[stable(feature = "op_assign_traits", since = "1.8.0")]
842     fn rem_assign(&mut self, rhs: Rhs);
843 }
844
845 macro_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         }
852
853         forward_ref_op_assign! { impl RemAssign, rem_assign for $t, $t }
854     )+)
855 }
856
857 rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }