]> git.lizzy.rs Git - rust.git/blob - src/libstd/ops.rs
Register new snapshots
[rust.git] / src / libstd / 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  * Traits representing built-in operators, useful for overloading
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  * struct Point {
31  *     x: int,
32  *     y: int
33  * }
34  *
35  * impl Add<Point, Point> for Point {
36  *     fn add(&self, other: &Point) -> Point {
37  *         Point {x: self.x + other.x, y: self.y + other.y}
38  *     }
39  * }
40  *
41  * impl Sub<Point, Point> for Point {
42  *     fn sub(&self, other: &Point) -> Point {
43  *         Point {x: self.x - other.x, y: self.y - other.y}
44  *     }
45  * }
46  * fn main() {
47  *     println!("{:?}", Point {x: 1, y: 0} + Point {x: 2, y: 3});
48  *     println!("{:?}", Point {x: 1, y: 0} - Point {x: 2, y: 3});
49  * }
50  * ```
51  *
52  * See the documentation for each trait for a minimum implementation that prints
53  * something to the screen.
54  *
55  */
56
57 /**
58  *
59  * The `Drop` trait is used to run some code when a value goes out of scope. This
60  * is sometimes called a 'destructor'.
61  *
62  * # Example
63  *
64  * A trivial implementation of `Drop`. The `drop` method is called when `_x` goes
65  * out of scope, and therefore `main` prints `Dropping!`.
66  *
67  * ```rust
68  * struct HasDrop;
69  *
70  * impl Drop for HasDrop {
71  *   fn drop(&mut self) {
72  *       println!("Dropping!");
73  *   }
74  * }
75  *
76  * fn main() {
77  *   let _x = HasDrop;
78  * }
79  * ```
80  */
81 #[lang="drop"]
82 pub trait Drop {
83     /// The `drop` method, called when the value goes out of scope.
84     fn drop(&mut self);
85 }
86
87 /**
88  *
89  * The `Add` trait is used to specify the functionality of `+`.
90  *
91  * # Example
92  *
93  * A trivial implementation of `Add`. When `Foo + Foo` happens, it ends up
94  * calling `add`, and therefore, `main` prints `Adding!`.
95  *
96  * ```rust
97  * struct Foo;
98  *
99  * impl Add<Foo, Foo> for Foo {
100  *     fn add(&self, _rhs: &Foo) -> Foo {
101  *       println!("Adding!");
102  *       *self
103  *   }
104  * }
105  *
106  * fn main() {
107  *   Foo + Foo;
108  * }
109  * ```
110  */
111 #[lang="add"]
112 pub trait Add<RHS,Result> {
113     /// The method for the `+` operator
114     fn add(&self, rhs: &RHS) -> Result;
115 }
116
117 /**
118  *
119  * The `Sub` trait is used to specify the functionality of `-`.
120  *
121  * # Example
122  *
123  * A trivial implementation of `Sub`. When `Foo - Foo` happens, it ends up
124  * calling `sub`, and therefore, `main` prints `Subtracting!`.
125  *
126  * ```rust
127  * struct Foo;
128  *
129  * impl Sub<Foo, Foo> for Foo {
130  *     fn sub(&self, _rhs: &Foo) -> Foo {
131  *         println!("Subtracting!");
132  *         *self
133  *     }
134  * }
135  *
136  * fn main() {
137  *     Foo - Foo;
138  * }
139  * ```
140  */
141 #[lang="sub"]
142 pub trait Sub<RHS,Result> {
143     /// The method for the `-` operator
144     fn sub(&self, rhs: &RHS) -> Result;
145 }
146
147 /**
148  *
149  * The `Mul` trait is used to specify the functionality of `*`.
150  *
151  * # Example
152  *
153  * A trivial implementation of `Mul`. When `Foo * Foo` happens, it ends up
154  * calling `mul`, and therefore, `main` prints `Multiplying!`.
155  *
156  * ```rust
157  * struct Foo;
158  *
159  * impl Mul<Foo, Foo> for Foo {
160  *     fn mul(&self, _rhs: &Foo) -> Foo {
161  *         println!("Multiplying!");
162  *         *self
163  *     }
164  * }
165  *
166  * fn main() {
167  *     Foo * Foo;
168  * }
169  * ```
170  */
171 #[lang="mul"]
172 pub trait Mul<RHS,Result> {
173     /// The method for the `*` operator
174     fn mul(&self, rhs: &RHS) -> Result;
175 }
176
177 /**
178  *
179  * The `Div` trait is used to specify the functionality of `/`.
180  *
181  * # Example
182  *
183  * A trivial implementation of `Div`. When `Foo / Foo` happens, it ends up
184  * calling `div`, and therefore, `main` prints `Dividing!`.
185  *
186  * ```
187  * struct Foo;
188  *
189  * impl Div<Foo, Foo> for Foo {
190  *     fn div(&self, _rhs: &Foo) -> Foo {
191  *         println!("Dividing!");
192  *         *self
193  *     }
194  * }
195  *
196  * fn main() {
197  *     Foo / Foo;
198  * }
199  * ```
200  */
201 #[lang="div"]
202 pub trait Div<RHS,Result> {
203     /// The method for the `/` operator
204     fn div(&self, rhs: &RHS) -> Result;
205 }
206
207 /**
208  *
209  * The `Rem` trait is used to specify the functionality of `%`.
210  *
211  * # Example
212  *
213  * A trivial implementation of `Rem`. When `Foo % Foo` happens, it ends up
214  * calling `rem`, and therefore, `main` prints `Remainder-ing!`.
215  *
216  * ```
217  * struct Foo;
218  *
219  * impl Rem<Foo, Foo> for Foo {
220  *     fn rem(&self, _rhs: &Foo) -> Foo {
221  *         println!("Remainder-ing!");
222  *         *self
223  *     }
224  * }
225  *
226  * fn main() {
227  *     Foo % Foo;
228  * }
229  * ```
230  */
231 #[lang="rem"]
232 pub trait Rem<RHS,Result> {
233     /// The method for the `%` operator
234     fn rem(&self, rhs: &RHS) -> Result;
235 }
236
237 /**
238  *
239  * The `Neg` trait is used to specify the functionality of unary `-`.
240  *
241  * # Example
242  *
243  * A trivial implementation of `Neg`. When `-Foo` happens, it ends up calling
244  * `neg`, and therefore, `main` prints `Negating!`.
245  *
246  * ```
247  * struct Foo;
248  *
249  * impl Neg<Foo> for Foo {
250  *     fn neg(&self) -> Foo {
251  *         println!("Negating!");
252  *         *self
253  *     }
254  * }
255  *
256  * fn main() {
257  *     -Foo;
258  * }
259  * ```
260  */
261 #[lang="neg"]
262 pub trait Neg<Result> {
263     /// The method for the unary `-` operator
264     fn neg(&self) -> Result;
265 }
266
267 /**
268  *
269  * The `Not` trait is used to specify the functionality of unary `!`.
270  *
271  * # Example
272  *
273  * A trivial implementation of `Not`. When `!Foo` happens, it ends up calling
274  * `not`, and therefore, `main` prints `Not-ing!`.
275  *
276  * ```
277  * struct Foo;
278  *
279  * impl Not<Foo> for Foo {
280  *     fn not(&self) -> Foo {
281  *         println!("Not-ing!");
282  *         *self
283  *     }
284  * }
285  *
286  * fn main() {
287  *     !Foo;
288  * }
289  * ```
290  */
291 #[lang="not"]
292 pub trait Not<Result> {
293     /// The method for the unary `!` operator
294     fn not(&self) -> Result;
295 }
296
297 /**
298  *
299  * The `BitAnd` trait is used to specify the functionality of `&`.
300  *
301  * # Example
302  *
303  * A trivial implementation of `BitAnd`. When `Foo & Foo` happens, it ends up
304  * calling `bitand`, and therefore, `main` prints `Bitwise And-ing!`.
305  *
306  * ```
307  * struct Foo;
308  *
309  * impl BitAnd<Foo, Foo> for Foo {
310  *     fn bitand(&self, _rhs: &Foo) -> Foo {
311  *         println!("Bitwise And-ing!");
312  *         *self
313  *     }
314  * }
315  *
316  * fn main() {
317  *     Foo & Foo;
318  * }
319  * ```
320  */
321 #[lang="bitand"]
322 pub trait BitAnd<RHS,Result> {
323     /// The method for the `&` operator
324     fn bitand(&self, rhs: &RHS) -> Result;
325 }
326
327 /**
328  *
329  * The `BitOr` trait is used to specify the functionality of `|`.
330  *
331  * # Example
332  *
333  * A trivial implementation of `BitOr`. When `Foo | Foo` happens, it ends up
334  * calling `bitor`, and therefore, `main` prints `Bitwise Or-ing!`.
335  *
336  * ```
337  * struct Foo;
338  *
339  * impl BitOr<Foo, Foo> for Foo {
340  *     fn bitor(&self, _rhs: &Foo) -> Foo {
341  *         println!("Bitwise Or-ing!");
342  *         *self
343  *     }
344  * }
345  *
346  * fn main() {
347  *     Foo | Foo;
348  * }
349  * ```
350  */
351 #[lang="bitor"]
352 pub trait BitOr<RHS,Result> {
353     /// The method for the `|` operator
354     fn bitor(&self, rhs: &RHS) -> Result;
355 }
356
357 /**
358  *
359  * The `BitXor` trait is used to specify the functionality of `^`.
360  *
361  * # Example
362  *
363  * A trivial implementation of `BitXor`. When `Foo ^ Foo` happens, it ends up
364  * calling `bitxor`, and therefore, `main` prints `Bitwise Xor-ing!`.
365  *
366  * ```
367  * struct Foo;
368  *
369  * impl BitXor<Foo, Foo> for Foo {
370  *     fn bitxor(&self, _rhs: &Foo) -> Foo {
371  *         println!("Bitwise Xor-ing!");
372  *         *self
373  *     }
374  * }
375  *
376  * fn main() {
377  *     Foo ^ Foo;
378  * }
379  * ```
380  */
381 #[lang="bitxor"]
382 pub trait BitXor<RHS,Result> {
383     /// The method for the `^` operator
384     fn bitxor(&self, rhs: &RHS) -> Result;
385 }
386
387 /**
388  *
389  * The `Shl` trait is used to specify the functionality of `<<`.
390  *
391  * # Example
392  *
393  * A trivial implementation of `Shl`. When `Foo << Foo` happens, it ends up
394  * calling `shl`, and therefore, `main` prints `Shifting left!`.
395  *
396  * ```
397  * struct Foo;
398  *
399  * impl Shl<Foo, Foo> for Foo {
400  *     fn shl(&self, _rhs: &Foo) -> Foo {
401  *         println!("Shifting left!");
402  *         *self
403  *     }
404  * }
405  *
406  * fn main() {
407  *     Foo << Foo;
408  * }
409  * ```
410  */
411 #[lang="shl"]
412 pub trait Shl<RHS,Result> {
413     /// The method for the `<<` operator
414     fn shl(&self, rhs: &RHS) -> Result;
415 }
416
417 /**
418  *
419  * The `Shr` trait is used to specify the functionality of `>>`.
420  *
421  * # Example
422  *
423  * A trivial implementation of `Shr`. When `Foo >> Foo` happens, it ends up
424  * calling `shr`, and therefore, `main` prints `Shifting right!`.
425  *
426  * ```
427  * struct Foo;
428  *
429  * impl Shr<Foo, Foo> for Foo {
430  *     fn shr(&self, _rhs: &Foo) -> Foo {
431  *         println!("Shifting right!");
432  *         *self
433  *     }
434  * }
435  *
436  * fn main() {
437  *     Foo >> Foo;
438  * }
439  * ```
440  */
441 #[lang="shr"]
442 pub trait Shr<RHS,Result> {
443     /// The method for the `>>` operator
444     fn shr(&self, rhs: &RHS) -> Result;
445 }
446
447 /**
448  *
449  * The `Index` trait is used to specify the functionality of indexing operations
450  * like `arr[idx]`.
451  *
452  * # Example
453  *
454  * A trivial implementation of `Index`. When `Foo[Foo]` happens, it ends up
455  * calling `index`, and therefore, `main` prints `Indexing!`.
456  *
457  * ```
458  * struct Foo;
459  *
460  * impl Index<Foo, Foo> for Foo {
461  *     fn index(&self, _rhs: &Foo) -> Foo {
462  *         println!("Indexing!");
463  *         *self
464  *     }
465  * }
466  *
467  * fn main() {
468  *     Foo[Foo];
469  * }
470  * ```
471  */
472 #[lang="index"]
473 pub trait Index<Index,Result> {
474     /// The method for the indexing (`Foo[Bar]`) operation
475     fn index(&self, index: &Index) -> Result;
476 }
477
478 /**
479  *
480  * The `Deref` trait is used to specify the functionality of dereferencing
481  * operations like `*v`.
482  *
483  * # Example
484  *
485  * A struct with a single field which is accessible via dereferencing the
486  * struct.
487  *
488  * ```
489  * struct DerefExample<T> {
490  *     value: T
491  * }
492  *
493  * impl<T> Deref<T> for DerefExample<T> {
494  *     fn deref<'a>(&'a self) -> &'a T {
495  *         &self.value
496  *     }
497  * }
498  *
499  * fn main() {
500  *     let x = DerefExample { value: 'a' };
501  *     assert_eq!('a', *x);
502  * }
503  * ```
504  */
505 #[lang="deref"]
506 pub trait Deref<Result> {
507     /// The method called to dereference a value
508     fn deref<'a>(&'a self) -> &'a Result;
509 }
510
511 /**
512  *
513  * The `DerefMut` trait is used to specify the functionality of dereferencing
514  * mutably like `*v = 1;`
515  *
516  * # Example
517  *
518  * A struct with a single field which is modifiable via dereferencing the
519  * struct.
520  *
521  * ```
522  * struct DerefMutExample<T> {
523  *     value: T
524  * }
525  *
526  * impl<T> Deref<T> for DerefMutExample<T> {
527  *     fn deref<'a>(&'a self) -> &'a T {
528  *         &self.value
529  *     }
530  * }
531  *
532  * impl<T> DerefMut<T> for DerefMutExample<T> {
533  *     fn deref_mut<'a>(&'a mut self) -> &'a mut T {
534  *         &mut self.value
535  *     }
536  * }
537  *
538  * fn main() {
539  *     let mut x = DerefMutExample { value: 'a' };
540  *     *x = 'b';
541  *     assert_eq!('b', *x);
542  * }
543  * ```
544  */
545 #[lang="deref_mut"]
546 pub trait DerefMut<Result>: Deref<Result> {
547     /// The method called to mutably dereference a value
548     fn deref_mut<'a>(&'a mut self) -> &'a mut Result;
549 }
550
551 #[cfg(test)]
552 mod bench {
553     extern crate test;
554     use self::test::BenchHarness;
555     use ops::Drop;
556
557     // Overhead of dtors
558
559     struct HasDtor {
560         x: int
561     }
562
563     impl Drop for HasDtor {
564         fn drop(&mut self) {
565         }
566     }
567
568     #[bench]
569     fn alloc_obj_with_dtor(bh: &mut BenchHarness) {
570         bh.iter(|| {
571             HasDtor { x : 10 };
572         })
573     }
574 }