]> git.lizzy.rs Git - rust.git/blob - src/libcore/ops.rs
af1df973a3e655c2fc61da948e7a48ccc3b5410c
[rust.git] / src / libcore / ops.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 /*!
12  *
13  * Overloadable operators
14  *
15  * Implementing these traits allows you to get an effect similar to
16  * overloading operators.
17  *
18  * The values for the right hand side of an operator are automatically
19  * borrowed, so `a + b` is sugar for `a.add(&b)`.
20  *
21  * All of these traits are imported by the prelude, so they are available in
22  * every Rust program.
23  *
24  * # Example
25  *
26  * This example creates a `Point` struct that implements `Add` and `Sub`, and then
27  * demonstrates adding and subtracting two `Point`s.
28  *
29  * ```rust
30  * #[deriving(Show)]
31  * struct Point {
32  *     x: int,
33  *     y: int
34  * }
35  *
36  * impl Add<Point, Point> for Point {
37  *     fn add(&self, other: &Point) -> Point {
38  *         Point {x: self.x + other.x, y: self.y + other.y}
39  *     }
40  * }
41  *
42  * impl Sub<Point, Point> for Point {
43  *     fn sub(&self, other: &Point) -> Point {
44  *         Point {x: self.x - other.x, y: self.y - other.y}
45  *     }
46  * }
47  * fn main() {
48  *     println!("{}", Point {x: 1, y: 0} + Point {x: 2, y: 3});
49  *     println!("{}", Point {x: 1, y: 0} - Point {x: 2, y: 3});
50  * }
51  * ```
52  *
53  * See the documentation for each trait for a minimum implementation that prints
54  * something to the screen.
55  *
56  */
57
58 /**
59  *
60  * The `Drop` trait is used to run some code when a value goes out of scope. This
61  * is sometimes called a 'destructor'.
62  *
63  * # Example
64  *
65  * A trivial implementation of `Drop`. The `drop` method is called when `_x` goes
66  * out of scope, and therefore `main` prints `Dropping!`.
67  *
68  * ```rust
69  * struct HasDrop;
70  *
71  * impl Drop for HasDrop {
72  *   fn drop(&mut self) {
73  *       println!("Dropping!");
74  *   }
75  * }
76  *
77  * fn main() {
78  *   let _x = HasDrop;
79  * }
80  * ```
81  */
82 #[lang="drop"]
83 pub trait Drop {
84     /// The `drop` method, called when the value goes out of scope.
85     fn drop(&mut self);
86 }
87
88 /**
89  *
90  * The `Add` trait is used to specify the functionality of `+`.
91  *
92  * # Example
93  *
94  * A trivial implementation of `Add`. When `Foo + Foo` happens, it ends up
95  * calling `add`, and therefore, `main` prints `Adding!`.
96  *
97  * ```rust
98  * struct Foo;
99  *
100  * impl Add<Foo, Foo> for Foo {
101  *     fn add(&self, _rhs: &Foo) -> Foo {
102  *       println!("Adding!");
103  *       *self
104  *   }
105  * }
106  *
107  * fn main() {
108  *   Foo + Foo;
109  * }
110  * ```
111  */
112 #[lang="add"]
113 pub trait Add<RHS,Result> {
114     /// The method for the `+` operator
115     fn add(&self, rhs: &RHS) -> Result;
116 }
117
118 macro_rules! add_impl(
119     ($($t:ty)*) => ($(
120         #[cfg(not(test))]
121         impl Add<$t, $t> for $t {
122             #[inline]
123             fn add(&self, other: &$t) -> $t { (*self) + (*other) }
124         }
125     )*)
126 )
127
128 add_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
129
130 /**
131  *
132  * The `Sub` trait is used to specify the functionality of `-`.
133  *
134  * # Example
135  *
136  * A trivial implementation of `Sub`. When `Foo - Foo` happens, it ends up
137  * calling `sub`, and therefore, `main` prints `Subtracting!`.
138  *
139  * ```rust
140  * struct Foo;
141  *
142  * impl Sub<Foo, Foo> for Foo {
143  *     fn sub(&self, _rhs: &Foo) -> Foo {
144  *         println!("Subtracting!");
145  *         *self
146  *     }
147  * }
148  *
149  * fn main() {
150  *     Foo - Foo;
151  * }
152  * ```
153  */
154 #[lang="sub"]
155 pub trait Sub<RHS,Result> {
156     /// The method for the `-` operator
157     fn sub(&self, rhs: &RHS) -> Result;
158 }
159
160 macro_rules! sub_impl(
161     ($($t:ty)*) => ($(
162         #[cfg(not(test))]
163         impl Sub<$t, $t> for $t {
164             #[inline]
165             fn sub(&self, other: &$t) -> $t { (*self) - (*other) }
166         }
167     )*)
168 )
169
170 sub_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
171
172 /**
173  *
174  * The `Mul` trait is used to specify the functionality of `*`.
175  *
176  * # Example
177  *
178  * A trivial implementation of `Mul`. When `Foo * Foo` happens, it ends up
179  * calling `mul`, and therefore, `main` prints `Multiplying!`.
180  *
181  * ```rust
182  * struct Foo;
183  *
184  * impl Mul<Foo, Foo> for Foo {
185  *     fn mul(&self, _rhs: &Foo) -> Foo {
186  *         println!("Multiplying!");
187  *         *self
188  *     }
189  * }
190  *
191  * fn main() {
192  *     Foo * Foo;
193  * }
194  * ```
195  */
196 #[lang="mul"]
197 pub trait Mul<RHS,Result> {
198     /// The method for the `*` operator
199     fn mul(&self, rhs: &RHS) -> Result;
200 }
201
202 macro_rules! mul_impl(
203     ($($t:ty)*) => ($(
204         #[cfg(not(test))]
205         impl Mul<$t, $t> for $t {
206             #[inline]
207             fn mul(&self, other: &$t) -> $t { (*self) * (*other) }
208         }
209     )*)
210 )
211
212 mul_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
213
214 /**
215  *
216  * The `Div` trait is used to specify the functionality of `/`.
217  *
218  * # Example
219  *
220  * A trivial implementation of `Div`. When `Foo / Foo` happens, it ends up
221  * calling `div`, and therefore, `main` prints `Dividing!`.
222  *
223  * ```
224  * struct Foo;
225  *
226  * impl Div<Foo, Foo> for Foo {
227  *     fn div(&self, _rhs: &Foo) -> Foo {
228  *         println!("Dividing!");
229  *         *self
230  *     }
231  * }
232  *
233  * fn main() {
234  *     Foo / Foo;
235  * }
236  * ```
237  */
238 #[lang="div"]
239 pub trait Div<RHS,Result> {
240     /// The method for the `/` operator
241     fn div(&self, rhs: &RHS) -> Result;
242 }
243
244 macro_rules! div_impl(
245     ($($t:ty)*) => ($(
246         #[cfg(not(test))]
247         impl Div<$t, $t> for $t {
248             #[inline]
249             fn div(&self, other: &$t) -> $t { (*self) / (*other) }
250         }
251     )*)
252 )
253
254 div_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
255
256 /**
257  *
258  * The `Rem` trait is used to specify the functionality of `%`.
259  *
260  * # Example
261  *
262  * A trivial implementation of `Rem`. When `Foo % Foo` happens, it ends up
263  * calling `rem`, and therefore, `main` prints `Remainder-ing!`.
264  *
265  * ```
266  * struct Foo;
267  *
268  * impl Rem<Foo, Foo> for Foo {
269  *     fn rem(&self, _rhs: &Foo) -> Foo {
270  *         println!("Remainder-ing!");
271  *         *self
272  *     }
273  * }
274  *
275  * fn main() {
276  *     Foo % Foo;
277  * }
278  * ```
279  */
280 #[lang="rem"]
281 pub trait Rem<RHS,Result> {
282     /// The method for the `%` operator
283     fn rem(&self, rhs: &RHS) -> Result;
284 }
285
286 macro_rules! rem_impl(
287     ($($t:ty)*) => ($(
288         #[cfg(not(test))]
289         impl Rem<$t, $t> for $t {
290             #[inline]
291             fn rem(&self, other: &$t) -> $t { (*self) % (*other) }
292         }
293     )*)
294 )
295
296 macro_rules! rem_float_impl(
297     ($t:ty, $fmod:ident) => {
298         #[cfg(not(test))]
299         impl Rem<$t, $t> for $t {
300             #[inline]
301             fn rem(&self, other: &$t) -> $t {
302                 extern { fn $fmod(a: $t, b: $t) -> $t; }
303                 unsafe { $fmod(*self, *other) }
304             }
305         }
306     }
307 )
308
309 rem_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64)
310 rem_float_impl!(f32, fmodf)
311 rem_float_impl!(f64, fmod)
312
313 /**
314  *
315  * The `Neg` trait is used to specify the functionality of unary `-`.
316  *
317  * # Example
318  *
319  * A trivial implementation of `Neg`. When `-Foo` happens, it ends up calling
320  * `neg`, and therefore, `main` prints `Negating!`.
321  *
322  * ```
323  * struct Foo;
324  *
325  * impl Neg<Foo> for Foo {
326  *     fn neg(&self) -> Foo {
327  *         println!("Negating!");
328  *         *self
329  *     }
330  * }
331  *
332  * fn main() {
333  *     -Foo;
334  * }
335  * ```
336  */
337 #[lang="neg"]
338 pub trait Neg<Result> {
339     /// The method for the unary `-` operator
340     fn neg(&self) -> Result;
341 }
342
343 macro_rules! neg_impl(
344     ($($t:ty)*) => ($(
345         #[cfg(not(test))]
346         impl Neg<$t> for $t {
347             #[inline]
348             fn neg(&self) -> $t { -*self }
349         }
350     )*)
351 )
352
353 macro_rules! neg_uint_impl(
354     ($t:ty, $t_signed:ty) => {
355         #[cfg(not(test))]
356         impl Neg<$t> for $t {
357             #[inline]
358             fn neg(&self) -> $t { -(*self as $t_signed) as $t }
359         }
360     }
361 )
362
363 neg_impl!(int i8 i16 i32 i64 f32 f64)
364
365 neg_uint_impl!(uint, int)
366 neg_uint_impl!(u8, i8)
367 neg_uint_impl!(u16, i16)
368 neg_uint_impl!(u32, i32)
369 neg_uint_impl!(u64, i64)
370
371
372 /**
373  *
374  * The `Not` trait is used to specify the functionality of unary `!`.
375  *
376  * # Example
377  *
378  * A trivial implementation of `Not`. When `!Foo` happens, it ends up calling
379  * `not`, and therefore, `main` prints `Not-ing!`.
380  *
381  * ```
382  * struct Foo;
383  *
384  * impl Not<Foo> for Foo {
385  *     fn not(&self) -> Foo {
386  *         println!("Not-ing!");
387  *         *self
388  *     }
389  * }
390  *
391  * fn main() {
392  *     !Foo;
393  * }
394  * ```
395  */
396 #[lang="not"]
397 pub trait Not<Result> {
398     /// The method for the unary `!` operator
399     fn not(&self) -> Result;
400 }
401
402
403 macro_rules! not_impl(
404     ($($t:ty)*) => ($(
405         #[cfg(not(test))]
406         impl Not<$t> for $t {
407             #[inline]
408             fn not(&self) -> $t { !*self }
409         }
410     )*)
411 )
412
413 not_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64)
414
415 /**
416  *
417  * The `BitAnd` trait is used to specify the functionality of `&`.
418  *
419  * # Example
420  *
421  * A trivial implementation of `BitAnd`. When `Foo & Foo` happens, it ends up
422  * calling `bitand`, and therefore, `main` prints `Bitwise And-ing!`.
423  *
424  * ```
425  * struct Foo;
426  *
427  * impl BitAnd<Foo, Foo> for Foo {
428  *     fn bitand(&self, _rhs: &Foo) -> Foo {
429  *         println!("Bitwise And-ing!");
430  *         *self
431  *     }
432  * }
433  *
434  * fn main() {
435  *     Foo & Foo;
436  * }
437  * ```
438  */
439 #[lang="bitand"]
440 pub trait BitAnd<RHS,Result> {
441     /// The method for the `&` operator
442     fn bitand(&self, rhs: &RHS) -> Result;
443 }
444
445 macro_rules! bitand_impl(
446     ($($t:ty)*) => ($(
447         #[cfg(not(test))]
448         impl BitAnd<$t, $t> for $t {
449             #[inline]
450             fn bitand(&self, rhs: &$t) -> $t { (*self) & (*rhs) }
451         }
452     )*)
453 )
454
455 bitand_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64)
456
457 /**
458  *
459  * The `BitOr` trait is used to specify the functionality of `|`.
460  *
461  * # Example
462  *
463  * A trivial implementation of `BitOr`. When `Foo | Foo` happens, it ends up
464  * calling `bitor`, and therefore, `main` prints `Bitwise Or-ing!`.
465  *
466  * ```
467  * struct Foo;
468  *
469  * impl BitOr<Foo, Foo> for Foo {
470  *     fn bitor(&self, _rhs: &Foo) -> Foo {
471  *         println!("Bitwise Or-ing!");
472  *         *self
473  *     }
474  * }
475  *
476  * fn main() {
477  *     Foo | Foo;
478  * }
479  * ```
480  */
481 #[lang="bitor"]
482 pub trait BitOr<RHS,Result> {
483     /// The method for the `|` operator
484     fn bitor(&self, rhs: &RHS) -> Result;
485 }
486
487 macro_rules! bitor_impl(
488     ($($t:ty)*) => ($(
489         #[cfg(not(test))]
490         impl BitOr<$t,$t> for $t {
491             #[inline]
492             fn bitor(&self, rhs: &$t) -> $t { (*self) | (*rhs) }
493         }
494     )*)
495 )
496
497 bitor_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64)
498
499 /**
500  *
501  * The `BitXor` trait is used to specify the functionality of `^`.
502  *
503  * # Example
504  *
505  * A trivial implementation of `BitXor`. When `Foo ^ Foo` happens, it ends up
506  * calling `bitxor`, and therefore, `main` prints `Bitwise Xor-ing!`.
507  *
508  * ```
509  * struct Foo;
510  *
511  * impl BitXor<Foo, Foo> for Foo {
512  *     fn bitxor(&self, _rhs: &Foo) -> Foo {
513  *         println!("Bitwise Xor-ing!");
514  *         *self
515  *     }
516  * }
517  *
518  * fn main() {
519  *     Foo ^ Foo;
520  * }
521  * ```
522  */
523 #[lang="bitxor"]
524 pub trait BitXor<RHS,Result> {
525     /// The method for the `^` operator
526     fn bitxor(&self, rhs: &RHS) -> Result;
527 }
528
529 macro_rules! bitxor_impl(
530     ($($t:ty)*) => ($(
531         #[cfg(not(test))]
532         impl BitXor<$t, $t> for $t {
533             #[inline]
534             fn bitxor(&self, other: &$t) -> $t { (*self) ^ (*other) }
535         }
536     )*)
537 )
538
539 bitxor_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64)
540
541 /**
542  *
543  * The `Shl` trait is used to specify the functionality of `<<`.
544  *
545  * # Example
546  *
547  * A trivial implementation of `Shl`. When `Foo << Foo` happens, it ends up
548  * calling `shl`, and therefore, `main` prints `Shifting left!`.
549  *
550  * ```
551  * struct Foo;
552  *
553  * impl Shl<Foo, Foo> for Foo {
554  *     fn shl(&self, _rhs: &Foo) -> Foo {
555  *         println!("Shifting left!");
556  *         *self
557  *     }
558  * }
559  *
560  * fn main() {
561  *     Foo << Foo;
562  * }
563  * ```
564  */
565 #[lang="shl"]
566 pub trait Shl<RHS,Result> {
567     /// The method for the `<<` operator
568     fn shl(&self, rhs: &RHS) -> Result;
569 }
570
571 macro_rules! shl_impl(
572     ($($t:ty)*) => ($(
573         #[cfg(not(test))]
574         impl Shl<$t, $t> for $t {
575             #[inline]
576             fn shl(&self, other: &$t) -> $t { (*self) << (*other) }
577         }
578     )*)
579 )
580
581 shl_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64)
582
583 /**
584  *
585  * The `Shr` trait is used to specify the functionality of `>>`.
586  *
587  * # Example
588  *
589  * A trivial implementation of `Shr`. When `Foo >> Foo` happens, it ends up
590  * calling `shr`, and therefore, `main` prints `Shifting right!`.
591  *
592  * ```
593  * struct Foo;
594  *
595  * impl Shr<Foo, Foo> for Foo {
596  *     fn shr(&self, _rhs: &Foo) -> Foo {
597  *         println!("Shifting right!");
598  *         *self
599  *     }
600  * }
601  *
602  * fn main() {
603  *     Foo >> Foo;
604  * }
605  * ```
606  */
607 #[lang="shr"]
608 pub trait Shr<RHS,Result> {
609     /// The method for the `>>` operator
610     fn shr(&self, rhs: &RHS) -> Result;
611 }
612
613 macro_rules! shr_impl(
614     ($($t:ty)*) => ($(
615         #[cfg(not(test))]
616         impl Shr<$t, $t> for $t {
617             #[inline]
618             fn shr(&self, other: &$t) -> $t { (*self) >> (*other) }
619         }
620     )*)
621 )
622
623 shr_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64)
624
625 /**
626  *
627  * The `Index` trait is used to specify the functionality of indexing operations
628  * like `arr[idx]`.
629  *
630  * # Example
631  *
632  * A trivial implementation of `Index`. When `Foo[Foo]` happens, it ends up
633  * calling `index`, and therefore, `main` prints `Indexing!`.
634  *
635  * ```
636  * struct Foo;
637  *
638  * impl Index<Foo, Foo> for Foo {
639  *     fn index(&self, _rhs: &Foo) -> Foo {
640  *         println!("Indexing!");
641  *         *self
642  *     }
643  * }
644  *
645  * fn main() {
646  *     Foo[Foo];
647  * }
648  * ```
649  */
650 #[lang="index"]
651 pub trait Index<Index,Result> {
652     /// The method for the indexing (`Foo[Bar]`) operation
653     fn index(&self, index: &Index) -> Result;
654 }
655
656 /**
657  *
658  * The `Deref` trait is used to specify the functionality of dereferencing
659  * operations like `*v`.
660  *
661  * # Example
662  *
663  * A struct with a single field which is accessible via dereferencing the
664  * struct.
665  *
666  * ```
667  * struct DerefExample<T> {
668  *     value: T
669  * }
670  *
671  * impl<T> Deref<T> for DerefExample<T> {
672  *     fn deref<'a>(&'a self) -> &'a T {
673  *         &self.value
674  *     }
675  * }
676  *
677  * fn main() {
678  *     let x = DerefExample { value: 'a' };
679  *     assert_eq!('a', *x);
680  * }
681  * ```
682  */
683 #[lang="deref"]
684 pub trait Deref<Result> {
685     /// The method called to dereference a value
686     fn deref<'a>(&'a self) -> &'a Result;
687 }
688
689 /**
690  *
691  * The `DerefMut` trait is used to specify the functionality of dereferencing
692  * mutably like `*v = 1;`
693  *
694  * # Example
695  *
696  * A struct with a single field which is modifiable via dereferencing the
697  * struct.
698  *
699  * ```
700  * struct DerefMutExample<T> {
701  *     value: T
702  * }
703  *
704  * impl<T> Deref<T> for DerefMutExample<T> {
705  *     fn deref<'a>(&'a self) -> &'a T {
706  *         &self.value
707  *     }
708  * }
709  *
710  * impl<T> DerefMut<T> for DerefMutExample<T> {
711  *     fn deref_mut<'a>(&'a mut self) -> &'a mut T {
712  *         &mut self.value
713  *     }
714  * }
715  *
716  * fn main() {
717  *     let mut x = DerefMutExample { value: 'a' };
718  *     *x = 'b';
719  *     assert_eq!('b', *x);
720  * }
721  * ```
722  */
723 #[lang="deref_mut"]
724 pub trait DerefMut<Result>: Deref<Result> {
725     /// The method called to mutably dereference a value
726     fn deref_mut<'a>(&'a mut self) -> &'a mut Result;
727 }
728
729 /// A version of the call operator that takes an immutable receiver.
730 #[lang="fn"]
731 pub trait Fn<Args,Result> {
732     /// This is called when the call operator is used.
733     fn call(&self, args: Args) -> Result;
734 }
735
736 /// A version of the call operator that takes a mutable receiver.
737 #[lang="fn_mut"]
738 pub trait FnMut<Args,Result> {
739     /// This is called when the call operator is used.
740     fn call_mut(&mut self, args: Args) -> Result;
741 }
742
743 /// A version of the call operator that takes a by-value receiver.
744 #[lang="fn_once"]
745 pub trait FnOnce<Args,Result> {
746     /// This is called when the call operator is used.
747     fn call_once(self, args: Args) -> Result;
748 }
749
750 #[cfg(test)]
751 mod bench {
752     extern crate test;
753     use self::test::Bencher;
754     use ops::Drop;
755
756     // Overhead of dtors
757
758     struct HasDtor {
759         x: int
760     }
761
762     impl Drop for HasDtor {
763         fn drop(&mut self) {
764         }
765     }
766
767     #[bench]
768     fn alloc_obj_with_dtor(b: &mut Bencher) {
769         b.iter(|| {
770             HasDtor { x : 10 };
771         })
772     }
773 }