]> git.lizzy.rs Git - rust.git/blob - src/libstd/ops.rs
auto merge of #10977 : brson/rust/androidtest, r=brson
[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 // So we don't have to document the actual methods on the traits.
12 #[allow(missing_doc)];
13
14 /*!
15  *
16  * Traits for the built-in operators. Implementing these traits allows you to get
17  * an effect similar to overloading operators.
18  *
19  * The values for the right hand side of an operator are automatically
20  * borrowed, so `a + b` is sugar for `a.add(&b)`.
21  *
22  * All of these traits are imported by the prelude, so they are available in
23  * every Rust program.
24  *
25  * # Example
26  *
27  * This example creates a `Point` struct that implements `Add` and `Sub`, and then
28  * demonstrates adding and subtracting two `Point`s.
29  *
30  * ```rust
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(format!("{:?}", Point {x: 1, y: 0} + Point {x: 2, y: 3}));
49  *     println(format!("{:?}", 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     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     fn add(&self, rhs: &RHS) -> Result;
114 }
115
116 /**
117  *
118  * The `Sub` trait is used to specify the functionality of `-`.
119  *
120  * # Example
121  *
122  * A trivial implementation of `Sub`. When `Foo - Foo` happens, it ends up
123  * calling `sub`, and therefore, `main` prints `Subtracting!`.
124  *
125  * ```rust
126  * struct Foo;
127  *
128  * impl Sub<Foo, Foo> for Foo {
129  *     fn sub(&self, _rhs: &Foo) -> Foo {
130  *         println("Subtracting!");
131  *         *self
132  *     }
133  * }
134  *
135  * fn main() {
136  *     Foo - Foo;
137  * }
138  * ```
139  */
140 #[lang="sub"]
141 pub trait Sub<RHS,Result> {
142     fn sub(&self, rhs: &RHS) -> Result;
143 }
144
145 /**
146  *
147  * The `Mul` trait is used to specify the functionality of `*`.
148  *
149  * # Example
150  *
151  * A trivial implementation of `Mul`. When `Foo * Foo` happens, it ends up
152  * calling `mul`, and therefore, `main` prints `Multiplying!`.
153  *
154  * ```rust
155  * struct Foo;
156  *
157  * impl Mul<Foo, Foo> for Foo {
158  *     fn mul(&self, _rhs: &Foo) -> Foo {
159  *         println("Multiplying!");
160  *         *self
161  *     }
162  * }
163  *
164  * fn main() {
165  *     Foo * Foo;
166  * }
167  * ```
168  */
169 #[lang="mul"]
170 pub trait Mul<RHS,Result> {
171     fn mul(&self, rhs: &RHS) -> Result;
172 }
173
174 /**
175  *
176  * The `Div` trait is used to specify the functionality of `/`.
177  *
178  * # Example
179  *
180  * A trivial implementation of `Div`. When `Foo / Foo` happens, it ends up
181  * calling `div`, and therefore, `main` prints `Dividing!`.
182  *
183  * ```
184  * struct Foo;
185  *
186  * impl Div<Foo, Foo> for Foo {
187  *     fn div(&self, _rhs: &Foo) -> Foo {
188  *         println("Dividing!");
189  *         *self
190  *     }
191  * }
192  *
193  * fn main() {
194  *     Foo / Foo;
195  * }
196  * ```
197  */
198 #[lang="div"]
199 pub trait Div<RHS,Result> {
200     fn div(&self, rhs: &RHS) -> Result;
201 }
202
203 /**
204  *
205  * The `Rem` trait is used to specify the functionality of `%`.
206  *
207  * # Example
208  *
209  * A trivial implementation of `Rem`. When `Foo % Foo` happens, it ends up
210  * calling `rem`, and therefore, `main` prints `Remainder-ing!`.
211  *
212  * ```
213  * struct Foo;
214  *
215  * impl Rem<Foo, Foo> for Foo {
216  *     fn rem(&self, _rhs: &Foo) -> Foo {
217  *         println("Remainder-ing!");
218  *         *self
219  *     }
220  * }
221  *
222  * fn main() {
223  *     Foo % Foo;
224  * }
225  * ```
226  */
227 #[lang="rem"]
228 pub trait Rem<RHS,Result> {
229     fn rem(&self, rhs: &RHS) -> Result;
230 }
231
232 /**
233  *
234  * The `Neg` trait is used to specify the functionality of unary `-`.
235  *
236  * # Example
237  *
238  * A trivial implementation of `Neg`. When `-Foo` happens, it ends up calling
239  * `neg`, and therefore, `main` prints `Negating!`.
240  *
241  * ```
242  * struct Foo;
243  *
244  * impl Neg<Foo> for Foo {
245  *     fn neg(&self) -> Foo {
246  *         println("Negating!");
247  *         *self
248  *     }
249  * }
250  *
251  * fn main() {
252  *     -Foo;
253  * }
254  * ```
255  */
256 #[lang="neg"]
257 pub trait Neg<Result> {
258     fn neg(&self) -> Result;
259 }
260
261 /**
262  *
263  * The `Not` trait is used to specify the functionality of unary `!`.
264  *
265  * # Example
266  *
267  * A trivial implementation of `Not`. When `!Foo` happens, it ends up calling
268  * `not`, and therefore, `main` prints `Not-ing!`.
269  *
270  * ```
271  * struct Foo;
272  *
273  * impl Not<Foo> for Foo {
274  *     fn not(&self) -> Foo {
275  *         println("Not-ing!");
276  *         *self
277  *     }
278  * }
279  *
280  * fn main() {
281  *     !Foo;
282  * }
283  * ```
284  */
285 #[lang="not"]
286 pub trait Not<Result> {
287     fn not(&self) -> Result;
288 }
289
290 /**
291  *
292  * The `BitAnd` trait is used to specify the functionality of `&`.
293  *
294  * # Example
295  *
296  * A trivial implementation of `BitAnd`. When `Foo & Foo` happens, it ends up
297  * calling `bitand`, and therefore, `main` prints `Bitwise And-ing!`.
298  *
299  * ```
300  * struct Foo;
301  *
302  * impl BitAnd<Foo, Foo> for Foo {
303  *     fn bitand(&self, _rhs: &Foo) -> Foo {
304  *         println("Bitwise And-ing!");
305  *         *self
306  *     }
307  * }
308  *
309  * fn main() {
310  *     Foo & Foo;
311  * }
312  * ```
313  */
314 #[lang="bitand"]
315 pub trait BitAnd<RHS,Result> {
316     fn bitand(&self, rhs: &RHS) -> Result;
317 }
318
319 /**
320  *
321  * The `BitOr` trait is used to specify the functionality of `|`.
322  *
323  * # Example
324  *
325  * A trivial implementation of `BitOr`. When `Foo | Foo` happens, it ends up
326  * calling `bitor`, and therefore, `main` prints `Bitwise Or-ing!`.
327  *
328  * ```
329  * struct Foo;
330  *
331  * impl BitOr<Foo, Foo> for Foo {
332  *     fn bitor(&self, _rhs: &Foo) -> Foo {
333  *         println("Bitwise Or-ing!");
334  *         *self
335  *     }
336  * }
337  *
338  * fn main() {
339  *     Foo | Foo;
340  * }
341  * ```
342  */
343 #[lang="bitor"]
344 pub trait BitOr<RHS,Result> {
345     fn bitor(&self, rhs: &RHS) -> Result;
346 }
347
348 /**
349  *
350  * The `BitXor` trait is used to specify the functionality of `^`.
351  *
352  * # Example
353  *
354  * A trivial implementation of `BitXor`. When `Foo ^ Foo` happens, it ends up
355  * calling `bitxor`, and therefore, `main` prints `Bitwise Xor-ing!`.
356  *
357  * ```
358  * struct Foo;
359  *
360  * impl BitXor<Foo, Foo> for Foo {
361  *     fn bitxor(&self, _rhs: &Foo) -> Foo {
362  *         println("Bitwise Xor-ing!");
363  *         *self
364  *     }
365  * }
366  *
367  * fn main() {
368  *     Foo ^ Foo;
369  * }
370  * ```
371  */
372 #[lang="bitxor"]
373 pub trait BitXor<RHS,Result> {
374     fn bitxor(&self, rhs: &RHS) -> Result;
375 }
376
377 /**
378  *
379  * The `Shl` trait is used to specify the functionality of `<<`.
380  *
381  * # Example
382  *
383  * A trivial implementation of `Shl`. When `Foo << Foo` happens, it ends up
384  * calling `shl`, and therefore, `main` prints `Shifting left!`.
385  *
386  * ```
387  * struct Foo;
388  *
389  * impl Shl<Foo, Foo> for Foo {
390  *     fn shl(&self, _rhs: &Foo) -> Foo {
391  *         println("Shifting left!");
392  *         *self
393  *     }
394  * }
395  *
396  * fn main() {
397  *     Foo << Foo;
398  * }
399  * ```
400  */
401 #[lang="shl"]
402 pub trait Shl<RHS,Result> {
403     fn shl(&self, rhs: &RHS) -> Result;
404 }
405
406 /**
407  *
408  * The `Shr` trait is used to specify the functionality of `>>`.
409  *
410  * # Example
411  *
412  * A trivial implementation of `Shr`. When `Foo >> Foo` happens, it ends up
413  * calling `shr`, and therefore, `main` prints `Shifting right!`.
414  *
415  * ```
416  * struct Foo;
417  *
418  * impl Shr<Foo, Foo> for Foo {
419  *     fn shr(&self, _rhs: &Foo) -> Foo {
420  *         println("Shifting right!");
421  *         *self
422  *     }
423  * }
424  *
425  * fn main() {
426  *     Foo >> Foo;
427  * }
428  * ```
429  */
430 #[lang="shr"]
431 pub trait Shr<RHS,Result> {
432     fn shr(&self, rhs: &RHS) -> Result;
433 }
434
435 /**
436  *
437  * The `Index` trait is used to specify the functionality of indexing operations
438  * like `arr[idx]`.
439  *
440  * # Example
441  *
442  * A trivial implementation of `Index`. When `Foo[Foo]` happens, it ends up
443  * calling `index`, and therefore, `main` prints `Indexing!`.
444  *
445  * ```
446  * struct Foo;
447  *
448  * impl Index<Foo, Foo> for Foo {
449  *     fn index(&self, _rhs: &Foo) -> Foo {
450  *         println("Indexing!");
451  *         *self
452  *     }
453  * }
454  *
455  * fn main() {
456  *     Foo[Foo];
457  * }
458  * ```
459  */
460 #[lang="index"]
461 pub trait Index<Index,Result> {
462     fn index(&self, index: &Index) -> Result;
463 }
464
465 #[cfg(test)]
466 mod bench {
467
468     use extra::test::BenchHarness;
469     use ops::Drop;
470
471     // Overhead of dtors
472
473     struct HasDtor {
474         x: int
475     }
476
477     impl Drop for HasDtor {
478         fn drop(&mut self) {
479         }
480     }
481
482     #[bench]
483     fn alloc_obj_with_dtor(bh: &mut BenchHarness) {
484         bh.iter(|| {
485             HasDtor { x : 10 };
486         })
487     }
488 }