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