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