]> git.lizzy.rs Git - rust.git/blob - src/libcore/ops.rs
Auto merge of #23931 - steveklabnik:doc_std_fs, r=alexcrichton
[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 //! Overloadable operators
12 //!
13 //! Implementing these traits allows you to get an effect similar to
14 //! overloading operators.
15 //!
16 //! Some of these traits are imported by the prelude, so they are available in
17 //! every Rust program.
18 //!
19 //! Many of the operators take their operands by value. In non-generic
20 //! contexts involving built-in types, this is usually not a problem.
21 //! However, using these operators in generic code, requires some
22 //! attention if values have to be reused as opposed to letting the operators
23 //! consume them. One option is to occasionally use `clone()`.
24 //! Another option is to rely on the types involved providing additional
25 //! operator implementations for references. For example, for a user-defined
26 //! type `T` which is supposed to support addition, it is probably a good
27 //! idea to have both `T` and `&T` implement the traits `Add<T>` and `Add<&T>`
28 //! so that generic code can be written without unnecessary cloning.
29 //!
30 //! # Examples
31 //!
32 //! This example creates a `Point` struct that implements `Add` and `Sub`, and then
33 //! demonstrates adding and subtracting two `Point`s.
34 //!
35 //! ```rust
36 //! use std::ops::{Add, Sub};
37 //!
38 //! #[derive(Debug)]
39 //! struct Point {
40 //!     x: i32,
41 //!     y: i32
42 //! }
43 //!
44 //! impl Add for Point {
45 //!     type Output = Point;
46 //!
47 //!     fn add(self, other: Point) -> Point {
48 //!         Point {x: self.x + other.x, y: self.y + other.y}
49 //!     }
50 //! }
51 //!
52 //! impl Sub for Point {
53 //!     type Output = Point;
54 //!
55 //!     fn sub(self, other: Point) -> Point {
56 //!         Point {x: self.x - other.x, y: self.y - other.y}
57 //!     }
58 //! }
59 //! fn main() {
60 //!     println!("{:?}", Point {x: 1, y: 0} + Point {x: 2, y: 3});
61 //!     println!("{:?}", Point {x: 1, y: 0} - Point {x: 2, y: 3});
62 //! }
63 //! ```
64 //!
65 //! See the documentation for each trait for a minimum implementation that prints
66 //! something to the screen.
67
68 #![stable(feature = "rust1", since = "1.0.0")]
69
70 use marker::Sized;
71 use fmt;
72
73 /// The `Drop` trait is used to run some code when a value goes out of scope. This
74 /// is sometimes called a 'destructor'.
75 ///
76 /// # Examples
77 ///
78 /// A trivial implementation of `Drop`. The `drop` method is called when `_x` goes
79 /// out of scope, and therefore `main` prints `Dropping!`.
80 ///
81 /// ```
82 /// struct HasDrop;
83 ///
84 /// impl Drop for HasDrop {
85 ///     fn drop(&mut self) {
86 ///         println!("Dropping!");
87 ///     }
88 /// }
89 ///
90 /// fn main() {
91 ///     let _x = HasDrop;
92 /// }
93 /// ```
94 #[lang="drop"]
95 #[stable(feature = "rust1", since = "1.0.0")]
96 pub trait Drop {
97     /// The `drop` method, called when the value goes out of scope.
98     #[stable(feature = "rust1", since = "1.0.0")]
99     fn drop(&mut self);
100 }
101
102 // implements the unary operator "op &T"
103 // based on "op T" where T is expected to be `Copy`able
104 macro_rules! forward_ref_unop {
105     (impl $imp:ident, $method:ident for $t:ty) => {
106         #[unstable(feature = "core",
107                    reason = "recently added, waiting for dust to settle")]
108         impl<'a> $imp for &'a $t {
109             type Output = <$t as $imp>::Output;
110
111             #[inline]
112             fn $method(self) -> <$t as $imp>::Output {
113                 $imp::$method(*self)
114             }
115         }
116     }
117 }
118
119 // implements binary operators "&T op U", "T op &U", "&T op &U"
120 // based on "T op U" where T and U are expected to be `Copy`able
121 macro_rules! forward_ref_binop {
122     (impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
123         #[unstable(feature = "core",
124                    reason = "recently added, waiting for dust to settle")]
125         impl<'a> $imp<$u> for &'a $t {
126             type Output = <$t as $imp<$u>>::Output;
127
128             #[inline]
129             fn $method(self, other: $u) -> <$t as $imp<$u>>::Output {
130                 $imp::$method(*self, other)
131             }
132         }
133
134         #[unstable(feature = "core",
135                    reason = "recently added, waiting for dust to settle")]
136         impl<'a> $imp<&'a $u> for $t {
137             type Output = <$t as $imp<$u>>::Output;
138
139             #[inline]
140             fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
141                 $imp::$method(self, *other)
142             }
143         }
144
145         #[unstable(feature = "core",
146                    reason = "recently added, waiting for dust to settle")]
147         impl<'a, 'b> $imp<&'a $u> for &'b $t {
148             type Output = <$t as $imp<$u>>::Output;
149
150             #[inline]
151             fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
152                 $imp::$method(*self, *other)
153             }
154         }
155     }
156 }
157
158 /// The `Add` trait is used to specify the functionality of `+`.
159 ///
160 /// # Examples
161 ///
162 /// A trivial implementation of `Add`. When `Foo + Foo` happens, it ends up
163 /// calling `add`, and therefore, `main` prints `Adding!`.
164 ///
165 /// ```
166 /// use std::ops::Add;
167 ///
168 /// #[derive(Copy, Clone)]
169 /// struct Foo;
170 ///
171 /// impl Add for Foo {
172 ///     type Output = Foo;
173 ///
174 ///     fn add(self, _rhs: Foo) -> Foo {
175 ///       println!("Adding!");
176 ///       self
177 ///   }
178 /// }
179 ///
180 /// fn main() {
181 ///   Foo + Foo;
182 /// }
183 /// ```
184 #[lang="add"]
185 #[stable(feature = "rust1", since = "1.0.0")]
186 pub trait Add<RHS=Self> {
187     /// The resulting type after applying the `+` operator
188     #[stable(feature = "rust1", since = "1.0.0")]
189     type Output;
190
191     /// The method for the `+` operator
192     #[stable(feature = "rust1", since = "1.0.0")]
193     fn add(self, rhs: RHS) -> Self::Output;
194 }
195
196 macro_rules! add_impl {
197     ($($t:ty)*) => ($(
198         #[stable(feature = "rust1", since = "1.0.0")]
199         impl Add for $t {
200             type Output = $t;
201
202             #[inline]
203             fn add(self, other: $t) -> $t { self + other }
204         }
205
206         forward_ref_binop! { impl Add, add for $t, $t }
207     )*)
208 }
209
210 add_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
211
212 /// The `Sub` trait is used to specify the functionality of `-`.
213 ///
214 /// # Examples
215 ///
216 /// A trivial implementation of `Sub`. When `Foo - Foo` happens, it ends up
217 /// calling `sub`, and therefore, `main` prints `Subtracting!`.
218 ///
219 /// ```
220 /// use std::ops::Sub;
221 ///
222 /// #[derive(Copy, Clone)]
223 /// struct Foo;
224 ///
225 /// impl Sub for Foo {
226 ///     type Output = Foo;
227 ///
228 ///     fn sub(self, _rhs: Foo) -> Foo {
229 ///         println!("Subtracting!");
230 ///         self
231 ///     }
232 /// }
233 ///
234 /// fn main() {
235 ///     Foo - Foo;
236 /// }
237 /// ```
238 #[lang="sub"]
239 #[stable(feature = "rust1", since = "1.0.0")]
240 pub trait Sub<RHS=Self> {
241     /// The resulting type after applying the `-` operator
242     #[stable(feature = "rust1", since = "1.0.0")]
243     type Output;
244
245     /// The method for the `-` operator
246     #[stable(feature = "rust1", since = "1.0.0")]
247     fn sub(self, rhs: RHS) -> Self::Output;
248 }
249
250 macro_rules! sub_impl {
251     ($($t:ty)*) => ($(
252         #[stable(feature = "rust1", since = "1.0.0")]
253         impl Sub for $t {
254             type Output = $t;
255
256             #[inline]
257             fn sub(self, other: $t) -> $t { self - other }
258         }
259
260         forward_ref_binop! { impl Sub, sub for $t, $t }
261     )*)
262 }
263
264 sub_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
265
266 /// The `Mul` trait is used to specify the functionality of `*`.
267 ///
268 /// # Examples
269 ///
270 /// A trivial implementation of `Mul`. When `Foo * Foo` happens, it ends up
271 /// calling `mul`, and therefore, `main` prints `Multiplying!`.
272 ///
273 /// ```
274 /// use std::ops::Mul;
275 ///
276 /// #[derive(Copy, Clone)]
277 /// struct Foo;
278 ///
279 /// impl Mul for Foo {
280 ///     type Output = Foo;
281 ///
282 ///     fn mul(self, _rhs: Foo) -> Foo {
283 ///         println!("Multiplying!");
284 ///         self
285 ///     }
286 /// }
287 ///
288 /// fn main() {
289 ///     Foo * Foo;
290 /// }
291 /// ```
292 #[lang="mul"]
293 #[stable(feature = "rust1", since = "1.0.0")]
294 pub trait Mul<RHS=Self> {
295     /// The resulting type after applying the `*` operator
296     #[stable(feature = "rust1", since = "1.0.0")]
297     type Output;
298
299     /// The method for the `*` operator
300     #[stable(feature = "rust1", since = "1.0.0")]
301     fn mul(self, rhs: RHS) -> Self::Output;
302 }
303
304 macro_rules! mul_impl {
305     ($($t:ty)*) => ($(
306         #[stable(feature = "rust1", since = "1.0.0")]
307         impl Mul for $t {
308             type Output = $t;
309
310             #[inline]
311             fn mul(self, other: $t) -> $t { self * other }
312         }
313
314         forward_ref_binop! { impl Mul, mul for $t, $t }
315     )*)
316 }
317
318 mul_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
319
320 /// The `Div` trait is used to specify the functionality of `/`.
321 ///
322 /// # Examples
323 ///
324 /// A trivial implementation of `Div`. When `Foo / Foo` happens, it ends up
325 /// calling `div`, and therefore, `main` prints `Dividing!`.
326 ///
327 /// ```
328 /// use std::ops::Div;
329 ///
330 /// #[derive(Copy, Clone)]
331 /// struct Foo;
332 ///
333 /// impl Div for Foo {
334 ///     type Output = Foo;
335 ///
336 ///     fn div(self, _rhs: Foo) -> Foo {
337 ///         println!("Dividing!");
338 ///         self
339 ///     }
340 /// }
341 ///
342 /// fn main() {
343 ///     Foo / Foo;
344 /// }
345 /// ```
346 #[lang="div"]
347 #[stable(feature = "rust1", since = "1.0.0")]
348 pub trait Div<RHS=Self> {
349     /// The resulting type after applying the `/` operator
350     #[stable(feature = "rust1", since = "1.0.0")]
351     type Output;
352
353     /// The method for the `/` operator
354     #[stable(feature = "rust1", since = "1.0.0")]
355     fn div(self, rhs: RHS) -> Self::Output;
356 }
357
358 macro_rules! div_impl {
359     ($($t:ty)*) => ($(
360         #[stable(feature = "rust1", since = "1.0.0")]
361         impl Div for $t {
362             type Output = $t;
363
364             #[inline]
365             fn div(self, other: $t) -> $t { self / other }
366         }
367
368         forward_ref_binop! { impl Div, div for $t, $t }
369     )*)
370 }
371
372 div_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
373
374 /// The `Rem` trait is used to specify the functionality of `%`.
375 ///
376 /// # Examples
377 ///
378 /// A trivial implementation of `Rem`. When `Foo % Foo` happens, it ends up
379 /// calling `rem`, and therefore, `main` prints `Remainder-ing!`.
380 ///
381 /// ```
382 /// use std::ops::Rem;
383 ///
384 /// #[derive(Copy, Clone)]
385 /// struct Foo;
386 ///
387 /// impl Rem for Foo {
388 ///     type Output = Foo;
389 ///
390 ///     fn rem(self, _rhs: Foo) -> Foo {
391 ///         println!("Remainder-ing!");
392 ///         self
393 ///     }
394 /// }
395 ///
396 /// fn main() {
397 ///     Foo % Foo;
398 /// }
399 /// ```
400 #[lang="rem"]
401 #[stable(feature = "rust1", since = "1.0.0")]
402 pub trait Rem<RHS=Self> {
403     /// The resulting type after applying the `%` operator
404     #[stable(feature = "rust1", since = "1.0.0")]
405     type Output = Self;
406
407     /// The method for the `%` operator
408     #[stable(feature = "rust1", since = "1.0.0")]
409     fn rem(self, rhs: RHS) -> Self::Output;
410 }
411
412 macro_rules! rem_impl {
413     ($($t:ty)*) => ($(
414         #[stable(feature = "rust1", since = "1.0.0")]
415         impl Rem for $t {
416             type Output = $t;
417
418             #[inline]
419             fn rem(self, other: $t) -> $t { self % other }
420         }
421
422         forward_ref_binop! { impl Rem, rem for $t, $t }
423     )*)
424 }
425
426 macro_rules! rem_float_impl {
427     ($t:ty, $fmod:ident) => {
428         #[stable(feature = "rust1", since = "1.0.0")]
429         impl Rem for $t {
430             type Output = $t;
431
432             #[inline]
433             fn rem(self, other: $t) -> $t {
434                 extern { fn $fmod(a: $t, b: $t) -> $t; }
435                 unsafe { $fmod(self, other) }
436             }
437         }
438
439         forward_ref_binop! { impl Rem, rem for $t, $t }
440     }
441 }
442
443 rem_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
444 rem_float_impl! { f32, fmodf }
445 rem_float_impl! { f64, fmod }
446
447 /// The `Neg` trait is used to specify the functionality of unary `-`.
448 ///
449 /// # Examples
450 ///
451 /// A trivial implementation of `Neg`. When `-Foo` happens, it ends up calling
452 /// `neg`, and therefore, `main` prints `Negating!`.
453 ///
454 /// ```
455 /// use std::ops::Neg;
456 ///
457 /// #[derive(Copy, Clone)]
458 /// struct Foo;
459 ///
460 /// impl Neg for Foo {
461 ///     type Output = Foo;
462 ///
463 ///     fn neg(self) -> Foo {
464 ///         println!("Negating!");
465 ///         self
466 ///     }
467 /// }
468 ///
469 /// fn main() {
470 ///     -Foo;
471 /// }
472 /// ```
473 #[lang="neg"]
474 #[stable(feature = "rust1", since = "1.0.0")]
475 pub trait Neg {
476     /// The resulting type after applying the `-` operator
477     #[stable(feature = "rust1", since = "1.0.0")]
478     type Output;
479
480     /// The method for the unary `-` operator
481     #[stable(feature = "rust1", since = "1.0.0")]
482     fn neg(self) -> Self::Output;
483 }
484
485
486
487 macro_rules! neg_impl_core {
488     ($id:ident => $body:expr, $($t:ty)*) => ($(
489         #[stable(feature = "rust1", since = "1.0.0")]
490         #[allow(unsigned_negation)]
491         impl Neg for $t {
492             #[stable(feature = "rust1", since = "1.0.0")]
493             type Output = $t;
494
495             #[inline]
496             #[stable(feature = "rust1", since = "1.0.0")]
497             fn neg(self) -> $t { let $id = self; $body }
498         }
499
500         forward_ref_unop! { impl Neg, neg for $t }
501     )*)
502 }
503
504 macro_rules! neg_impl_numeric {
505     ($($t:ty)*) => { neg_impl_core!{ x => -x, $($t)*} }
506 }
507
508 macro_rules! neg_impl_unsigned {
509     ($($t:ty)*) => {
510         neg_impl_core!{ x => {
511             #[cfg(stage0)]
512             use ::num::wrapping::WrappingOps;
513             !x.wrapping_add(1)
514         }, $($t)*} }
515 }
516
517 // neg_impl_unsigned! { usize u8 u16 u32 u64 }
518 neg_impl_numeric! { isize i8 i16 i32 i64 f32 f64 }
519
520 /// The `Not` trait is used to specify the functionality of unary `!`.
521 ///
522 /// # Examples
523 ///
524 /// A trivial implementation of `Not`. When `!Foo` happens, it ends up calling
525 /// `not`, and therefore, `main` prints `Not-ing!`.
526 ///
527 /// ```
528 /// use std::ops::Not;
529 ///
530 /// #[derive(Copy, Clone)]
531 /// struct Foo;
532 ///
533 /// impl Not for Foo {
534 ///     type Output = Foo;
535 ///
536 ///     fn not(self) -> Foo {
537 ///         println!("Not-ing!");
538 ///         self
539 ///     }
540 /// }
541 ///
542 /// fn main() {
543 ///     !Foo;
544 /// }
545 /// ```
546 #[lang="not"]
547 #[stable(feature = "rust1", since = "1.0.0")]
548 pub trait Not {
549     /// The resulting type after applying the `!` operator
550     #[stable(feature = "rust1", since = "1.0.0")]
551     type Output;
552
553     /// The method for the unary `!` operator
554     #[stable(feature = "rust1", since = "1.0.0")]
555     fn not(self) -> Self::Output;
556 }
557
558 macro_rules! not_impl {
559     ($($t:ty)*) => ($(
560         #[stable(feature = "rust1", since = "1.0.0")]
561         impl Not for $t {
562             type Output = $t;
563
564             #[inline]
565             fn not(self) -> $t { !self }
566         }
567
568         forward_ref_unop! { impl Not, not for $t }
569     )*)
570 }
571
572 not_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
573
574 /// The `BitAnd` trait is used to specify the functionality of `&`.
575 ///
576 /// # Examples
577 ///
578 /// A trivial implementation of `BitAnd`. When `Foo & Foo` happens, it ends up
579 /// calling `bitand`, and therefore, `main` prints `Bitwise And-ing!`.
580 ///
581 /// ```
582 /// use std::ops::BitAnd;
583 ///
584 /// #[derive(Copy, Clone)]
585 /// struct Foo;
586 ///
587 /// impl BitAnd for Foo {
588 ///     type Output = Foo;
589 ///
590 ///     fn bitand(self, _rhs: Foo) -> Foo {
591 ///         println!("Bitwise And-ing!");
592 ///         self
593 ///     }
594 /// }
595 ///
596 /// fn main() {
597 ///     Foo & Foo;
598 /// }
599 /// ```
600 #[lang="bitand"]
601 #[stable(feature = "rust1", since = "1.0.0")]
602 pub trait BitAnd<RHS=Self> {
603     /// The resulting type after applying the `&` operator
604     #[stable(feature = "rust1", since = "1.0.0")]
605     type Output;
606
607     /// The method for the `&` operator
608     #[stable(feature = "rust1", since = "1.0.0")]
609     fn bitand(self, rhs: RHS) -> Self::Output;
610 }
611
612 macro_rules! bitand_impl {
613     ($($t:ty)*) => ($(
614         #[stable(feature = "rust1", since = "1.0.0")]
615         impl BitAnd for $t {
616             type Output = $t;
617
618             #[inline]
619             fn bitand(self, rhs: $t) -> $t { self & rhs }
620         }
621
622         forward_ref_binop! { impl BitAnd, bitand for $t, $t }
623     )*)
624 }
625
626 bitand_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
627
628 /// The `BitOr` trait is used to specify the functionality of `|`.
629 ///
630 /// # Examples
631 ///
632 /// A trivial implementation of `BitOr`. When `Foo | Foo` happens, it ends up
633 /// calling `bitor`, and therefore, `main` prints `Bitwise Or-ing!`.
634 ///
635 /// ```
636 /// use std::ops::BitOr;
637 ///
638 /// #[derive(Copy, Clone)]
639 /// struct Foo;
640 ///
641 /// impl BitOr for Foo {
642 ///     type Output = Foo;
643 ///
644 ///     fn bitor(self, _rhs: Foo) -> Foo {
645 ///         println!("Bitwise Or-ing!");
646 ///         self
647 ///     }
648 /// }
649 ///
650 /// fn main() {
651 ///     Foo | Foo;
652 /// }
653 /// ```
654 #[lang="bitor"]
655 #[stable(feature = "rust1", since = "1.0.0")]
656 pub trait BitOr<RHS=Self> {
657     /// The resulting type after applying the `|` operator
658     #[stable(feature = "rust1", since = "1.0.0")]
659     type Output;
660
661     /// The method for the `|` operator
662     #[stable(feature = "rust1", since = "1.0.0")]
663     fn bitor(self, rhs: RHS) -> Self::Output;
664 }
665
666 macro_rules! bitor_impl {
667     ($($t:ty)*) => ($(
668         #[stable(feature = "rust1", since = "1.0.0")]
669         impl BitOr for $t {
670             type Output = $t;
671
672             #[inline]
673             fn bitor(self, rhs: $t) -> $t { self | rhs }
674         }
675
676         forward_ref_binop! { impl BitOr, bitor for $t, $t }
677     )*)
678 }
679
680 bitor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
681
682 /// The `BitXor` trait is used to specify the functionality of `^`.
683 ///
684 /// # Examples
685 ///
686 /// A trivial implementation of `BitXor`. When `Foo ^ Foo` happens, it ends up
687 /// calling `bitxor`, and therefore, `main` prints `Bitwise Xor-ing!`.
688 ///
689 /// ```
690 /// use std::ops::BitXor;
691 ///
692 /// #[derive(Copy, Clone)]
693 /// struct Foo;
694 ///
695 /// impl BitXor for Foo {
696 ///     type Output = Foo;
697 ///
698 ///     fn bitxor(self, _rhs: Foo) -> Foo {
699 ///         println!("Bitwise Xor-ing!");
700 ///         self
701 ///     }
702 /// }
703 ///
704 /// fn main() {
705 ///     Foo ^ Foo;
706 /// }
707 /// ```
708 #[lang="bitxor"]
709 #[stable(feature = "rust1", since = "1.0.0")]
710 pub trait BitXor<RHS=Self> {
711     /// The resulting type after applying the `^` operator
712     #[stable(feature = "rust1", since = "1.0.0")]
713     type Output;
714
715     /// The method for the `^` operator
716     #[stable(feature = "rust1", since = "1.0.0")]
717     fn bitxor(self, rhs: RHS) -> Self::Output;
718 }
719
720 macro_rules! bitxor_impl {
721     ($($t:ty)*) => ($(
722         #[stable(feature = "rust1", since = "1.0.0")]
723         impl BitXor for $t {
724             type Output = $t;
725
726             #[inline]
727             fn bitxor(self, other: $t) -> $t { self ^ other }
728         }
729
730         forward_ref_binop! { impl BitXor, bitxor for $t, $t }
731     )*)
732 }
733
734 bitxor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
735
736 /// The `Shl` trait is used to specify the functionality of `<<`.
737 ///
738 /// # Examples
739 ///
740 /// A trivial implementation of `Shl`. When `Foo << Foo` happens, it ends up
741 /// calling `shl`, and therefore, `main` prints `Shifting left!`.
742 ///
743 /// ```
744 /// use std::ops::Shl;
745 ///
746 /// #[derive(Copy, Clone)]
747 /// struct Foo;
748 ///
749 /// impl Shl<Foo> for Foo {
750 ///     type Output = Foo;
751 ///
752 ///     fn shl(self, _rhs: Foo) -> Foo {
753 ///         println!("Shifting left!");
754 ///         self
755 ///     }
756 /// }
757 ///
758 /// fn main() {
759 ///     Foo << Foo;
760 /// }
761 /// ```
762 #[lang="shl"]
763 #[stable(feature = "rust1", since = "1.0.0")]
764 pub trait Shl<RHS> {
765     /// The resulting type after applying the `<<` operator
766     #[stable(feature = "rust1", since = "1.0.0")]
767     type Output;
768
769     /// The method for the `<<` operator
770     #[stable(feature = "rust1", since = "1.0.0")]
771     fn shl(self, rhs: RHS) -> Self::Output;
772 }
773
774 macro_rules! shl_impl {
775     ($t:ty, $f:ty) => (
776         #[stable(feature = "rust1", since = "1.0.0")]
777         impl Shl<$f> for $t {
778             type Output = $t;
779
780             #[inline]
781             fn shl(self, other: $f) -> $t {
782                 self << other
783             }
784         }
785
786         forward_ref_binop! { impl Shl, shl for $t, $f }
787     )
788 }
789
790 macro_rules! shl_impl_all {
791     ($($t:ty)*) => ($(
792         shl_impl! { $t, u8 }
793         shl_impl! { $t, u16 }
794         shl_impl! { $t, u32 }
795         shl_impl! { $t, u64 }
796         shl_impl! { $t, usize }
797
798         shl_impl! { $t, i8 }
799         shl_impl! { $t, i16 }
800         shl_impl! { $t, i32 }
801         shl_impl! { $t, i64 }
802         shl_impl! { $t, isize }
803     )*)
804 }
805
806 shl_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
807
808 /// The `Shr` trait is used to specify the functionality of `>>`.
809 ///
810 /// # Examples
811 ///
812 /// A trivial implementation of `Shr`. When `Foo >> Foo` happens, it ends up
813 /// calling `shr`, and therefore, `main` prints `Shifting right!`.
814 ///
815 /// ```
816 /// use std::ops::Shr;
817 ///
818 /// #[derive(Copy, Clone)]
819 /// struct Foo;
820 ///
821 /// impl Shr<Foo> for Foo {
822 ///     type Output = Foo;
823 ///
824 ///     fn shr(self, _rhs: Foo) -> Foo {
825 ///         println!("Shifting right!");
826 ///         self
827 ///     }
828 /// }
829 ///
830 /// fn main() {
831 ///     Foo >> Foo;
832 /// }
833 /// ```
834 #[lang="shr"]
835 #[stable(feature = "rust1", since = "1.0.0")]
836 pub trait Shr<RHS> {
837     /// The resulting type after applying the `>>` operator
838     #[stable(feature = "rust1", since = "1.0.0")]
839     type Output;
840
841     /// The method for the `>>` operator
842     #[stable(feature = "rust1", since = "1.0.0")]
843     fn shr(self, rhs: RHS) -> Self::Output;
844 }
845
846 macro_rules! shr_impl {
847     ($t:ty, $f:ty) => (
848         impl Shr<$f> for $t {
849             type Output = $t;
850
851             #[inline]
852             fn shr(self, other: $f) -> $t {
853                 self >> other
854             }
855         }
856
857         forward_ref_binop! { impl Shr, shr for $t, $f }
858     )
859 }
860
861 macro_rules! shr_impl_all {
862     ($($t:ty)*) => ($(
863         shr_impl! { $t, u8 }
864         shr_impl! { $t, u16 }
865         shr_impl! { $t, u32 }
866         shr_impl! { $t, u64 }
867         shr_impl! { $t, usize }
868
869         shr_impl! { $t, i8 }
870         shr_impl! { $t, i16 }
871         shr_impl! { $t, i32 }
872         shr_impl! { $t, i64 }
873         shr_impl! { $t, isize }
874     )*)
875 }
876
877 shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
878
879 /// The `Index` trait is used to specify the functionality of indexing operations
880 /// like `arr[idx]` when used in an immutable context.
881 ///
882 /// # Examples
883 ///
884 /// A trivial implementation of `Index`. When `Foo[Bar]` happens, it ends up
885 /// calling `index`, and therefore, `main` prints `Indexing!`.
886 ///
887 /// ```
888 /// use std::ops::Index;
889 ///
890 /// #[derive(Copy, Clone)]
891 /// struct Foo;
892 /// struct Bar;
893 ///
894 /// impl Index<Bar> for Foo {
895 ///     type Output = Foo;
896 ///
897 ///     fn index<'a>(&'a self, _index: Bar) -> &'a Foo {
898 ///         println!("Indexing!");
899 ///         self
900 ///     }
901 /// }
902 ///
903 /// fn main() {
904 ///     Foo[Bar];
905 /// }
906 /// ```
907 #[lang="index"]
908 #[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
909 #[stable(feature = "rust1", since = "1.0.0")]
910 pub trait Index<Idx: ?Sized> {
911     /// The returned type after indexing
912     #[stable(feature = "rust1", since = "1.0.0")]
913     type Output: ?Sized;
914
915     /// The method for the indexing (`Foo[Bar]`) operation
916     #[stable(feature = "rust1", since = "1.0.0")]
917     fn index<'a>(&'a self, index: Idx) -> &'a Self::Output;
918 }
919
920 /// The `IndexMut` trait is used to specify the functionality of indexing
921 /// operations like `arr[idx]`, when used in a mutable context.
922 ///
923 /// # Examples
924 ///
925 /// A trivial implementation of `IndexMut`. When `Foo[Bar]` happens, it ends up
926 /// calling `index_mut`, and therefore, `main` prints `Indexing!`.
927 ///
928 /// ```
929 /// use std::ops::{Index, IndexMut};
930 ///
931 /// #[derive(Copy, Clone)]
932 /// struct Foo;
933 /// struct Bar;
934 ///
935 /// impl Index<Bar> for Foo {
936 ///     type Output = Foo;
937 ///
938 ///     fn index<'a>(&'a self, _index: Bar) -> &'a Foo {
939 ///         self
940 ///     }
941 /// }
942 ///
943 /// impl IndexMut<Bar> for Foo {
944 ///     fn index_mut<'a>(&'a mut self, _index: Bar) -> &'a mut Foo {
945 ///         println!("Indexing!");
946 ///         self
947 ///     }
948 /// }
949 ///
950 /// fn main() {
951 ///     &mut Foo[Bar];
952 /// }
953 /// ```
954 #[lang="index_mut"]
955 #[rustc_on_unimplemented = "the type `{Self}` cannot be mutably indexed by `{Idx}`"]
956 #[stable(feature = "rust1", since = "1.0.0")]
957 pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
958     /// The method for the indexing (`Foo[Bar]`) operation
959     #[stable(feature = "rust1", since = "1.0.0")]
960     fn index_mut<'a>(&'a mut self, index: Idx) -> &'a mut Self::Output;
961 }
962
963 /// An unbounded range.
964 #[derive(Copy, Clone, PartialEq, Eq)]
965 #[lang="range_full"]
966 #[stable(feature = "rust1", since = "1.0.0")]
967 pub struct RangeFull;
968
969 #[stable(feature = "rust1", since = "1.0.0")]
970 impl fmt::Debug for RangeFull {
971     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
972         fmt::Debug::fmt("..", fmt)
973     }
974 }
975
976 /// A (half-open) range which is bounded at both ends.
977 #[derive(Clone, PartialEq, Eq)]
978 #[lang="range"]
979 #[stable(feature = "rust1", since = "1.0.0")]
980 pub struct Range<Idx> {
981     /// The lower bound of the range (inclusive).
982     #[stable(feature = "rust1", since = "1.0.0")]
983     pub start: Idx,
984     /// The upper bound of the range (exclusive).
985     #[stable(feature = "rust1", since = "1.0.0")]
986     pub end: Idx,
987 }
988
989 #[stable(feature = "rust1", since = "1.0.0")]
990 impl<Idx: fmt::Debug> fmt::Debug for Range<Idx> {
991     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
992         write!(fmt, "{:?}..{:?}", self.start, self.end)
993     }
994 }
995
996 /// A range which is only bounded below.
997 #[derive(Clone, PartialEq, Eq)]
998 #[lang="range_from"]
999 #[stable(feature = "rust1", since = "1.0.0")]
1000 pub struct RangeFrom<Idx> {
1001     /// The lower bound of the range (inclusive).
1002     #[stable(feature = "rust1", since = "1.0.0")]
1003     pub start: Idx,
1004 }
1005
1006 #[stable(feature = "rust1", since = "1.0.0")]
1007 impl<Idx: fmt::Debug> fmt::Debug for RangeFrom<Idx> {
1008     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1009         write!(fmt, "{:?}..", self.start)
1010     }
1011 }
1012
1013 /// A range which is only bounded above.
1014 #[derive(Copy, Clone, PartialEq, Eq)]
1015 #[lang="range_to"]
1016 #[stable(feature = "rust1", since = "1.0.0")]
1017 pub struct RangeTo<Idx> {
1018     /// The upper bound of the range (exclusive).
1019     #[stable(feature = "rust1", since = "1.0.0")]
1020     pub end: Idx,
1021 }
1022
1023 #[stable(feature = "rust1", since = "1.0.0")]
1024 impl<Idx: fmt::Debug> fmt::Debug for RangeTo<Idx> {
1025     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1026         write!(fmt, "..{:?}", self.end)
1027     }
1028 }
1029
1030 /// The `Deref` trait is used to specify the functionality of dereferencing
1031 /// operations like `*v`.
1032 ///
1033 /// # Examples
1034 ///
1035 /// A struct with a single field which is accessible via dereferencing the
1036 /// struct.
1037 ///
1038 /// ```
1039 /// use std::ops::Deref;
1040 ///
1041 /// struct DerefExample<T> {
1042 ///     value: T
1043 /// }
1044 ///
1045 /// impl<T> Deref for DerefExample<T> {
1046 ///     type Target = T;
1047 ///
1048 ///     fn deref<'a>(&'a self) -> &'a T {
1049 ///         &self.value
1050 ///     }
1051 /// }
1052 ///
1053 /// fn main() {
1054 ///     let x = DerefExample { value: 'a' };
1055 ///     assert_eq!('a', *x);
1056 /// }
1057 /// ```
1058 #[lang="deref"]
1059 #[stable(feature = "rust1", since = "1.0.0")]
1060 pub trait Deref {
1061     /// The resulting type after dereferencing
1062     #[stable(feature = "rust1", since = "1.0.0")]
1063     type Target: ?Sized;
1064
1065     /// The method called to dereference a value
1066     #[stable(feature = "rust1", since = "1.0.0")]
1067     fn deref<'a>(&'a self) -> &'a Self::Target;
1068 }
1069
1070 #[stable(feature = "rust1", since = "1.0.0")]
1071 impl<'a, T: ?Sized> Deref for &'a T {
1072     type Target = T;
1073
1074     fn deref(&self) -> &T { *self }
1075 }
1076
1077 #[stable(feature = "rust1", since = "1.0.0")]
1078 impl<'a, T: ?Sized> Deref for &'a mut T {
1079     type Target = T;
1080
1081     fn deref(&self) -> &T { *self }
1082 }
1083
1084 /// The `DerefMut` trait is used to specify the functionality of dereferencing
1085 /// mutably like `*v = 1;`
1086 ///
1087 /// # Examples
1088 ///
1089 /// A struct with a single field which is modifiable via dereferencing the
1090 /// struct.
1091 ///
1092 /// ```
1093 /// use std::ops::{Deref, DerefMut};
1094 ///
1095 /// struct DerefMutExample<T> {
1096 ///     value: T
1097 /// }
1098 ///
1099 /// impl<T> Deref for DerefMutExample<T> {
1100 ///     type Target = T;
1101 ///
1102 ///     fn deref<'a>(&'a self) -> &'a T {
1103 ///         &self.value
1104 ///     }
1105 /// }
1106 ///
1107 /// impl<T> DerefMut for DerefMutExample<T> {
1108 ///     fn deref_mut<'a>(&'a mut self) -> &'a mut T {
1109 ///         &mut self.value
1110 ///     }
1111 /// }
1112 ///
1113 /// fn main() {
1114 ///     let mut x = DerefMutExample { value: 'a' };
1115 ///     *x = 'b';
1116 ///     assert_eq!('b', *x);
1117 /// }
1118 /// ```
1119 #[lang="deref_mut"]
1120 #[stable(feature = "rust1", since = "1.0.0")]
1121 pub trait DerefMut: Deref {
1122     /// The method called to mutably dereference a value
1123     #[stable(feature = "rust1", since = "1.0.0")]
1124     fn deref_mut<'a>(&'a mut self) -> &'a mut Self::Target;
1125 }
1126
1127 #[stable(feature = "rust1", since = "1.0.0")]
1128 impl<'a, T: ?Sized> DerefMut for &'a mut T {
1129     fn deref_mut(&mut self) -> &mut T { *self }
1130 }
1131
1132 /// A version of the call operator that takes an immutable receiver.
1133 #[lang="fn"]
1134 #[stable(feature = "rust1", since = "1.0.0")]
1135 #[rustc_paren_sugar]
1136 #[fundamental] // so that regex can rely that `&str: !FnMut`
1137 pub trait Fn<Args> : FnMut<Args> {
1138     /// This is called when the call operator is used.
1139     extern "rust-call" fn call(&self, args: Args) -> Self::Output;
1140 }
1141
1142 /// A version of the call operator that takes a mutable receiver.
1143 #[lang="fn_mut"]
1144 #[stable(feature = "rust1", since = "1.0.0")]
1145 #[rustc_paren_sugar]
1146 #[fundamental] // so that regex can rely that `&str: !FnMut`
1147 pub trait FnMut<Args> : FnOnce<Args> {
1148     /// This is called when the call operator is used.
1149     extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
1150 }
1151
1152 /// A version of the call operator that takes a by-value receiver.
1153 #[lang="fn_once"]
1154 #[stable(feature = "rust1", since = "1.0.0")]
1155 #[rustc_paren_sugar]
1156 #[fundamental] // so that regex can rely that `&str: !FnMut`
1157 pub trait FnOnce<Args> {
1158     /// The returned type after the call operator is used.
1159     type Output;
1160
1161     /// This is called when the call operator is used.
1162     extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
1163 }
1164
1165 #[cfg(not(stage0))]
1166 mod impls {
1167     use marker::Sized;
1168     use super::{Fn, FnMut, FnOnce};
1169
1170     impl<'a,A,F:?Sized> Fn<A> for &'a F
1171         where F : Fn<A>
1172     {
1173         extern "rust-call" fn call(&self, args: A) -> F::Output {
1174             (**self).call(args)
1175         }
1176     }
1177
1178     impl<'a,A,F:?Sized> FnMut<A> for &'a F
1179         where F : Fn<A>
1180     {
1181         extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
1182             (**self).call(args)
1183         }
1184     }
1185
1186     impl<'a,A,F:?Sized> FnOnce<A> for &'a F
1187         where F : Fn<A>
1188     {
1189         type Output = F::Output;
1190
1191         extern "rust-call" fn call_once(self, args: A) -> F::Output {
1192             (*self).call(args)
1193         }
1194     }
1195
1196     impl<'a,A,F:?Sized> FnMut<A> for &'a mut F
1197         where F : FnMut<A>
1198     {
1199         extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
1200             (*self).call_mut(args)
1201         }
1202     }
1203
1204     impl<'a,A,F:?Sized> FnOnce<A> for &'a mut F
1205         where F : FnMut<A>
1206     {
1207         type Output = F::Output;
1208         extern "rust-call" fn call_once(mut self, args: A) -> F::Output {
1209             (*self).call_mut(args)
1210         }
1211     }
1212 }