]> git.proxmox.com Git - rustc.git/blame - library/core/src/ops/arith.rs
New upstream version 1.76.0+dfsg1
[rustc.git] / library / core / src / ops / arith.rs
CommitLineData
041b39d2
XL
1/// The addition operator `+`.
2///
532ac7d7 3/// Note that `Rhs` is `Self` by default, but this is not mandatory. For
3b2f2976
XL
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///
041b39d2
XL
9/// # Examples
10///
3b2f2976 11/// ## `Add`able points
041b39d2
XL
12///
13/// ```
14/// use std::ops::Add;
15///
ba9703b0 16/// #[derive(Debug, Copy, Clone, PartialEq)]
041b39d2
XL
17/// struct Point {
18/// x: i32,
19/// y: i32,
20/// }
21///
22/// impl Add for Point {
532ac7d7 23/// type Output = Self;
041b39d2 24///
532ac7d7
XL
25/// fn add(self, other: Self) -> Self {
26/// Self {
041b39d2
XL
27/// x: self.x + other.x,
28/// y: self.y + other.y,
29/// }
30/// }
31/// }
32///
3b2f2976
XL
33/// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
34/// Point { x: 3, y: 3 });
041b39d2
XL
35/// ```
36///
3b2f2976
XL
37/// ## Implementing `Add` with generics
38///
041b39d2
XL
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///
ba9703b0 45/// #[derive(Debug, Copy, Clone, PartialEq)]
041b39d2
XL
46/// struct Point<T> {
47/// x: T,
48/// y: T,
49/// }
50///
3b2f2976 51/// // Notice that the implementation uses the associated type `Output`.
9fa01778 52/// impl<T: Add<Output = T>> Add for Point<T> {
532ac7d7 53/// type Output = Self;
041b39d2 54///
532ac7d7
XL
55/// fn add(self, other: Self) -> Self::Output {
56/// Self {
041b39d2
XL
57/// x: self.x + other.x,
58/// y: self.y + other.y,
59/// }
60/// }
61/// }
62///
3b2f2976
XL
63/// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
64/// Point { x: 3, y: 3 });
041b39d2 65/// ```
041b39d2
XL
66#[lang = "add"]
67#[stable(feature = "rust1", since = "1.0.0")]
2b03887a
FG
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
2c00a5a8 74)]
83c7162d 75#[doc(alias = "+")]
60c5eb7d 76pub trait Add<Rhs = Self> {
3b2f2976 77 /// The resulting type after applying the `+` operator.
041b39d2
XL
78 #[stable(feature = "rust1", since = "1.0.0")]
79 type Output;
80
3b2f2976 81 /// Performs the `+` operation.
1b1a35ee
XL
82 ///
83 /// # Example
84 ///
85 /// ```
86 /// assert_eq!(12 + 1, 13);
87 /// ```
9ffffee4
FG
88 #[must_use = "this returns the result of the operation, without modifying the original"]
89 #[rustc_diagnostic_item = "add"]
041b39d2 90 #[stable(feature = "rust1", since = "1.0.0")]
532ac7d7 91 fn add(self, rhs: Rhs) -> Self::Output;
041b39d2
XL
92}
93
94macro_rules! add_impl {
95 ($($t:ty)*) => ($(
96 #[stable(feature = "rust1", since = "1.0.0")]
49aad941 97 impl Add for $t {
041b39d2
XL
98 type Output = $t;
99
100 #[inline]
4b012472 101 #[track_caller]
041b39d2
XL
102 #[rustc_inherit_overflow_checks]
103 fn add(self, other: $t) -> $t { self + other }
104 }
105
49aad941 106 forward_ref_binop! { impl Add, add for $t, $t }
041b39d2
XL
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///
532ac7d7 114/// Note that `Rhs` is `Self` by default, but this is not mandatory. For
3b2f2976
XL
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///
041b39d2
XL
120/// # Examples
121///
3b2f2976 122/// ## `Sub`tractable points
041b39d2
XL
123///
124/// ```
125/// use std::ops::Sub;
126///
ba9703b0 127/// #[derive(Debug, Copy, Clone, PartialEq)]
041b39d2
XL
128/// struct Point {
129/// x: i32,
130/// y: i32,
131/// }
132///
133/// impl Sub for Point {
1b1a35ee 134/// type Output = Self;
041b39d2 135///
1b1a35ee
XL
136/// fn sub(self, other: Self) -> Self::Output {
137/// Self {
041b39d2
XL
138/// x: self.x - other.x,
139/// y: self.y - other.y,
140/// }
141/// }
142/// }
143///
3b2f2976
XL
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.
041b39d2 152///
041b39d2 153/// ```
3b2f2976 154/// use std::ops::Sub;
041b39d2 155///
3b2f2976
XL
156/// #[derive(Debug, PartialEq)]
157/// struct Point<T> {
158/// x: T,
159/// y: T,
160/// }
041b39d2 161///
3b2f2976 162/// // Notice that the implementation uses the associated type `Output`.
9fa01778 163/// impl<T: Sub<Output = T>> Sub for Point<T> {
532ac7d7 164/// type Output = Self;
3b2f2976 165///
532ac7d7 166/// fn sub(self, other: Self) -> Self::Output {
3b2f2976
XL
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/// ```
041b39d2
XL
177#[lang = "sub"]
178#[stable(feature = "rust1", since = "1.0.0")]
60c5eb7d
XL
179#[rustc_on_unimplemented(
180 message = "cannot subtract `{Rhs}` from `{Self}`",
2b03887a
FG
181 label = "no implementation for `{Self} - {Rhs}`",
182 append_const_msg
60c5eb7d 183)]
83c7162d 184#[doc(alias = "-")]
60c5eb7d 185pub trait Sub<Rhs = Self> {
3b2f2976 186 /// The resulting type after applying the `-` operator.
041b39d2
XL
187 #[stable(feature = "rust1", since = "1.0.0")]
188 type Output;
189
3b2f2976 190 /// Performs the `-` operation.
1b1a35ee
XL
191 ///
192 /// # Example
193 ///
194 /// ```
195 /// assert_eq!(12 - 1, 11);
196 /// ```
9ffffee4
FG
197 #[must_use = "this returns the result of the operation, without modifying the original"]
198 #[rustc_diagnostic_item = "sub"]
041b39d2 199 #[stable(feature = "rust1", since = "1.0.0")]
532ac7d7 200 fn sub(self, rhs: Rhs) -> Self::Output;
041b39d2
XL
201}
202
203macro_rules! sub_impl {
204 ($($t:ty)*) => ($(
205 #[stable(feature = "rust1", since = "1.0.0")]
49aad941 206 impl Sub for $t {
041b39d2
XL
207 type Output = $t;
208
209 #[inline]
4b012472 210 #[track_caller]
041b39d2
XL
211 #[rustc_inherit_overflow_checks]
212 fn sub(self, other: $t) -> $t { self - other }
213 }
214
49aad941 215 forward_ref_binop! { impl Sub, sub for $t, $t }
041b39d2
XL
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///
532ac7d7 223/// Note that `Rhs` is `Self` by default, but this is not mandatory.
3b2f2976 224///
041b39d2
XL
225/// # Examples
226///
3b2f2976 227/// ## `Mul`tipliable rational numbers
041b39d2
XL
228///
229/// ```
230/// use std::ops::Mul;
231///
3b2f2976
XL
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)]
041b39d2 236/// struct Rational {
48663c56 237/// numerator: usize,
041b39d2
XL
238/// denominator: usize,
239/// }
240///
241/// impl Rational {
48663c56 242/// fn new(numerator: usize, denominator: usize) -> Self {
041b39d2
XL
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.
48663c56 249/// let gcd = gcd(numerator, denominator);
1b1a35ee 250/// Self {
48663c56 251/// numerator: numerator / gcd,
041b39d2
XL
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 {
48663c56 262/// let numerator = self.numerator * rhs.numerator;
041b39d2 263/// let denominator = self.denominator * rhs.denominator;
1b1a35ee 264/// Self::new(numerator, denominator)
041b39d2
XL
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///
3b2f2976 286/// ## Multiplying vectors by scalars as in linear algebra
041b39d2
XL
287///
288/// ```
289/// use std::ops::Mul;
290///
3b2f2976 291/// struct Scalar { value: usize }
041b39d2 292///
3b2f2976
XL
293/// #[derive(Debug, PartialEq)]
294/// struct Vector { value: Vec<usize> }
041b39d2 295///
3b2f2976 296/// impl Mul<Scalar> for Vector {
532ac7d7 297/// type Output = Self;
041b39d2 298///
532ac7d7 299/// fn mul(self, rhs: Scalar) -> Self::Output {
1b1a35ee 300/// Self { value: self.value.iter().map(|v| v * rhs.value).collect() }
041b39d2
XL
301/// }
302/// }
303///
3b2f2976
XL
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] });
041b39d2
XL
307/// ```
308#[lang = "mul"]
309#[stable(feature = "rust1", since = "1.0.0")]
60c5eb7d 310#[rustc_on_unimplemented(
29967ef6 311 message = "cannot multiply `{Self}` by `{Rhs}`",
60c5eb7d
XL
312 label = "no implementation for `{Self} * {Rhs}`"
313)]
83c7162d 314#[doc(alias = "*")]
60c5eb7d 315pub trait Mul<Rhs = Self> {
3b2f2976 316 /// The resulting type after applying the `*` operator.
041b39d2
XL
317 #[stable(feature = "rust1", since = "1.0.0")]
318 type Output;
319
3b2f2976 320 /// Performs the `*` operation.
1b1a35ee
XL
321 ///
322 /// # Example
323 ///
324 /// ```
325 /// assert_eq!(12 * 2, 24);
326 /// ```
9ffffee4
FG
327 #[must_use = "this returns the result of the operation, without modifying the original"]
328 #[rustc_diagnostic_item = "mul"]
041b39d2 329 #[stable(feature = "rust1", since = "1.0.0")]
532ac7d7 330 fn mul(self, rhs: Rhs) -> Self::Output;
041b39d2
XL
331}
332
333macro_rules! mul_impl {
334 ($($t:ty)*) => ($(
335 #[stable(feature = "rust1", since = "1.0.0")]
49aad941 336 impl Mul for $t {
041b39d2
XL
337 type Output = $t;
338
339 #[inline]
4b012472 340 #[track_caller]
041b39d2
XL
341 #[rustc_inherit_overflow_checks]
342 fn mul(self, other: $t) -> $t { self * other }
343 }
344
49aad941 345 forward_ref_binop! { impl Mul, mul for $t, $t }
041b39d2
XL
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///
532ac7d7 353/// Note that `Rhs` is `Self` by default, but this is not mandatory.
3b2f2976 354///
041b39d2
XL
355/// # Examples
356///
3b2f2976 357/// ## `Div`idable rational numbers
041b39d2
XL
358///
359/// ```
360/// use std::ops::Div;
361///
3b2f2976
XL
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)]
041b39d2 366/// struct Rational {
48663c56 367/// numerator: usize,
041b39d2
XL
368/// denominator: usize,
369/// }
370///
371/// impl Rational {
48663c56 372/// fn new(numerator: usize, denominator: usize) -> Self {
041b39d2
XL
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.
48663c56 379/// let gcd = gcd(numerator, denominator);
1b1a35ee 380/// Self {
48663c56 381/// numerator: numerator / gcd,
041b39d2
XL
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///
532ac7d7 391/// fn div(self, rhs: Self) -> Self::Output {
48663c56 392/// if rhs.numerator == 0 {
041b39d2
XL
393/// panic!("Cannot divide by zero-valued `Rational`!");
394/// }
395///
48663c56
XL
396/// let numerator = self.numerator * rhs.denominator;
397/// let denominator = self.denominator * rhs.numerator;
1b1a35ee 398/// Self::new(numerator, denominator)
041b39d2
XL
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///
3b2f2976
XL
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));
041b39d2
XL
418/// ```
419///
3b2f2976 420/// ## Dividing vectors by scalars as in linear algebra
041b39d2
XL
421///
422/// ```
423/// use std::ops::Div;
424///
3b2f2976 425/// struct Scalar { value: f32 }
041b39d2 426///
3b2f2976
XL
427/// #[derive(Debug, PartialEq)]
428/// struct Vector { value: Vec<f32> }
041b39d2
XL
429///
430/// impl Div<Scalar> for Vector {
532ac7d7 431/// type Output = Self;
041b39d2 432///
532ac7d7 433/// fn div(self, rhs: Scalar) -> Self::Output {
1b1a35ee 434/// Self { value: self.value.iter().map(|v| v / rhs.value).collect() }
041b39d2
XL
435/// }
436/// }
437///
3b2f2976
XL
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] });
041b39d2
XL
441/// ```
442#[lang = "div"]
443#[stable(feature = "rust1", since = "1.0.0")]
60c5eb7d
XL
444#[rustc_on_unimplemented(
445 message = "cannot divide `{Self}` by `{Rhs}`",
446 label = "no implementation for `{Self} / {Rhs}`"
447)]
83c7162d 448#[doc(alias = "/")]
60c5eb7d 449pub trait Div<Rhs = Self> {
3b2f2976 450 /// The resulting type after applying the `/` operator.
041b39d2
XL
451 #[stable(feature = "rust1", since = "1.0.0")]
452 type Output;
453
3b2f2976 454 /// Performs the `/` operation.
1b1a35ee
XL
455 ///
456 /// # Example
457 ///
458 /// ```
459 /// assert_eq!(12 / 2, 6);
460 /// ```
9ffffee4
FG
461 #[must_use = "this returns the result of the operation, without modifying the original"]
462 #[rustc_diagnostic_item = "div"]
041b39d2 463 #[stable(feature = "rust1", since = "1.0.0")]
532ac7d7 464 fn div(self, rhs: Rhs) -> Self::Output;
041b39d2
XL
465}
466
467macro_rules! div_impl_integer {
cdc7bbd5 468 ($(($($t:ty)*) => $panic:expr),*) => ($($(
041b39d2
XL
469 /// This operation rounds towards zero, truncating any
470 /// fractional part of the exact result.
cdc7bbd5
XL
471 ///
472 /// # Panics
473 ///
474 #[doc = $panic]
041b39d2 475 #[stable(feature = "rust1", since = "1.0.0")]
49aad941 476 impl Div for $t {
041b39d2
XL
477 type Output = $t;
478
479 #[inline]
4b012472 480 #[track_caller]
041b39d2
XL
481 fn div(self, other: $t) -> $t { self / other }
482 }
483
49aad941 484 forward_ref_binop! { impl Div, div for $t, $t }
cdc7bbd5 485 )*)*)
041b39d2
XL
486}
487
cdc7bbd5
XL
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}
041b39d2
XL
492
493macro_rules! div_impl_float {
494 ($($t:ty)*) => ($(
495 #[stable(feature = "rust1", since = "1.0.0")]
49aad941 496 impl Div for $t {
041b39d2
XL
497 type Output = $t;
498
499 #[inline]
500 fn div(self, other: $t) -> $t { self / other }
501 }
502
49aad941 503 forward_ref_binop! { impl Div, div for $t, $t }
041b39d2
XL
504 )*)
505}
506
507div_impl_float! { f32 f64 }
508
509/// The remainder operator `%`.
510///
532ac7d7 511/// Note that `Rhs` is `Self` by default, but this is not mandatory.
3b2f2976 512///
041b39d2
XL
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)]
49aad941 524/// struct SplitSlice<'a, T> {
041b39d2
XL
525/// slice: &'a [T],
526/// }
527///
528/// impl<'a, T> Rem<usize> for SplitSlice<'a, T> {
532ac7d7 529/// type Output = Self;
041b39d2 530///
532ac7d7 531/// fn rem(self, modulus: usize) -> Self::Output {
041b39d2
XL
532/// let len = self.slice.len();
533/// let rem = len % modulus;
534/// let start = len - rem;
1b1a35ee 535/// Self {slice: &self.slice[start..]}
041b39d2
XL
536/// }
537/// }
538///
539/// // If we were to divide &[0, 1, 2, 3, 4, 5, 6, 7] into slices of size 3,
3b2f2976 540/// // the remainder would be &[6, 7].
041b39d2
XL
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")]
60c5eb7d 546#[rustc_on_unimplemented(
9ffffee4 547 message = "cannot calculate the remainder of `{Self}` divided by `{Rhs}`",
60c5eb7d
XL
548 label = "no implementation for `{Self} % {Rhs}`"
549)]
83c7162d 550#[doc(alias = "%")]
60c5eb7d 551pub trait Rem<Rhs = Self> {
3b2f2976 552 /// The resulting type after applying the `%` operator.
041b39d2 553 #[stable(feature = "rust1", since = "1.0.0")]
dc9dc135 554 type Output;
041b39d2 555
3b2f2976 556 /// Performs the `%` operation.
1b1a35ee
XL
557 ///
558 /// # Example
559 ///
560 /// ```
561 /// assert_eq!(12 % 10, 2);
562 /// ```
9ffffee4
FG
563 #[must_use = "this returns the result of the operation, without modifying the original"]
564 #[rustc_diagnostic_item = "rem"]
041b39d2 565 #[stable(feature = "rust1", since = "1.0.0")]
532ac7d7 566 fn rem(self, rhs: Rhs) -> Self::Output;
041b39d2
XL
567}
568
569macro_rules! rem_impl_integer {
cdc7bbd5 570 ($(($($t:ty)*) => $panic:expr),*) => ($($(
9fa01778 571 /// This operation satisfies `n % d == n - (n / d) * d`. The
041b39d2 572 /// result has the same sign as the left operand.
cdc7bbd5
XL
573 ///
574 /// # Panics
575 ///
576 #[doc = $panic]
041b39d2 577 #[stable(feature = "rust1", since = "1.0.0")]
49aad941 578 impl Rem for $t {
041b39d2
XL
579 type Output = $t;
580
581 #[inline]
4b012472 582 #[track_caller]
041b39d2
XL
583 fn rem(self, other: $t) -> $t { self % other }
584 }
585
49aad941 586 forward_ref_binop! { impl Rem, rem for $t, $t }
cdc7bbd5 587 )*)*)
041b39d2
XL
588}
589
cdc7bbd5
XL
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}
041b39d2 594
041b39d2
XL
595macro_rules! rem_impl_float {
596 ($($t:ty)*) => ($(
532ac7d7
XL
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 /// ```
041b39d2 612 #[stable(feature = "rust1", since = "1.0.0")]
49aad941 613 impl Rem for $t {
041b39d2
XL
614 type Output = $t;
615
616 #[inline]
617 fn rem(self, other: $t) -> $t { self % other }
618 }
619
49aad941 620 forward_ref_binop! { impl Rem, rem for $t, $t }
041b39d2
XL
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 {
1b1a35ee 644/// type Output = Self;
041b39d2 645///
532ac7d7 646/// fn neg(self) -> Self::Output {
041b39d2
XL
647/// match self {
648/// Sign::Negative => Sign::Positive,
649/// Sign::Zero => Sign::Zero,
650/// Sign::Positive => Sign::Negative,
651/// }
652/// }
653/// }
654///
3b2f2976 655/// // A negative positive is a negative.
041b39d2 656/// assert_eq!(-Sign::Positive, Sign::Negative);
3b2f2976 657/// // A double negative is a positive.
041b39d2 658/// assert_eq!(-Sign::Negative, Sign::Positive);
3b2f2976 659/// // Zero is its own negation.
041b39d2
XL
660/// assert_eq!(-Sign::Zero, Sign::Zero);
661/// ```
662#[lang = "neg"]
663#[stable(feature = "rust1", since = "1.0.0")]
83c7162d 664#[doc(alias = "-")]
041b39d2 665pub trait Neg {
3b2f2976 666 /// The resulting type after applying the `-` operator.
041b39d2
XL
667 #[stable(feature = "rust1", since = "1.0.0")]
668 type Output;
669
3b2f2976 670 /// Performs the unary `-` operation.
1b1a35ee
XL
671 ///
672 /// # Example
673 ///
674 /// ```
675 /// let x: i32 = 12;
676 /// assert_eq!(-x, -12);
677 /// ```
9ffffee4
FG
678 #[must_use = "this returns the result of the operation, without modifying the original"]
679 #[rustc_diagnostic_item = "neg"]
041b39d2
XL
680 #[stable(feature = "rust1", since = "1.0.0")]
681 fn neg(self) -> Self::Output;
682}
683
ba9703b0
XL
684macro_rules! neg_impl {
685 ($($t:ty)*) => ($(
041b39d2 686 #[stable(feature = "rust1", since = "1.0.0")]
49aad941 687 impl Neg for $t {
041b39d2
XL
688 type Output = $t;
689
690 #[inline]
691 #[rustc_inherit_overflow_checks]
ba9703b0 692 fn neg(self) -> $t { -self }
041b39d2
XL
693 }
694
49aad941 695 forward_ref_unop! { impl Neg, neg for $t }
041b39d2
XL
696 )*)
697}
698
ba9703b0 699neg_impl! { isize i8 i16 i32 i64 i128 f32 f64 }
041b39d2
XL
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///
ba9703b0 711/// #[derive(Debug, Copy, Clone, PartialEq)]
041b39d2
XL
712/// struct Point {
713/// x: i32,
714/// y: i32,
715/// }
716///
717/// impl AddAssign for Point {
532ac7d7
XL
718/// fn add_assign(&mut self, other: Self) {
719/// *self = Self {
041b39d2
XL
720/// x: self.x + other.x,
721/// y: self.y + other.y,
722/// };
723/// }
724/// }
725///
041b39d2
XL
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")]
60c5eb7d
XL
732#[rustc_on_unimplemented(
733 message = "cannot add-assign `{Rhs}` to `{Self}`",
734 label = "no implementation for `{Self} += {Rhs}`"
735)]
83c7162d
XL
736#[doc(alias = "+")]
737#[doc(alias = "+=")]
60c5eb7d 738pub trait AddAssign<Rhs = Self> {
3b2f2976 739 /// Performs the `+=` operation.
1b1a35ee
XL
740 ///
741 /// # Example
742 ///
743 /// ```
744 /// let mut x: u32 = 12;
745 /// x += 1;
746 /// assert_eq!(x, 13);
747 /// ```
041b39d2
XL
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")]
49aad941 755 impl AddAssign for $t {
041b39d2 756 #[inline]
4b012472 757 #[track_caller]
041b39d2
XL
758 #[rustc_inherit_overflow_checks]
759 fn add_assign(&mut self, other: $t) { *self += other }
760 }
ea8adc8c 761
49aad941 762 forward_ref_op_assign! { impl AddAssign, add_assign for $t, $t }
041b39d2
XL
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///
ba9703b0 778/// #[derive(Debug, Copy, Clone, PartialEq)]
041b39d2
XL
779/// struct Point {
780/// x: i32,
781/// y: i32,
782/// }
783///
784/// impl SubAssign for Point {
532ac7d7
XL
785/// fn sub_assign(&mut self, other: Self) {
786/// *self = Self {
041b39d2
XL
787/// x: self.x - other.x,
788/// y: self.y - other.y,
789/// };
790/// }
791/// }
792///
041b39d2
XL
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")]
60c5eb7d
XL
799#[rustc_on_unimplemented(
800 message = "cannot subtract-assign `{Rhs}` from `{Self}`",
801 label = "no implementation for `{Self} -= {Rhs}`"
802)]
83c7162d
XL
803#[doc(alias = "-")]
804#[doc(alias = "-=")]
60c5eb7d 805pub trait SubAssign<Rhs = Self> {
3b2f2976 806 /// Performs the `-=` operation.
1b1a35ee
XL
807 ///
808 /// # Example
809 ///
810 /// ```
811 /// let mut x: u32 = 12;
812 /// x -= 1;
813 /// assert_eq!(x, 11);
814 /// ```
041b39d2
XL
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")]
49aad941 822 impl SubAssign for $t {
041b39d2 823 #[inline]
4b012472 824 #[track_caller]
041b39d2
XL
825 #[rustc_inherit_overflow_checks]
826 fn sub_assign(&mut self, other: $t) { *self -= other }
827 }
ea8adc8c 828
49aad941 829 forward_ref_op_assign! { impl SubAssign, sub_assign for $t, $t }
041b39d2
XL
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///
041b39d2
XL
839/// ```
840/// use std::ops::MulAssign;
841///
3b2f2976
XL
842/// #[derive(Debug, PartialEq)]
843/// struct Frequency { hertz: f64 }
041b39d2 844///
3b2f2976
XL
845/// impl MulAssign<f64> for Frequency {
846/// fn mul_assign(&mut self, rhs: f64) {
847/// self.hertz *= rhs;
041b39d2
XL
848/// }
849/// }
850///
3b2f2976
XL
851/// let mut frequency = Frequency { hertz: 50.0 };
852/// frequency *= 4.0;
853/// assert_eq!(Frequency { hertz: 200.0 }, frequency);
041b39d2
XL
854/// ```
855#[lang = "mul_assign"]
856#[stable(feature = "op_assign_traits", since = "1.8.0")]
60c5eb7d 857#[rustc_on_unimplemented(
29967ef6 858 message = "cannot multiply-assign `{Self}` by `{Rhs}`",
60c5eb7d
XL
859 label = "no implementation for `{Self} *= {Rhs}`"
860)]
83c7162d
XL
861#[doc(alias = "*")]
862#[doc(alias = "*=")]
60c5eb7d 863pub trait MulAssign<Rhs = Self> {
3b2f2976 864 /// Performs the `*=` operation.
1b1a35ee
XL
865 ///
866 /// # Example
867 ///
868 /// ```
869 /// let mut x: u32 = 12;
870 /// x *= 2;
871 /// assert_eq!(x, 24);
872 /// ```
041b39d2
XL
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")]
49aad941 880 impl MulAssign for $t {
041b39d2 881 #[inline]
4b012472 882 #[track_caller]
041b39d2
XL
883 #[rustc_inherit_overflow_checks]
884 fn mul_assign(&mut self, other: $t) { *self *= other }
885 }
ea8adc8c 886
49aad941 887 forward_ref_op_assign! { impl MulAssign, mul_assign for $t, $t }
041b39d2
XL
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///
041b39d2
XL
897/// ```
898/// use std::ops::DivAssign;
899///
3b2f2976
XL
900/// #[derive(Debug, PartialEq)]
901/// struct Frequency { hertz: f64 }
041b39d2 902///
3b2f2976
XL
903/// impl DivAssign<f64> for Frequency {
904/// fn div_assign(&mut self, rhs: f64) {
905/// self.hertz /= rhs;
041b39d2
XL
906/// }
907/// }
908///
3b2f2976
XL
909/// let mut frequency = Frequency { hertz: 200.0 };
910/// frequency /= 4.0;
911/// assert_eq!(Frequency { hertz: 50.0 }, frequency);
041b39d2
XL
912/// ```
913#[lang = "div_assign"]
914#[stable(feature = "op_assign_traits", since = "1.8.0")]
60c5eb7d
XL
915#[rustc_on_unimplemented(
916 message = "cannot divide-assign `{Self}` by `{Rhs}`",
917 label = "no implementation for `{Self} /= {Rhs}`"
918)]
83c7162d
XL
919#[doc(alias = "/")]
920#[doc(alias = "/=")]
60c5eb7d 921pub trait DivAssign<Rhs = Self> {
3b2f2976 922 /// Performs the `/=` operation.
1b1a35ee
XL
923 ///
924 /// # Example
925 ///
926 /// ```
927 /// let mut x: u32 = 12;
928 /// x /= 2;
929 /// assert_eq!(x, 6);
930 /// ```
041b39d2
XL
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")]
49aad941 938 impl DivAssign for $t {
041b39d2 939 #[inline]
4b012472 940 #[track_caller]
041b39d2
XL
941 fn div_assign(&mut self, other: $t) { *self /= other }
942 }
ea8adc8c 943
49aad941 944 forward_ref_op_assign! { impl DivAssign, div_assign for $t, $t }
041b39d2
XL
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///
041b39d2
XL
954/// ```
955/// use std::ops::RemAssign;
956///
3b2f2976 957/// struct CookieJar { cookies: u32 }
041b39d2 958///
3b2f2976
XL
959/// impl RemAssign<u32> for CookieJar {
960/// fn rem_assign(&mut self, piles: u32) {
961/// self.cookies %= piles;
041b39d2
XL
962/// }
963/// }
964///
3b2f2976
XL
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);
041b39d2
XL
973/// ```
974#[lang = "rem_assign"]
975#[stable(feature = "op_assign_traits", since = "1.8.0")]
60c5eb7d 976#[rustc_on_unimplemented(
9ffffee4 977 message = "cannot calculate and assign the remainder of `{Self}` divided by `{Rhs}`",
60c5eb7d
XL
978 label = "no implementation for `{Self} %= {Rhs}`"
979)]
83c7162d
XL
980#[doc(alias = "%")]
981#[doc(alias = "%=")]
60c5eb7d 982pub trait RemAssign<Rhs = Self> {
3b2f2976 983 /// Performs the `%=` operation.
1b1a35ee
XL
984 ///
985 /// # Example
986 ///
987 /// ```
988 /// let mut x: u32 = 12;
989 /// x %= 10;
990 /// assert_eq!(x, 2);
991 /// ```
041b39d2
XL
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")]
49aad941 999 impl RemAssign for $t {
041b39d2 1000 #[inline]
4b012472 1001 #[track_caller]
041b39d2
XL
1002 fn rem_assign(&mut self, other: $t) { *self %= other }
1003 }
ea8adc8c 1004
49aad941 1005 forward_ref_op_assign! { impl RemAssign, rem_assign for $t, $t }
041b39d2
XL
1006 )+)
1007}
1008
1009rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }