]>
Commit | Line | Data |
---|---|---|
041b39d2 XL |
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 | /// | |
3b2f2976 XL |
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 | /// | |
041b39d2 XL |
19 | /// # Examples |
20 | /// | |
3b2f2976 | 21 | /// ## `Add`able points |
041b39d2 XL |
22 | /// |
23 | /// ``` | |
24 | /// use std::ops::Add; | |
25 | /// | |
3b2f2976 | 26 | /// #[derive(Debug, PartialEq)] |
041b39d2 XL |
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 | /// | |
3b2f2976 XL |
43 | /// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 }, |
44 | /// Point { x: 3, y: 3 }); | |
041b39d2 XL |
45 | /// ``` |
46 | /// | |
3b2f2976 XL |
47 | /// ## Implementing `Add` with generics |
48 | /// | |
041b39d2 XL |
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 | /// | |
3b2f2976 | 55 | /// #[derive(Debug, PartialEq)] |
041b39d2 XL |
56 | /// struct Point<T> { |
57 | /// x: T, | |
58 | /// y: T, | |
59 | /// } | |
60 | /// | |
3b2f2976 | 61 | /// // Notice that the implementation uses the associated type `Output`. |
041b39d2 XL |
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 | /// | |
3b2f2976 XL |
73 | /// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 }, |
74 | /// Point { x: 3, y: 3 }); | |
041b39d2 | 75 | /// ``` |
041b39d2 XL |
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> { | |
3b2f2976 | 80 | /// The resulting type after applying the `+` operator. |
041b39d2 XL |
81 | #[stable(feature = "rust1", since = "1.0.0")] |
82 | type Output; | |
83 | ||
3b2f2976 | 84 | /// Performs the `+` operation. |
041b39d2 XL |
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 | /// | |
3b2f2976 XL |
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 | /// | |
041b39d2 XL |
114 | /// # Examples |
115 | /// | |
3b2f2976 | 116 | /// ## `Sub`tractable points |
041b39d2 XL |
117 | /// |
118 | /// ``` | |
119 | /// use std::ops::Sub; | |
120 | /// | |
3b2f2976 | 121 | /// #[derive(Debug, PartialEq)] |
041b39d2 XL |
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 | /// | |
3b2f2976 XL |
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. | |
041b39d2 | 146 | /// |
041b39d2 | 147 | /// ``` |
3b2f2976 | 148 | /// use std::ops::Sub; |
041b39d2 | 149 | /// |
3b2f2976 XL |
150 | /// #[derive(Debug, PartialEq)] |
151 | /// struct Point<T> { | |
152 | /// x: T, | |
153 | /// y: T, | |
154 | /// } | |
041b39d2 | 155 | /// |
3b2f2976 XL |
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 | /// ``` | |
041b39d2 XL |
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> { | |
3b2f2976 | 175 | /// The resulting type after applying the `-` operator. |
041b39d2 XL |
176 | #[stable(feature = "rust1", since = "1.0.0")] |
177 | type Output; | |
178 | ||
3b2f2976 | 179 | /// Performs the `-` operation. |
041b39d2 XL |
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 | /// | |
3b2f2976 XL |
203 | /// Note that `RHS` is `Self` by default, but this is not mandatory. |
204 | /// | |
041b39d2 XL |
205 | /// # Examples |
206 | /// | |
3b2f2976 | 207 | /// ## `Mul`tipliable rational numbers |
041b39d2 XL |
208 | /// |
209 | /// ``` | |
210 | /// use std::ops::Mul; | |
211 | /// | |
3b2f2976 XL |
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)] | |
041b39d2 XL |
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 | /// | |
3b2f2976 | 266 | /// ## Multiplying vectors by scalars as in linear algebra |
041b39d2 XL |
267 | /// |
268 | /// ``` | |
269 | /// use std::ops::Mul; | |
270 | /// | |
3b2f2976 | 271 | /// struct Scalar { value: usize } |
041b39d2 | 272 | /// |
3b2f2976 XL |
273 | /// #[derive(Debug, PartialEq)] |
274 | /// struct Vector { value: Vec<usize> } | |
041b39d2 | 275 | /// |
3b2f2976 | 276 | /// impl Mul<Scalar> for Vector { |
041b39d2 XL |
277 | /// type Output = Vector; |
278 | /// | |
3b2f2976 XL |
279 | /// fn mul(self, rhs: Scalar) -> Vector { |
280 | /// Vector { value: self.value.iter().map(|v| v * rhs.value).collect() } | |
041b39d2 XL |
281 | /// } |
282 | /// } | |
283 | /// | |
3b2f2976 XL |
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] }); | |
041b39d2 XL |
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> { | |
3b2f2976 | 292 | /// The resulting type after applying the `*` operator. |
041b39d2 XL |
293 | #[stable(feature = "rust1", since = "1.0.0")] |
294 | type Output; | |
295 | ||
3b2f2976 | 296 | /// Performs the `*` operation. |
041b39d2 XL |
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 | /// | |
3b2f2976 XL |
320 | /// Note that `RHS` is `Self` by default, but this is not mandatory. |
321 | /// | |
041b39d2 XL |
322 | /// # Examples |
323 | /// | |
3b2f2976 | 324 | /// ## `Div`idable rational numbers |
041b39d2 XL |
325 | /// |
326 | /// ``` | |
327 | /// use std::ops::Div; | |
328 | /// | |
3b2f2976 XL |
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)] | |
041b39d2 XL |
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 | /// | |
3b2f2976 XL |
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)); | |
041b39d2 XL |
385 | /// ``` |
386 | /// | |
3b2f2976 | 387 | /// ## Dividing vectors by scalars as in linear algebra |
041b39d2 XL |
388 | /// |
389 | /// ``` | |
390 | /// use std::ops::Div; | |
391 | /// | |
3b2f2976 | 392 | /// struct Scalar { value: f32 } |
041b39d2 | 393 | /// |
3b2f2976 XL |
394 | /// #[derive(Debug, PartialEq)] |
395 | /// struct Vector { value: Vec<f32> } | |
041b39d2 XL |
396 | /// |
397 | /// impl Div<Scalar> for Vector { | |
398 | /// type Output = Vector; | |
399 | /// | |
400 | /// fn div(self, rhs: Scalar) -> Vector { | |
3b2f2976 | 401 | /// Vector { value: self.value.iter().map(|v| v / rhs.value).collect() } |
041b39d2 XL |
402 | /// } |
403 | /// } | |
404 | /// | |
3b2f2976 XL |
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] }); | |
041b39d2 XL |
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> { | |
3b2f2976 | 413 | /// The resulting type after applying the `/` operator. |
041b39d2 XL |
414 | #[stable(feature = "rust1", since = "1.0.0")] |
415 | type Output; | |
416 | ||
3b2f2976 | 417 | /// Performs the `/` operation. |
041b39d2 XL |
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 | /// | |
3b2f2976 XL |
458 | /// Note that `RHS` is `Self` by default, but this is not mandatory. |
459 | /// | |
041b39d2 XL |
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, | |
3b2f2976 | 487 | /// // the remainder would be &[6, 7]. |
041b39d2 XL |
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> { | |
3b2f2976 | 495 | /// The resulting type after applying the `%` operator. |
041b39d2 XL |
496 | #[stable(feature = "rust1", since = "1.0.0")] |
497 | type Output = Self; | |
498 | ||
3b2f2976 | 499 | /// Performs the `%` operation. |
041b39d2 XL |
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 | /// | |
3b2f2976 | 568 | /// // A negative positive is a negative. |
041b39d2 | 569 | /// assert_eq!(-Sign::Positive, Sign::Negative); |
3b2f2976 | 570 | /// // A double negative is a positive. |
041b39d2 | 571 | /// assert_eq!(-Sign::Negative, Sign::Positive); |
3b2f2976 | 572 | /// // Zero is its own negation. |
041b39d2 XL |
573 | /// assert_eq!(-Sign::Zero, Sign::Zero); |
574 | /// ``` | |
575 | #[lang = "neg"] | |
576 | #[stable(feature = "rust1", since = "1.0.0")] | |
577 | pub trait Neg { | |
3b2f2976 | 578 | /// The resulting type after applying the `-` operator. |
041b39d2 XL |
579 | #[stable(feature = "rust1", since = "1.0.0")] |
580 | type Output; | |
581 | ||
3b2f2976 | 582 | /// Performs the unary `-` operation. |
041b39d2 XL |
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 | /// | |
3b2f2976 | 629 | /// #[derive(Debug, PartialEq)] |
041b39d2 XL |
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 | /// | |
041b39d2 XL |
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> { | |
3b2f2976 | 652 | /// Performs the `+=` operation. |
041b39d2 XL |
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 | } | |
ea8adc8c XL |
665 | |
666 | forward_ref_op_assign! { impl AddAssign, add_assign for $t, $t } | |
041b39d2 XL |
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 | /// | |
3b2f2976 | 682 | /// #[derive(Debug, PartialEq)] |
041b39d2 XL |
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 | /// | |
041b39d2 XL |
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> { | |
3b2f2976 | 705 | /// Performs the `-=` operation. |
041b39d2 XL |
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 | } | |
ea8adc8c XL |
718 | |
719 | forward_ref_op_assign! { impl SubAssign, sub_assign for $t, $t } | |
041b39d2 XL |
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 | /// | |
041b39d2 XL |
729 | /// ``` |
730 | /// use std::ops::MulAssign; | |
731 | /// | |
3b2f2976 XL |
732 | /// #[derive(Debug, PartialEq)] |
733 | /// struct Frequency { hertz: f64 } | |
041b39d2 | 734 | /// |
3b2f2976 XL |
735 | /// impl MulAssign<f64> for Frequency { |
736 | /// fn mul_assign(&mut self, rhs: f64) { | |
737 | /// self.hertz *= rhs; | |
041b39d2 XL |
738 | /// } |
739 | /// } | |
740 | /// | |
3b2f2976 XL |
741 | /// let mut frequency = Frequency { hertz: 50.0 }; |
742 | /// frequency *= 4.0; | |
743 | /// assert_eq!(Frequency { hertz: 200.0 }, frequency); | |
041b39d2 XL |
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> { | |
3b2f2976 | 749 | /// Performs the `*=` operation. |
041b39d2 XL |
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 | } | |
ea8adc8c XL |
762 | |
763 | forward_ref_op_assign! { impl MulAssign, mul_assign for $t, $t } | |
041b39d2 XL |
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 | /// | |
041b39d2 XL |
773 | /// ``` |
774 | /// use std::ops::DivAssign; | |
775 | /// | |
3b2f2976 XL |
776 | /// #[derive(Debug, PartialEq)] |
777 | /// struct Frequency { hertz: f64 } | |
041b39d2 | 778 | /// |
3b2f2976 XL |
779 | /// impl DivAssign<f64> for Frequency { |
780 | /// fn div_assign(&mut self, rhs: f64) { | |
781 | /// self.hertz /= rhs; | |
041b39d2 XL |
782 | /// } |
783 | /// } | |
784 | /// | |
3b2f2976 XL |
785 | /// let mut frequency = Frequency { hertz: 200.0 }; |
786 | /// frequency /= 4.0; | |
787 | /// assert_eq!(Frequency { hertz: 50.0 }, frequency); | |
041b39d2 XL |
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> { | |
3b2f2976 | 793 | /// Performs the `/=` operation. |
041b39d2 XL |
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 | } | |
ea8adc8c XL |
805 | |
806 | forward_ref_op_assign! { impl DivAssign, div_assign for $t, $t } | |
041b39d2 XL |
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 | /// | |
041b39d2 XL |
816 | /// ``` |
817 | /// use std::ops::RemAssign; | |
818 | /// | |
3b2f2976 | 819 | /// struct CookieJar { cookies: u32 } |
041b39d2 | 820 | /// |
3b2f2976 XL |
821 | /// impl RemAssign<u32> for CookieJar { |
822 | /// fn rem_assign(&mut self, piles: u32) { | |
823 | /// self.cookies %= piles; | |
041b39d2 XL |
824 | /// } |
825 | /// } | |
826 | /// | |
3b2f2976 XL |
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); | |
041b39d2 XL |
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> { | |
3b2f2976 | 840 | /// Performs the `%=` operation. |
041b39d2 XL |
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 | } | |
ea8adc8c XL |
852 | |
853 | forward_ref_op_assign! { impl RemAssign, rem_assign for $t, $t } | |
041b39d2 XL |
854 | )+) |
855 | } | |
856 | ||
857 | rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } |