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