]> git.lizzy.rs Git - rust.git/blob - src/libcore/ops.rs
Rollup merge of #23788 - steveklabnik:gh23748, 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)]
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)]
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)]
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)]
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)]
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)]
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 macro_rules! neg_impl {
486     ($($t:ty)*) => ($(
487         #[stable(feature = "rust1", since = "1.0.0")]
488         impl Neg for $t {
489             #[stable(feature = "rust1", since = "1.0.0")]
490             type Output = $t;
491
492             #[inline]
493             #[stable(feature = "rust1", since = "1.0.0")]
494             fn neg(self) -> $t { -self }
495         }
496
497         forward_ref_unop! { impl Neg, neg for $t }
498     )*)
499 }
500
501 macro_rules! neg_uint_impl {
502     ($t:ty, $t_signed:ty) => {
503         #[stable(feature = "rust1", since = "1.0.0")]
504         impl Neg for $t {
505             type Output = $t;
506
507             #[inline]
508             fn neg(self) -> $t { -(self as $t_signed) as $t }
509         }
510
511         forward_ref_unop! { impl Neg, neg for $t }
512     }
513 }
514
515 neg_impl! { isize i8 i16 i32 i64 f32 f64 }
516
517 neg_uint_impl! { usize, isize }
518 neg_uint_impl! { u8, i8 }
519 neg_uint_impl! { u16, i16 }
520 neg_uint_impl! { u32, i32 }
521 neg_uint_impl! { u64, i64 }
522
523
524 /// The `Not` trait is used to specify the functionality of unary `!`.
525 ///
526 /// # Examples
527 ///
528 /// A trivial implementation of `Not`. When `!Foo` happens, it ends up calling
529 /// `not`, and therefore, `main` prints `Not-ing!`.
530 ///
531 /// ```
532 /// use std::ops::Not;
533 ///
534 /// #[derive(Copy)]
535 /// struct Foo;
536 ///
537 /// impl Not for Foo {
538 ///     type Output = Foo;
539 ///
540 ///     fn not(self) -> Foo {
541 ///         println!("Not-ing!");
542 ///         self
543 ///     }
544 /// }
545 ///
546 /// fn main() {
547 ///     !Foo;
548 /// }
549 /// ```
550 #[lang="not"]
551 #[stable(feature = "rust1", since = "1.0.0")]
552 pub trait Not {
553     /// The resulting type after applying the `!` operator
554     #[stable(feature = "rust1", since = "1.0.0")]
555     type Output;
556
557     /// The method for the unary `!` operator
558     #[stable(feature = "rust1", since = "1.0.0")]
559     fn not(self) -> Self::Output;
560 }
561
562 macro_rules! not_impl {
563     ($($t:ty)*) => ($(
564         #[stable(feature = "rust1", since = "1.0.0")]
565         impl Not for $t {
566             type Output = $t;
567
568             #[inline]
569             fn not(self) -> $t { !self }
570         }
571
572         forward_ref_unop! { impl Not, not for $t }
573     )*)
574 }
575
576 not_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
577
578 /// The `BitAnd` trait is used to specify the functionality of `&`.
579 ///
580 /// # Examples
581 ///
582 /// A trivial implementation of `BitAnd`. When `Foo & Foo` happens, it ends up
583 /// calling `bitand`, and therefore, `main` prints `Bitwise And-ing!`.
584 ///
585 /// ```
586 /// use std::ops::BitAnd;
587 ///
588 /// #[derive(Copy)]
589 /// struct Foo;
590 ///
591 /// impl BitAnd for Foo {
592 ///     type Output = Foo;
593 ///
594 ///     fn bitand(self, _rhs: Foo) -> Foo {
595 ///         println!("Bitwise And-ing!");
596 ///         self
597 ///     }
598 /// }
599 ///
600 /// fn main() {
601 ///     Foo & Foo;
602 /// }
603 /// ```
604 #[lang="bitand"]
605 #[stable(feature = "rust1", since = "1.0.0")]
606 pub trait BitAnd<RHS=Self> {
607     /// The resulting type after applying the `&` operator
608     #[stable(feature = "rust1", since = "1.0.0")]
609     type Output;
610
611     /// The method for the `&` operator
612     #[stable(feature = "rust1", since = "1.0.0")]
613     fn bitand(self, rhs: RHS) -> Self::Output;
614 }
615
616 macro_rules! bitand_impl {
617     ($($t:ty)*) => ($(
618         #[stable(feature = "rust1", since = "1.0.0")]
619         impl BitAnd for $t {
620             type Output = $t;
621
622             #[inline]
623             fn bitand(self, rhs: $t) -> $t { self & rhs }
624         }
625
626         forward_ref_binop! { impl BitAnd, bitand for $t, $t }
627     )*)
628 }
629
630 bitand_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
631
632 /// The `BitOr` trait is used to specify the functionality of `|`.
633 ///
634 /// # Examples
635 ///
636 /// A trivial implementation of `BitOr`. When `Foo | Foo` happens, it ends up
637 /// calling `bitor`, and therefore, `main` prints `Bitwise Or-ing!`.
638 ///
639 /// ```
640 /// use std::ops::BitOr;
641 ///
642 /// #[derive(Copy)]
643 /// struct Foo;
644 ///
645 /// impl BitOr for Foo {
646 ///     type Output = Foo;
647 ///
648 ///     fn bitor(self, _rhs: Foo) -> Foo {
649 ///         println!("Bitwise Or-ing!");
650 ///         self
651 ///     }
652 /// }
653 ///
654 /// fn main() {
655 ///     Foo | Foo;
656 /// }
657 /// ```
658 #[lang="bitor"]
659 #[stable(feature = "rust1", since = "1.0.0")]
660 pub trait BitOr<RHS=Self> {
661     /// The resulting type after applying the `|` operator
662     #[stable(feature = "rust1", since = "1.0.0")]
663     type Output;
664
665     /// The method for the `|` operator
666     #[stable(feature = "rust1", since = "1.0.0")]
667     fn bitor(self, rhs: RHS) -> Self::Output;
668 }
669
670 macro_rules! bitor_impl {
671     ($($t:ty)*) => ($(
672         #[stable(feature = "rust1", since = "1.0.0")]
673         impl BitOr for $t {
674             type Output = $t;
675
676             #[inline]
677             fn bitor(self, rhs: $t) -> $t { self | rhs }
678         }
679
680         forward_ref_binop! { impl BitOr, bitor for $t, $t }
681     )*)
682 }
683
684 bitor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
685
686 /// The `BitXor` trait is used to specify the functionality of `^`.
687 ///
688 /// # Examples
689 ///
690 /// A trivial implementation of `BitXor`. When `Foo ^ Foo` happens, it ends up
691 /// calling `bitxor`, and therefore, `main` prints `Bitwise Xor-ing!`.
692 ///
693 /// ```
694 /// use std::ops::BitXor;
695 ///
696 /// #[derive(Copy)]
697 /// struct Foo;
698 ///
699 /// impl BitXor for Foo {
700 ///     type Output = Foo;
701 ///
702 ///     fn bitxor(self, _rhs: Foo) -> Foo {
703 ///         println!("Bitwise Xor-ing!");
704 ///         self
705 ///     }
706 /// }
707 ///
708 /// fn main() {
709 ///     Foo ^ Foo;
710 /// }
711 /// ```
712 #[lang="bitxor"]
713 #[stable(feature = "rust1", since = "1.0.0")]
714 pub trait BitXor<RHS=Self> {
715     /// The resulting type after applying the `^` operator
716     #[stable(feature = "rust1", since = "1.0.0")]
717     type Output;
718
719     /// The method for the `^` operator
720     #[stable(feature = "rust1", since = "1.0.0")]
721     fn bitxor(self, rhs: RHS) -> Self::Output;
722 }
723
724 macro_rules! bitxor_impl {
725     ($($t:ty)*) => ($(
726         #[stable(feature = "rust1", since = "1.0.0")]
727         impl BitXor for $t {
728             type Output = $t;
729
730             #[inline]
731             fn bitxor(self, other: $t) -> $t { self ^ other }
732         }
733
734         forward_ref_binop! { impl BitXor, bitxor for $t, $t }
735     )*)
736 }
737
738 bitxor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
739
740 /// The `Shl` trait is used to specify the functionality of `<<`.
741 ///
742 /// # Examples
743 ///
744 /// A trivial implementation of `Shl`. When `Foo << Foo` happens, it ends up
745 /// calling `shl`, and therefore, `main` prints `Shifting left!`.
746 ///
747 /// ```
748 /// use std::ops::Shl;
749 ///
750 /// #[derive(Copy)]
751 /// struct Foo;
752 ///
753 /// impl Shl<Foo> for Foo {
754 ///     type Output = Foo;
755 ///
756 ///     fn shl(self, _rhs: Foo) -> Foo {
757 ///         println!("Shifting left!");
758 ///         self
759 ///     }
760 /// }
761 ///
762 /// fn main() {
763 ///     Foo << Foo;
764 /// }
765 /// ```
766 #[lang="shl"]
767 #[stable(feature = "rust1", since = "1.0.0")]
768 pub trait Shl<RHS> {
769     /// The resulting type after applying the `<<` operator
770     #[stable(feature = "rust1", since = "1.0.0")]
771     type Output;
772
773     /// The method for the `<<` operator
774     #[stable(feature = "rust1", since = "1.0.0")]
775     fn shl(self, rhs: RHS) -> Self::Output;
776 }
777
778 macro_rules! shl_impl {
779     ($t:ty, $f:ty) => (
780         #[stable(feature = "rust1", since = "1.0.0")]
781         impl Shl<$f> for $t {
782             type Output = $t;
783
784             #[inline]
785             fn shl(self, other: $f) -> $t {
786                 self << other
787             }
788         }
789
790         forward_ref_binop! { impl Shl, shl for $t, $f }
791     )
792 }
793
794 macro_rules! shl_impl_all {
795     ($($t:ty)*) => ($(
796         shl_impl! { $t, u8 }
797         shl_impl! { $t, u16 }
798         shl_impl! { $t, u32 }
799         shl_impl! { $t, u64 }
800         shl_impl! { $t, usize }
801
802         shl_impl! { $t, i8 }
803         shl_impl! { $t, i16 }
804         shl_impl! { $t, i32 }
805         shl_impl! { $t, i64 }
806         shl_impl! { $t, isize }
807     )*)
808 }
809
810 shl_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
811
812 /// The `Shr` trait is used to specify the functionality of `>>`.
813 ///
814 /// # Examples
815 ///
816 /// A trivial implementation of `Shr`. When `Foo >> Foo` happens, it ends up
817 /// calling `shr`, and therefore, `main` prints `Shifting right!`.
818 ///
819 /// ```
820 /// use std::ops::Shr;
821 ///
822 /// #[derive(Copy)]
823 /// struct Foo;
824 ///
825 /// impl Shr<Foo> for Foo {
826 ///     type Output = Foo;
827 ///
828 ///     fn shr(self, _rhs: Foo) -> Foo {
829 ///         println!("Shifting right!");
830 ///         self
831 ///     }
832 /// }
833 ///
834 /// fn main() {
835 ///     Foo >> Foo;
836 /// }
837 /// ```
838 #[lang="shr"]
839 #[stable(feature = "rust1", since = "1.0.0")]
840 pub trait Shr<RHS> {
841     /// The resulting type after applying the `>>` operator
842     #[stable(feature = "rust1", since = "1.0.0")]
843     type Output;
844
845     /// The method for the `>>` operator
846     #[stable(feature = "rust1", since = "1.0.0")]
847     fn shr(self, rhs: RHS) -> Self::Output;
848 }
849
850 macro_rules! shr_impl {
851     ($t:ty, $f:ty) => (
852         impl Shr<$f> for $t {
853             type Output = $t;
854
855             #[inline]
856             fn shr(self, other: $f) -> $t {
857                 self >> other
858             }
859         }
860
861         forward_ref_binop! { impl Shr, shr for $t, $f }
862     )
863 }
864
865 macro_rules! shr_impl_all {
866     ($($t:ty)*) => ($(
867         shr_impl! { $t, u8 }
868         shr_impl! { $t, u16 }
869         shr_impl! { $t, u32 }
870         shr_impl! { $t, u64 }
871         shr_impl! { $t, usize }
872
873         shr_impl! { $t, i8 }
874         shr_impl! { $t, i16 }
875         shr_impl! { $t, i32 }
876         shr_impl! { $t, i64 }
877         shr_impl! { $t, isize }
878     )*)
879 }
880
881 shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
882
883 /// The `Index` trait is used to specify the functionality of indexing operations
884 /// like `arr[idx]` when used in an immutable context.
885 ///
886 /// # Examples
887 ///
888 /// A trivial implementation of `Index`. When `Foo[Bar]` happens, it ends up
889 /// calling `index`, and therefore, `main` prints `Indexing!`.
890 ///
891 /// ```
892 /// use std::ops::Index;
893 ///
894 /// #[derive(Copy)]
895 /// struct Foo;
896 /// struct Bar;
897 ///
898 /// impl Index<Bar> for Foo {
899 ///     type Output = Foo;
900 ///
901 ///     fn index<'a>(&'a self, _index: Bar) -> &'a Foo {
902 ///         println!("Indexing!");
903 ///         self
904 ///     }
905 /// }
906 ///
907 /// fn main() {
908 ///     Foo[Bar];
909 /// }
910 /// ```
911 #[lang="index"]
912 #[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
913 #[stable(feature = "rust1", since = "1.0.0")]
914 pub trait Index<Idx: ?Sized> {
915     /// The returned type after indexing
916     #[stable(feature = "rust1", since = "1.0.0")]
917     type Output: ?Sized;
918
919     /// The method for the indexing (`Foo[Bar]`) operation
920     #[stable(feature = "rust1", since = "1.0.0")]
921     fn index<'a>(&'a self, index: Idx) -> &'a Self::Output;
922 }
923
924 /// The `IndexMut` trait is used to specify the functionality of indexing
925 /// operations like `arr[idx]`, when used in a mutable context.
926 ///
927 /// # Examples
928 ///
929 /// A trivial implementation of `IndexMut`. When `Foo[Bar]` happens, it ends up
930 /// calling `index_mut`, and therefore, `main` prints `Indexing!`.
931 ///
932 /// ```
933 /// use std::ops::{Index, IndexMut};
934 ///
935 /// #[derive(Copy)]
936 /// struct Foo;
937 /// struct Bar;
938 ///
939 /// impl Index<Bar> for Foo {
940 ///     type Output = Foo;
941 ///
942 ///     fn index<'a>(&'a self, _index: Bar) -> &'a Foo {
943 ///         self
944 ///     }
945 /// }
946 ///
947 /// impl IndexMut<Bar> for Foo {
948 ///     fn index_mut<'a>(&'a mut self, _index: Bar) -> &'a mut Foo {
949 ///         println!("Indexing!");
950 ///         self
951 ///     }
952 /// }
953 ///
954 /// fn main() {
955 ///     &mut Foo[Bar];
956 /// }
957 /// ```
958 #[lang="index_mut"]
959 #[rustc_on_unimplemented = "the type `{Self}` cannot be mutably indexed by `{Idx}`"]
960 #[stable(feature = "rust1", since = "1.0.0")]
961 pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
962     /// The method for the indexing (`Foo[Bar]`) operation
963     #[stable(feature = "rust1", since = "1.0.0")]
964     fn index_mut<'a>(&'a mut self, index: Idx) -> &'a mut Self::Output;
965 }
966
967 /// An unbounded range.
968 #[derive(Copy, Clone, PartialEq, Eq)]
969 #[lang="range_full"]
970 #[stable(feature = "rust1", since = "1.0.0")]
971 pub struct RangeFull;
972
973 #[stable(feature = "rust1", since = "1.0.0")]
974 impl fmt::Debug for RangeFull {
975     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
976         fmt::Debug::fmt("..", fmt)
977     }
978 }
979
980 /// A (half-open) range which is bounded at both ends.
981 #[derive(Clone, PartialEq, Eq)]
982 #[lang="range"]
983 #[stable(feature = "rust1", since = "1.0.0")]
984 pub struct Range<Idx> {
985     /// The lower bound of the range (inclusive).
986     #[stable(feature = "rust1", since = "1.0.0")]
987     pub start: Idx,
988     /// The upper bound of the range (exclusive).
989     #[stable(feature = "rust1", since = "1.0.0")]
990     pub end: Idx,
991 }
992
993 #[stable(feature = "rust1", since = "1.0.0")]
994 impl<Idx: fmt::Debug> fmt::Debug for Range<Idx> {
995     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
996         write!(fmt, "{:?}..{:?}", self.start, self.end)
997     }
998 }
999
1000 /// A range which is only bounded below.
1001 #[derive(Clone, PartialEq, Eq)]
1002 #[lang="range_from"]
1003 #[stable(feature = "rust1", since = "1.0.0")]
1004 pub struct RangeFrom<Idx> {
1005     /// The lower bound of the range (inclusive).
1006     #[stable(feature = "rust1", since = "1.0.0")]
1007     pub start: Idx,
1008 }
1009
1010 #[stable(feature = "rust1", since = "1.0.0")]
1011 impl<Idx: fmt::Debug> fmt::Debug for RangeFrom<Idx> {
1012     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1013         write!(fmt, "{:?}..", self.start)
1014     }
1015 }
1016
1017 /// A range which is only bounded above.
1018 #[derive(Copy, Clone, PartialEq, Eq)]
1019 #[lang="range_to"]
1020 #[stable(feature = "rust1", since = "1.0.0")]
1021 pub struct RangeTo<Idx> {
1022     /// The upper bound of the range (exclusive).
1023     #[stable(feature = "rust1", since = "1.0.0")]
1024     pub end: Idx,
1025 }
1026
1027 #[stable(feature = "rust1", since = "1.0.0")]
1028 impl<Idx: fmt::Debug> fmt::Debug for RangeTo<Idx> {
1029     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1030         write!(fmt, "..{:?}", self.end)
1031     }
1032 }
1033
1034 /// The `Deref` trait is used to specify the functionality of dereferencing
1035 /// operations like `*v`.
1036 ///
1037 /// # Examples
1038 ///
1039 /// A struct with a single field which is accessible via dereferencing the
1040 /// struct.
1041 ///
1042 /// ```
1043 /// use std::ops::Deref;
1044 ///
1045 /// struct DerefExample<T> {
1046 ///     value: T
1047 /// }
1048 ///
1049 /// impl<T> Deref for DerefExample<T> {
1050 ///     type Target = T;
1051 ///
1052 ///     fn deref<'a>(&'a self) -> &'a T {
1053 ///         &self.value
1054 ///     }
1055 /// }
1056 ///
1057 /// fn main() {
1058 ///     let x = DerefExample { value: 'a' };
1059 ///     assert_eq!('a', *x);
1060 /// }
1061 /// ```
1062 #[lang="deref"]
1063 #[stable(feature = "rust1", since = "1.0.0")]
1064 pub trait Deref {
1065     /// The resulting type after dereferencing
1066     #[stable(feature = "rust1", since = "1.0.0")]
1067     type Target: ?Sized;
1068
1069     /// The method called to dereference a value
1070     #[stable(feature = "rust1", since = "1.0.0")]
1071     fn deref<'a>(&'a self) -> &'a Self::Target;
1072 }
1073
1074 #[stable(feature = "rust1", since = "1.0.0")]
1075 impl<'a, T: ?Sized> Deref for &'a T {
1076     type Target = T;
1077
1078     fn deref(&self) -> &T { *self }
1079 }
1080
1081 #[stable(feature = "rust1", since = "1.0.0")]
1082 impl<'a, T: ?Sized> Deref for &'a mut T {
1083     type Target = T;
1084
1085     fn deref(&self) -> &T { *self }
1086 }
1087
1088 /// The `DerefMut` trait is used to specify the functionality of dereferencing
1089 /// mutably like `*v = 1;`
1090 ///
1091 /// # Examples
1092 ///
1093 /// A struct with a single field which is modifiable via dereferencing the
1094 /// struct.
1095 ///
1096 /// ```
1097 /// use std::ops::{Deref, DerefMut};
1098 ///
1099 /// struct DerefMutExample<T> {
1100 ///     value: T
1101 /// }
1102 ///
1103 /// impl<T> Deref for DerefMutExample<T> {
1104 ///     type Target = T;
1105 ///
1106 ///     fn deref<'a>(&'a self) -> &'a T {
1107 ///         &self.value
1108 ///     }
1109 /// }
1110 ///
1111 /// impl<T> DerefMut for DerefMutExample<T> {
1112 ///     fn deref_mut<'a>(&'a mut self) -> &'a mut T {
1113 ///         &mut self.value
1114 ///     }
1115 /// }
1116 ///
1117 /// fn main() {
1118 ///     let mut x = DerefMutExample { value: 'a' };
1119 ///     *x = 'b';
1120 ///     assert_eq!('b', *x);
1121 /// }
1122 /// ```
1123 #[lang="deref_mut"]
1124 #[stable(feature = "rust1", since = "1.0.0")]
1125 pub trait DerefMut: Deref {
1126     /// The method called to mutably dereference a value
1127     #[stable(feature = "rust1", since = "1.0.0")]
1128     fn deref_mut<'a>(&'a mut self) -> &'a mut Self::Target;
1129 }
1130
1131 #[stable(feature = "rust1", since = "1.0.0")]
1132 impl<'a, T: ?Sized> DerefMut for &'a mut T {
1133     fn deref_mut(&mut self) -> &mut T { *self }
1134 }
1135
1136 /// A version of the call operator that takes an immutable receiver.
1137 #[lang="fn"]
1138 #[stable(feature = "rust1", since = "1.0.0")]
1139 #[rustc_paren_sugar]
1140 pub trait Fn<Args> : FnMut<Args> {
1141     /// This is called when the call operator is used.
1142     extern "rust-call" fn call(&self, args: Args) -> Self::Output;
1143 }
1144
1145 /// A version of the call operator that takes a mutable receiver.
1146 #[lang="fn_mut"]
1147 #[stable(feature = "rust1", since = "1.0.0")]
1148 #[rustc_paren_sugar]
1149 pub trait FnMut<Args> : FnOnce<Args> {
1150     /// This is called when the call operator is used.
1151     extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
1152 }
1153
1154 /// A version of the call operator that takes a by-value receiver.
1155 #[lang="fn_once"]
1156 #[stable(feature = "rust1", since = "1.0.0")]
1157 #[rustc_paren_sugar]
1158 pub trait FnOnce<Args> {
1159     /// The returned type after the call operator is used.
1160     type Output;
1161
1162     /// This is called when the call operator is used.
1163     extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
1164 }