]> git.proxmox.com Git - rustc.git/blame - src/libcore/ops.rs
Imported Upstream version 1.9.0+dfsg1
[rustc.git] / src / libcore / ops.rs
CommitLineData
1a4d82fc
JJ
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
54a0048b 11//! Overloadable operators.
1a4d82fc
JJ
12//!
13//! Implementing these traits allows you to get an effect similar to
14//! overloading operators.
15//!
85aaf69f 16//! Some of these traits are imported by the prelude, so they are available in
1a4d82fc
JJ
17//! every Rust program.
18//!
85aaf69f
SL
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//!
c34b1796 30//! # Examples
1a4d82fc 31//!
62682a34
SL
32//! This example creates a `Point` struct that implements `Add` and `Sub`, and
33//! then demonstrates adding and subtracting two `Point`s.
1a4d82fc
JJ
34//!
35//! ```rust
1a4d82fc
JJ
36//! use std::ops::{Add, Sub};
37//!
85aaf69f 38//! #[derive(Debug)]
1a4d82fc 39//! struct Point {
85aaf69f 40//! x: i32,
9cc50fc6 41//! y: i32,
1a4d82fc
JJ
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//!
62682a34
SL
65//! See the documentation for each trait for a minimum implementation that
66//! prints something to the screen.
1a4d82fc 67
85aaf69f 68#![stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 69
54a0048b 70use cmp::PartialOrd;
1a4d82fc 71use fmt;
54a0048b
SL
72use convert::From;
73use marker::{Sized, Unsize};
74use num::One;
1a4d82fc 75
62682a34
SL
76/// The `Drop` trait is used to run some code when a value goes out of scope.
77/// This is sometimes called a 'destructor'.
1a4d82fc 78///
c34b1796 79/// # Examples
1a4d82fc 80///
62682a34
SL
81/// A trivial implementation of `Drop`. The `drop` method is called when `_x`
82/// goes out of scope, and therefore `main` prints `Dropping!`.
1a4d82fc 83///
c34b1796 84/// ```
1a4d82fc
JJ
85/// struct HasDrop;
86///
87/// impl Drop for HasDrop {
88/// fn drop(&mut self) {
89/// println!("Dropping!");
90/// }
91/// }
92///
93/// fn main() {
94/// let _x = HasDrop;
95/// }
96/// ```
d9579d0f 97#[lang = "drop"]
85aaf69f 98#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 99pub trait Drop {
b039eaaf 100 /// A method called when the value goes out of scope.
9cc50fc6
SL
101 ///
102 /// When this method has been called, `self` has not yet been deallocated.
103 /// If it were, `self` would be a dangling reference.
104 ///
105 /// After this function is over, the memory of `self` will be deallocated.
106 ///
107 /// # Panics
108 ///
109 /// Given that a `panic!` will call `drop()` as it unwinds, any `panic!` in
110 /// a `drop()` implementation will likely abort.
85aaf69f 111 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
112 fn drop(&mut self);
113}
114
85aaf69f
SL
115// implements the unary operator "op &T"
116// based on "op T" where T is expected to be `Copy`able
117macro_rules! forward_ref_unop {
118 (impl $imp:ident, $method:ident for $t:ty) => {
62682a34 119 #[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
120 impl<'a> $imp for &'a $t {
121 type Output = <$t as $imp>::Output;
122
123 #[inline]
124 fn $method(self) -> <$t as $imp>::Output {
125 $imp::$method(*self)
126 }
127 }
128 }
129}
130
131// implements binary operators "&T op U", "T op &U", "&T op &U"
132// based on "T op U" where T and U are expected to be `Copy`able
133macro_rules! forward_ref_binop {
134 (impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
62682a34 135 #[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
136 impl<'a> $imp<$u> for &'a $t {
137 type Output = <$t as $imp<$u>>::Output;
138
139 #[inline]
140 fn $method(self, other: $u) -> <$t as $imp<$u>>::Output {
141 $imp::$method(*self, other)
142 }
143 }
144
62682a34 145 #[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
146 impl<'a> $imp<&'a $u> for $t {
147 type Output = <$t as $imp<$u>>::Output;
148
149 #[inline]
150 fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
151 $imp::$method(self, *other)
152 }
153 }
154
62682a34 155 #[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
156 impl<'a, 'b> $imp<&'a $u> for &'b $t {
157 type Output = <$t as $imp<$u>>::Output;
158
159 #[inline]
160 fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
161 $imp::$method(*self, *other)
162 }
163 }
164 }
165}
166
1a4d82fc
JJ
167/// The `Add` trait is used to specify the functionality of `+`.
168///
c34b1796 169/// # Examples
1a4d82fc
JJ
170///
171/// A trivial implementation of `Add`. When `Foo + Foo` happens, it ends up
172/// calling `add`, and therefore, `main` prints `Adding!`.
173///
c34b1796 174/// ```
1a4d82fc
JJ
175/// use std::ops::Add;
176///
1a4d82fc
JJ
177/// struct Foo;
178///
179/// impl Add for Foo {
180/// type Output = Foo;
181///
182/// fn add(self, _rhs: Foo) -> Foo {
9346a6ac
AL
183/// println!("Adding!");
184/// self
185/// }
1a4d82fc
JJ
186/// }
187///
188/// fn main() {
9346a6ac 189/// Foo + Foo;
1a4d82fc
JJ
190/// }
191/// ```
d9579d0f 192#[lang = "add"]
85aaf69f 193#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 194pub trait Add<RHS=Self> {
c34b1796 195 /// The resulting type after applying the `+` operator
85aaf69f 196 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
197 type Output;
198
199 /// The method for the `+` operator
85aaf69f 200 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
201 fn add(self, rhs: RHS) -> Self::Output;
202}
203
204macro_rules! add_impl {
205 ($($t:ty)*) => ($(
85aaf69f 206 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
207 impl Add for $t {
208 type Output = $t;
209
210 #[inline]
211 fn add(self, other: $t) -> $t { self + other }
212 }
85aaf69f
SL
213
214 forward_ref_binop! { impl Add, add for $t, $t }
1a4d82fc
JJ
215 )*)
216}
217
85aaf69f 218add_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
1a4d82fc
JJ
219
220/// The `Sub` trait is used to specify the functionality of `-`.
221///
c34b1796 222/// # Examples
1a4d82fc
JJ
223///
224/// A trivial implementation of `Sub`. When `Foo - Foo` happens, it ends up
225/// calling `sub`, and therefore, `main` prints `Subtracting!`.
226///
c34b1796 227/// ```
1a4d82fc
JJ
228/// use std::ops::Sub;
229///
1a4d82fc
JJ
230/// struct Foo;
231///
232/// impl Sub for Foo {
233/// type Output = Foo;
234///
235/// fn sub(self, _rhs: Foo) -> Foo {
236/// println!("Subtracting!");
237/// self
238/// }
239/// }
240///
241/// fn main() {
242/// Foo - Foo;
243/// }
244/// ```
d9579d0f 245#[lang = "sub"]
85aaf69f 246#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 247pub trait Sub<RHS=Self> {
c34b1796 248 /// The resulting type after applying the `-` operator
85aaf69f 249 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
250 type Output;
251
252 /// The method for the `-` operator
85aaf69f 253 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
254 fn sub(self, rhs: RHS) -> Self::Output;
255}
256
257macro_rules! sub_impl {
258 ($($t:ty)*) => ($(
85aaf69f 259 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
260 impl Sub for $t {
261 type Output = $t;
262
263 #[inline]
264 fn sub(self, other: $t) -> $t { self - other }
265 }
85aaf69f
SL
266
267 forward_ref_binop! { impl Sub, sub for $t, $t }
1a4d82fc
JJ
268 )*)
269}
270
85aaf69f 271sub_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
1a4d82fc
JJ
272
273/// The `Mul` trait is used to specify the functionality of `*`.
274///
c34b1796 275/// # Examples
1a4d82fc
JJ
276///
277/// A trivial implementation of `Mul`. When `Foo * Foo` happens, it ends up
278/// calling `mul`, and therefore, `main` prints `Multiplying!`.
279///
c34b1796 280/// ```
1a4d82fc
JJ
281/// use std::ops::Mul;
282///
1a4d82fc
JJ
283/// struct Foo;
284///
285/// impl Mul for Foo {
286/// type Output = Foo;
287///
288/// fn mul(self, _rhs: Foo) -> Foo {
289/// println!("Multiplying!");
290/// self
291/// }
292/// }
293///
294/// fn main() {
295/// Foo * Foo;
296/// }
297/// ```
d9579d0f 298#[lang = "mul"]
85aaf69f 299#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 300pub trait Mul<RHS=Self> {
c34b1796 301 /// The resulting type after applying the `*` operator
85aaf69f 302 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
303 type Output;
304
305 /// The method for the `*` operator
85aaf69f 306 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
307 fn mul(self, rhs: RHS) -> Self::Output;
308}
309
310macro_rules! mul_impl {
311 ($($t:ty)*) => ($(
85aaf69f 312 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
313 impl Mul for $t {
314 type Output = $t;
315
316 #[inline]
317 fn mul(self, other: $t) -> $t { self * other }
318 }
85aaf69f
SL
319
320 forward_ref_binop! { impl Mul, mul for $t, $t }
1a4d82fc
JJ
321 )*)
322}
323
85aaf69f 324mul_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
1a4d82fc
JJ
325
326/// The `Div` trait is used to specify the functionality of `/`.
327///
c34b1796 328/// # Examples
1a4d82fc
JJ
329///
330/// A trivial implementation of `Div`. When `Foo / Foo` happens, it ends up
331/// calling `div`, and therefore, `main` prints `Dividing!`.
332///
333/// ```
1a4d82fc
JJ
334/// use std::ops::Div;
335///
1a4d82fc
JJ
336/// struct Foo;
337///
338/// impl Div for Foo {
339/// type Output = Foo;
340///
341/// fn div(self, _rhs: Foo) -> Foo {
342/// println!("Dividing!");
343/// self
344/// }
345/// }
346///
347/// fn main() {
348/// Foo / Foo;
349/// }
350/// ```
d9579d0f 351#[lang = "div"]
85aaf69f 352#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 353pub trait Div<RHS=Self> {
c34b1796 354 /// The resulting type after applying the `/` operator
85aaf69f 355 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
356 type Output;
357
358 /// The method for the `/` operator
85aaf69f 359 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
360 fn div(self, rhs: RHS) -> Self::Output;
361}
362
c1a9b12d 363macro_rules! div_impl_integer {
1a4d82fc 364 ($($t:ty)*) => ($(
c1a9b12d
SL
365 /// This operation rounds towards zero, truncating any
366 /// fractional part of the exact result.
85aaf69f 367 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
368 impl Div for $t {
369 type Output = $t;
370
371 #[inline]
372 fn div(self, other: $t) -> $t { self / other }
373 }
85aaf69f
SL
374
375 forward_ref_binop! { impl Div, div for $t, $t }
1a4d82fc
JJ
376 )*)
377}
378
c1a9b12d
SL
379div_impl_integer! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
380
381macro_rules! div_impl_float {
382 ($($t:ty)*) => ($(
383 #[stable(feature = "rust1", since = "1.0.0")]
384 impl Div for $t {
385 type Output = $t;
386
387 #[inline]
388 fn div(self, other: $t) -> $t { self / other }
389 }
390
391 forward_ref_binop! { impl Div, div for $t, $t }
392 )*)
393}
394
395div_impl_float! { f32 f64 }
1a4d82fc
JJ
396
397/// The `Rem` trait is used to specify the functionality of `%`.
398///
c34b1796 399/// # Examples
1a4d82fc
JJ
400///
401/// A trivial implementation of `Rem`. When `Foo % Foo` happens, it ends up
402/// calling `rem`, and therefore, `main` prints `Remainder-ing!`.
403///
404/// ```
1a4d82fc
JJ
405/// use std::ops::Rem;
406///
1a4d82fc
JJ
407/// struct Foo;
408///
409/// impl Rem for Foo {
410/// type Output = Foo;
411///
412/// fn rem(self, _rhs: Foo) -> Foo {
413/// println!("Remainder-ing!");
414/// self
415/// }
416/// }
417///
418/// fn main() {
419/// Foo % Foo;
420/// }
421/// ```
d9579d0f 422#[lang = "rem"]
85aaf69f 423#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 424pub trait Rem<RHS=Self> {
c34b1796 425 /// The resulting type after applying the `%` operator
85aaf69f 426 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
427 type Output = Self;
428
429 /// The method for the `%` operator
85aaf69f 430 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
431 fn rem(self, rhs: RHS) -> Self::Output;
432}
433
e9174d1e 434macro_rules! rem_impl_integer {
1a4d82fc 435 ($($t:ty)*) => ($(
c1a9b12d
SL
436 /// This operation satisfies `n % d == n - (n / d) * d`. The
437 /// result has the same sign as the left operand.
85aaf69f 438 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
439 impl Rem for $t {
440 type Output = $t;
441
442 #[inline]
443 fn rem(self, other: $t) -> $t { self % other }
444 }
85aaf69f
SL
445
446 forward_ref_binop! { impl Rem, rem for $t, $t }
1a4d82fc
JJ
447 )*)
448}
449
e9174d1e
SL
450rem_impl_integer! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
451
e9174d1e
SL
452macro_rules! rem_impl_float {
453 ($($t:ty)*) => ($(
454 #[stable(feature = "rust1", since = "1.0.0")]
455 impl Rem for $t {
456 type Output = $t;
457
458 #[inline]
459 fn rem(self, other: $t) -> $t { self % other }
460 }
461
462 forward_ref_binop! { impl Rem, rem for $t, $t }
463 )*)
464}
465
e9174d1e 466rem_impl_float! { f32 f64 }
1a4d82fc 467
1a4d82fc
JJ
468/// The `Neg` trait is used to specify the functionality of unary `-`.
469///
c34b1796 470/// # Examples
1a4d82fc
JJ
471///
472/// A trivial implementation of `Neg`. When `-Foo` happens, it ends up calling
473/// `neg`, and therefore, `main` prints `Negating!`.
474///
475/// ```
1a4d82fc
JJ
476/// use std::ops::Neg;
477///
478/// struct Foo;
479///
1a4d82fc
JJ
480/// impl Neg for Foo {
481/// type Output = Foo;
482///
483/// fn neg(self) -> Foo {
484/// println!("Negating!");
485/// self
486/// }
487/// }
488///
489/// fn main() {
490/// -Foo;
491/// }
492/// ```
d9579d0f 493#[lang = "neg"]
85aaf69f 494#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 495pub trait Neg {
c34b1796 496 /// The resulting type after applying the `-` operator
85aaf69f 497 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
498 type Output;
499
500 /// The method for the unary `-` operator
85aaf69f 501 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
502 fn neg(self) -> Self::Output;
503}
504
c34b1796
AL
505
506
507macro_rules! neg_impl_core {
508 ($id:ident => $body:expr, $($t:ty)*) => ($(
85aaf69f 509 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 510 impl Neg for $t {
1a4d82fc
JJ
511 type Output = $t;
512
513 #[inline]
c34b1796 514 fn neg(self) -> $t { let $id = self; $body }
1a4d82fc 515 }
85aaf69f
SL
516
517 forward_ref_unop! { impl Neg, neg for $t }
1a4d82fc
JJ
518 )*)
519}
520
c34b1796
AL
521macro_rules! neg_impl_numeric {
522 ($($t:ty)*) => { neg_impl_core!{ x => -x, $($t)*} }
1a4d82fc
JJ
523}
524
c34b1796
AL
525macro_rules! neg_impl_unsigned {
526 ($($t:ty)*) => {
527 neg_impl_core!{ x => {
c34b1796
AL
528 !x.wrapping_add(1)
529 }, $($t)*} }
530}
1a4d82fc 531
c34b1796
AL
532// neg_impl_unsigned! { usize u8 u16 u32 u64 }
533neg_impl_numeric! { isize i8 i16 i32 i64 f32 f64 }
1a4d82fc
JJ
534
535/// The `Not` trait is used to specify the functionality of unary `!`.
536///
c34b1796 537/// # Examples
1a4d82fc
JJ
538///
539/// A trivial implementation of `Not`. When `!Foo` happens, it ends up calling
540/// `not`, and therefore, `main` prints `Not-ing!`.
541///
542/// ```
1a4d82fc
JJ
543/// use std::ops::Not;
544///
545/// struct Foo;
546///
1a4d82fc
JJ
547/// impl Not for Foo {
548/// type Output = Foo;
549///
550/// fn not(self) -> Foo {
551/// println!("Not-ing!");
552/// self
553/// }
554/// }
555///
556/// fn main() {
557/// !Foo;
558/// }
559/// ```
d9579d0f 560#[lang = "not"]
85aaf69f 561#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 562pub trait Not {
c34b1796 563 /// The resulting type after applying the `!` operator
85aaf69f 564 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
565 type Output;
566
567 /// The method for the unary `!` operator
85aaf69f 568 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
569 fn not(self) -> Self::Output;
570}
571
572macro_rules! not_impl {
573 ($($t:ty)*) => ($(
85aaf69f 574 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
575 impl Not for $t {
576 type Output = $t;
577
578 #[inline]
579 fn not(self) -> $t { !self }
580 }
85aaf69f
SL
581
582 forward_ref_unop! { impl Not, not for $t }
1a4d82fc
JJ
583 )*)
584}
585
85aaf69f 586not_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
1a4d82fc
JJ
587
588/// The `BitAnd` trait is used to specify the functionality of `&`.
589///
c34b1796 590/// # Examples
1a4d82fc
JJ
591///
592/// A trivial implementation of `BitAnd`. When `Foo & Foo` happens, it ends up
593/// calling `bitand`, and therefore, `main` prints `Bitwise And-ing!`.
594///
595/// ```
1a4d82fc
JJ
596/// use std::ops::BitAnd;
597///
1a4d82fc
JJ
598/// struct Foo;
599///
600/// impl BitAnd for Foo {
601/// type Output = Foo;
602///
603/// fn bitand(self, _rhs: Foo) -> Foo {
604/// println!("Bitwise And-ing!");
605/// self
606/// }
607/// }
608///
609/// fn main() {
610/// Foo & Foo;
611/// }
612/// ```
d9579d0f 613#[lang = "bitand"]
85aaf69f 614#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 615pub trait BitAnd<RHS=Self> {
c34b1796 616 /// The resulting type after applying the `&` operator
85aaf69f 617 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
618 type Output;
619
620 /// The method for the `&` operator
85aaf69f 621 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
622 fn bitand(self, rhs: RHS) -> Self::Output;
623}
624
625macro_rules! bitand_impl {
626 ($($t:ty)*) => ($(
85aaf69f 627 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
628 impl BitAnd for $t {
629 type Output = $t;
630
631 #[inline]
632 fn bitand(self, rhs: $t) -> $t { self & rhs }
633 }
85aaf69f
SL
634
635 forward_ref_binop! { impl BitAnd, bitand for $t, $t }
1a4d82fc
JJ
636 )*)
637}
638
85aaf69f 639bitand_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
1a4d82fc
JJ
640
641/// The `BitOr` trait is used to specify the functionality of `|`.
642///
c34b1796 643/// # Examples
1a4d82fc
JJ
644///
645/// A trivial implementation of `BitOr`. When `Foo | Foo` happens, it ends up
646/// calling `bitor`, and therefore, `main` prints `Bitwise Or-ing!`.
647///
648/// ```
1a4d82fc
JJ
649/// use std::ops::BitOr;
650///
1a4d82fc
JJ
651/// struct Foo;
652///
653/// impl BitOr for Foo {
654/// type Output = Foo;
655///
656/// fn bitor(self, _rhs: Foo) -> Foo {
657/// println!("Bitwise Or-ing!");
658/// self
659/// }
660/// }
661///
662/// fn main() {
663/// Foo | Foo;
664/// }
665/// ```
d9579d0f 666#[lang = "bitor"]
85aaf69f 667#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 668pub trait BitOr<RHS=Self> {
c34b1796 669 /// The resulting type after applying the `|` operator
85aaf69f 670 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
671 type Output;
672
673 /// The method for the `|` operator
85aaf69f 674 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
675 fn bitor(self, rhs: RHS) -> Self::Output;
676}
677
678macro_rules! bitor_impl {
679 ($($t:ty)*) => ($(
85aaf69f 680 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
681 impl BitOr for $t {
682 type Output = $t;
683
684 #[inline]
685 fn bitor(self, rhs: $t) -> $t { self | rhs }
686 }
85aaf69f
SL
687
688 forward_ref_binop! { impl BitOr, bitor for $t, $t }
1a4d82fc
JJ
689 )*)
690}
691
85aaf69f 692bitor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
1a4d82fc
JJ
693
694/// The `BitXor` trait is used to specify the functionality of `^`.
695///
c34b1796 696/// # Examples
1a4d82fc
JJ
697///
698/// A trivial implementation of `BitXor`. When `Foo ^ Foo` happens, it ends up
699/// calling `bitxor`, and therefore, `main` prints `Bitwise Xor-ing!`.
700///
701/// ```
1a4d82fc
JJ
702/// use std::ops::BitXor;
703///
1a4d82fc
JJ
704/// struct Foo;
705///
706/// impl BitXor for Foo {
707/// type Output = Foo;
708///
709/// fn bitxor(self, _rhs: Foo) -> Foo {
710/// println!("Bitwise Xor-ing!");
711/// self
712/// }
713/// }
714///
715/// fn main() {
716/// Foo ^ Foo;
717/// }
718/// ```
d9579d0f 719#[lang = "bitxor"]
85aaf69f 720#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 721pub trait BitXor<RHS=Self> {
c34b1796 722 /// The resulting type after applying the `^` operator
85aaf69f 723 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
724 type Output;
725
726 /// The method for the `^` operator
85aaf69f 727 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
728 fn bitxor(self, rhs: RHS) -> Self::Output;
729}
730
731macro_rules! bitxor_impl {
732 ($($t:ty)*) => ($(
85aaf69f 733 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
734 impl BitXor for $t {
735 type Output = $t;
736
737 #[inline]
738 fn bitxor(self, other: $t) -> $t { self ^ other }
739 }
85aaf69f
SL
740
741 forward_ref_binop! { impl BitXor, bitxor for $t, $t }
1a4d82fc
JJ
742 )*)
743}
744
85aaf69f 745bitxor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
1a4d82fc
JJ
746
747/// The `Shl` trait is used to specify the functionality of `<<`.
748///
c34b1796 749/// # Examples
1a4d82fc
JJ
750///
751/// A trivial implementation of `Shl`. When `Foo << Foo` happens, it ends up
752/// calling `shl`, and therefore, `main` prints `Shifting left!`.
753///
754/// ```
1a4d82fc
JJ
755/// use std::ops::Shl;
756///
1a4d82fc
JJ
757/// struct Foo;
758///
759/// impl Shl<Foo> for Foo {
760/// type Output = Foo;
761///
762/// fn shl(self, _rhs: Foo) -> Foo {
763/// println!("Shifting left!");
764/// self
765/// }
766/// }
767///
768/// fn main() {
769/// Foo << Foo;
770/// }
771/// ```
d9579d0f 772#[lang = "shl"]
85aaf69f 773#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 774pub trait Shl<RHS> {
c34b1796 775 /// The resulting type after applying the `<<` operator
85aaf69f 776 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
777 type Output;
778
779 /// The method for the `<<` operator
85aaf69f 780 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
781 fn shl(self, rhs: RHS) -> Self::Output;
782}
783
784macro_rules! shl_impl {
85aaf69f
SL
785 ($t:ty, $f:ty) => (
786 #[stable(feature = "rust1", since = "1.0.0")]
787 impl Shl<$f> for $t {
1a4d82fc
JJ
788 type Output = $t;
789
790 #[inline]
85aaf69f 791 fn shl(self, other: $f) -> $t {
1a4d82fc
JJ
792 self << other
793 }
794 }
85aaf69f
SL
795
796 forward_ref_binop! { impl Shl, shl for $t, $f }
797 )
798}
799
800macro_rules! shl_impl_all {
801 ($($t:ty)*) => ($(
802 shl_impl! { $t, u8 }
803 shl_impl! { $t, u16 }
804 shl_impl! { $t, u32 }
805 shl_impl! { $t, u64 }
806 shl_impl! { $t, usize }
807
808 shl_impl! { $t, i8 }
809 shl_impl! { $t, i16 }
810 shl_impl! { $t, i32 }
811 shl_impl! { $t, i64 }
812 shl_impl! { $t, isize }
1a4d82fc
JJ
813 )*)
814}
815
85aaf69f 816shl_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
1a4d82fc
JJ
817
818/// The `Shr` trait is used to specify the functionality of `>>`.
819///
c34b1796 820/// # Examples
1a4d82fc
JJ
821///
822/// A trivial implementation of `Shr`. When `Foo >> Foo` happens, it ends up
823/// calling `shr`, and therefore, `main` prints `Shifting right!`.
824///
825/// ```
1a4d82fc
JJ
826/// use std::ops::Shr;
827///
1a4d82fc
JJ
828/// struct Foo;
829///
830/// impl Shr<Foo> for Foo {
831/// type Output = Foo;
832///
833/// fn shr(self, _rhs: Foo) -> Foo {
834/// println!("Shifting right!");
835/// self
836/// }
837/// }
838///
839/// fn main() {
840/// Foo >> Foo;
841/// }
842/// ```
d9579d0f 843#[lang = "shr"]
85aaf69f 844#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 845pub trait Shr<RHS> {
c34b1796 846 /// The resulting type after applying the `>>` operator
85aaf69f 847 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
848 type Output;
849
850 /// The method for the `>>` operator
85aaf69f 851 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
852 fn shr(self, rhs: RHS) -> Self::Output;
853}
854
855macro_rules! shr_impl {
85aaf69f 856 ($t:ty, $f:ty) => (
92a42be0 857 #[stable(feature = "rust1", since = "1.0.0")]
85aaf69f 858 impl Shr<$f> for $t {
1a4d82fc
JJ
859 type Output = $t;
860
861 #[inline]
85aaf69f
SL
862 fn shr(self, other: $f) -> $t {
863 self >> other
864 }
1a4d82fc 865 }
85aaf69f
SL
866
867 forward_ref_binop! { impl Shr, shr for $t, $f }
868 )
869}
870
871macro_rules! shr_impl_all {
872 ($($t:ty)*) => ($(
873 shr_impl! { $t, u8 }
874 shr_impl! { $t, u16 }
875 shr_impl! { $t, u32 }
876 shr_impl! { $t, u64 }
877 shr_impl! { $t, usize }
878
879 shr_impl! { $t, i8 }
880 shr_impl! { $t, i16 }
881 shr_impl! { $t, i32 }
882 shr_impl! { $t, i64 }
883 shr_impl! { $t, isize }
1a4d82fc
JJ
884 )*)
885}
886
85aaf69f 887shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
1a4d82fc 888
b039eaaf
SL
889/// The `AddAssign` trait is used to specify the functionality of `+=`.
890///
891/// # Examples
892///
893/// A trivial implementation of `AddAssign`. When `Foo += Foo` happens, it ends up
894/// calling `add_assign`, and therefore, `main` prints `Adding!`.
895///
896/// ```
b039eaaf
SL
897/// use std::ops::AddAssign;
898///
b039eaaf
SL
899/// struct Foo;
900///
901/// impl AddAssign for Foo {
902/// fn add_assign(&mut self, _rhs: Foo) {
903/// println!("Adding!");
904/// }
905/// }
906///
92a42be0 907/// # #[allow(unused_assignments)]
b039eaaf
SL
908/// fn main() {
909/// let mut foo = Foo;
910/// foo += Foo;
911/// }
912/// ```
b039eaaf 913#[lang = "add_assign"]
7453a54e 914#[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
915pub trait AddAssign<Rhs=Self> {
916 /// The method for the `+=` operator
7453a54e 917 #[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
918 fn add_assign(&mut self, Rhs);
919}
920
b039eaaf
SL
921macro_rules! add_assign_impl {
922 ($($t:ty)+) => ($(
7453a54e 923 #[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
924 impl AddAssign for $t {
925 #[inline]
926 fn add_assign(&mut self, other: $t) { *self += other }
927 }
928 )+)
929}
930
b039eaaf
SL
931add_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
932
933/// The `SubAssign` trait is used to specify the functionality of `-=`.
934///
935/// # Examples
936///
937/// A trivial implementation of `SubAssign`. When `Foo -= Foo` happens, it ends up
938/// calling `sub_assign`, and therefore, `main` prints `Subtracting!`.
939///
940/// ```
b039eaaf
SL
941/// use std::ops::SubAssign;
942///
b039eaaf
SL
943/// struct Foo;
944///
945/// impl SubAssign for Foo {
946/// fn sub_assign(&mut self, _rhs: Foo) {
947/// println!("Subtracting!");
948/// }
949/// }
950///
92a42be0 951/// # #[allow(unused_assignments)]
b039eaaf
SL
952/// fn main() {
953/// let mut foo = Foo;
954/// foo -= Foo;
955/// }
956/// ```
b039eaaf 957#[lang = "sub_assign"]
7453a54e 958#[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
959pub trait SubAssign<Rhs=Self> {
960 /// The method for the `-=` operator
7453a54e 961 #[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
962 fn sub_assign(&mut self, Rhs);
963}
964
b039eaaf
SL
965macro_rules! sub_assign_impl {
966 ($($t:ty)+) => ($(
7453a54e 967 #[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
968 impl SubAssign for $t {
969 #[inline]
970 fn sub_assign(&mut self, other: $t) { *self -= other }
971 }
972 )+)
973}
974
b039eaaf
SL
975sub_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
976
977/// The `MulAssign` trait is used to specify the functionality of `*=`.
978///
979/// # Examples
980///
981/// A trivial implementation of `MulAssign`. When `Foo *= Foo` happens, it ends up
982/// calling `mul_assign`, and therefore, `main` prints `Multiplying!`.
983///
984/// ```
b039eaaf
SL
985/// use std::ops::MulAssign;
986///
b039eaaf
SL
987/// struct Foo;
988///
989/// impl MulAssign for Foo {
990/// fn mul_assign(&mut self, _rhs: Foo) {
991/// println!("Multiplying!");
992/// }
993/// }
994///
92a42be0 995/// # #[allow(unused_assignments)]
b039eaaf
SL
996/// fn main() {
997/// let mut foo = Foo;
998/// foo *= Foo;
999/// }
1000/// ```
b039eaaf 1001#[lang = "mul_assign"]
7453a54e 1002#[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1003pub trait MulAssign<Rhs=Self> {
1004 /// The method for the `*=` operator
7453a54e 1005 #[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1006 fn mul_assign(&mut self, Rhs);
1007}
1008
b039eaaf
SL
1009macro_rules! mul_assign_impl {
1010 ($($t:ty)+) => ($(
7453a54e 1011 #[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1012 impl MulAssign for $t {
1013 #[inline]
1014 fn mul_assign(&mut self, other: $t) { *self *= other }
1015 }
1016 )+)
1017}
1018
b039eaaf
SL
1019mul_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
1020
1021/// The `DivAssign` trait is used to specify the functionality of `/=`.
1022///
1023/// # Examples
1024///
1025/// A trivial implementation of `DivAssign`. When `Foo /= Foo` happens, it ends up
1026/// calling `div_assign`, and therefore, `main` prints `Dividing!`.
1027///
1028/// ```
b039eaaf
SL
1029/// use std::ops::DivAssign;
1030///
b039eaaf
SL
1031/// struct Foo;
1032///
1033/// impl DivAssign for Foo {
1034/// fn div_assign(&mut self, _rhs: Foo) {
1035/// println!("Dividing!");
1036/// }
1037/// }
1038///
92a42be0 1039/// # #[allow(unused_assignments)]
b039eaaf
SL
1040/// fn main() {
1041/// let mut foo = Foo;
1042/// foo /= Foo;
1043/// }
1044/// ```
b039eaaf 1045#[lang = "div_assign"]
7453a54e 1046#[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1047pub trait DivAssign<Rhs=Self> {
1048 /// The method for the `/=` operator
7453a54e 1049 #[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1050 fn div_assign(&mut self, Rhs);
1051}
1052
b039eaaf
SL
1053macro_rules! div_assign_impl {
1054 ($($t:ty)+) => ($(
7453a54e 1055 #[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1056 impl DivAssign for $t {
1057 #[inline]
1058 fn div_assign(&mut self, other: $t) { *self /= other }
1059 }
1060 )+)
1061}
1062
b039eaaf
SL
1063div_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
1064
1065/// The `RemAssign` trait is used to specify the functionality of `%=`.
1066///
1067/// # Examples
1068///
1069/// A trivial implementation of `RemAssign`. When `Foo %= Foo` happens, it ends up
1070/// calling `rem_assign`, and therefore, `main` prints `Remainder-ing!`.
1071///
1072/// ```
b039eaaf
SL
1073/// use std::ops::RemAssign;
1074///
b039eaaf
SL
1075/// struct Foo;
1076///
1077/// impl RemAssign for Foo {
1078/// fn rem_assign(&mut self, _rhs: Foo) {
1079/// println!("Remainder-ing!");
1080/// }
1081/// }
1082///
92a42be0 1083/// # #[allow(unused_assignments)]
b039eaaf
SL
1084/// fn main() {
1085/// let mut foo = Foo;
1086/// foo %= Foo;
1087/// }
1088/// ```
b039eaaf 1089#[lang = "rem_assign"]
7453a54e 1090#[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1091pub trait RemAssign<Rhs=Self> {
1092 /// The method for the `%=` operator
7453a54e 1093 #[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1094 fn rem_assign(&mut self, Rhs);
1095}
1096
b039eaaf
SL
1097macro_rules! rem_assign_impl {
1098 ($($t:ty)+) => ($(
7453a54e 1099 #[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1100 impl RemAssign for $t {
1101 #[inline]
1102 fn rem_assign(&mut self, other: $t) { *self %= other }
1103 }
1104 )+)
1105}
1106
b039eaaf
SL
1107rem_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
1108
1109/// The `BitAndAssign` trait is used to specify the functionality of `&=`.
1110///
1111/// # Examples
1112///
1113/// A trivial implementation of `BitAndAssign`. When `Foo &= Foo` happens, it ends up
1114/// calling `bitand_assign`, and therefore, `main` prints `Bitwise And-ing!`.
1115///
1116/// ```
b039eaaf
SL
1117/// use std::ops::BitAndAssign;
1118///
b039eaaf
SL
1119/// struct Foo;
1120///
1121/// impl BitAndAssign for Foo {
1122/// fn bitand_assign(&mut self, _rhs: Foo) {
1123/// println!("Bitwise And-ing!");
1124/// }
1125/// }
1126///
92a42be0 1127/// # #[allow(unused_assignments)]
b039eaaf
SL
1128/// fn main() {
1129/// let mut foo = Foo;
1130/// foo &= Foo;
1131/// }
1132/// ```
b039eaaf 1133#[lang = "bitand_assign"]
7453a54e 1134#[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1135pub trait BitAndAssign<Rhs=Self> {
1136 /// The method for the `&` operator
7453a54e 1137 #[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1138 fn bitand_assign(&mut self, Rhs);
1139}
1140
b039eaaf
SL
1141macro_rules! bitand_assign_impl {
1142 ($($t:ty)+) => ($(
7453a54e 1143 #[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1144 impl BitAndAssign for $t {
1145 #[inline]
1146 fn bitand_assign(&mut self, other: $t) { *self &= other }
1147 }
1148 )+)
1149}
1150
b039eaaf
SL
1151bitand_assign_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
1152
1153/// The `BitOrAssign` trait is used to specify the functionality of `|=`.
1154///
1155/// # Examples
1156///
1157/// A trivial implementation of `BitOrAssign`. When `Foo |= Foo` happens, it ends up
1158/// calling `bitor_assign`, and therefore, `main` prints `Bitwise Or-ing!`.
1159///
1160/// ```
b039eaaf
SL
1161/// use std::ops::BitOrAssign;
1162///
b039eaaf
SL
1163/// struct Foo;
1164///
1165/// impl BitOrAssign for Foo {
1166/// fn bitor_assign(&mut self, _rhs: Foo) {
1167/// println!("Bitwise Or-ing!");
1168/// }
1169/// }
1170///
92a42be0 1171/// # #[allow(unused_assignments)]
b039eaaf
SL
1172/// fn main() {
1173/// let mut foo = Foo;
1174/// foo |= Foo;
1175/// }
1176/// ```
b039eaaf 1177#[lang = "bitor_assign"]
7453a54e 1178#[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1179pub trait BitOrAssign<Rhs=Self> {
1180 /// The method for the `|=` operator
7453a54e 1181 #[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1182 fn bitor_assign(&mut self, Rhs);
1183}
1184
b039eaaf
SL
1185macro_rules! bitor_assign_impl {
1186 ($($t:ty)+) => ($(
7453a54e 1187 #[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1188 impl BitOrAssign for $t {
1189 #[inline]
1190 fn bitor_assign(&mut self, other: $t) { *self |= other }
1191 }
1192 )+)
1193}
1194
b039eaaf
SL
1195bitor_assign_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
1196
1197/// The `BitXorAssign` trait is used to specify the functionality of `^=`.
1198///
1199/// # Examples
1200///
1201/// A trivial implementation of `BitXorAssign`. When `Foo ^= Foo` happens, it ends up
1202/// calling `bitxor_assign`, and therefore, `main` prints `Bitwise Xor-ing!`.
1203///
1204/// ```
b039eaaf
SL
1205/// use std::ops::BitXorAssign;
1206///
b039eaaf
SL
1207/// struct Foo;
1208///
1209/// impl BitXorAssign for Foo {
1210/// fn bitxor_assign(&mut self, _rhs: Foo) {
1211/// println!("Bitwise Xor-ing!");
1212/// }
1213/// }
1214///
92a42be0 1215/// # #[allow(unused_assignments)]
b039eaaf
SL
1216/// fn main() {
1217/// let mut foo = Foo;
1218/// foo ^= Foo;
1219/// }
1220/// ```
b039eaaf 1221#[lang = "bitxor_assign"]
7453a54e 1222#[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1223pub trait BitXorAssign<Rhs=Self> {
1224 /// The method for the `^=` operator
7453a54e 1225 #[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1226 fn bitxor_assign(&mut self, Rhs);
1227}
1228
b039eaaf
SL
1229macro_rules! bitxor_assign_impl {
1230 ($($t:ty)+) => ($(
7453a54e 1231 #[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1232 impl BitXorAssign for $t {
1233 #[inline]
1234 fn bitxor_assign(&mut self, other: $t) { *self ^= other }
1235 }
1236 )+)
1237}
1238
b039eaaf
SL
1239bitxor_assign_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
1240
1241/// The `ShlAssign` trait is used to specify the functionality of `<<=`.
1242///
1243/// # Examples
1244///
1245/// A trivial implementation of `ShlAssign`. When `Foo <<= Foo` happens, it ends up
1246/// calling `shl_assign`, and therefore, `main` prints `Shifting left!`.
1247///
1248/// ```
b039eaaf
SL
1249/// use std::ops::ShlAssign;
1250///
b039eaaf
SL
1251/// struct Foo;
1252///
1253/// impl ShlAssign<Foo> for Foo {
1254/// fn shl_assign(&mut self, _rhs: Foo) {
1255/// println!("Shifting left!");
1256/// }
1257/// }
1258///
92a42be0 1259/// # #[allow(unused_assignments)]
b039eaaf
SL
1260/// fn main() {
1261/// let mut foo = Foo;
1262/// foo <<= Foo;
1263/// }
1264/// ```
b039eaaf 1265#[lang = "shl_assign"]
7453a54e 1266#[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1267pub trait ShlAssign<Rhs> {
1268 /// The method for the `<<=` operator
7453a54e 1269 #[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1270 fn shl_assign(&mut self, Rhs);
1271}
1272
b039eaaf
SL
1273macro_rules! shl_assign_impl {
1274 ($t:ty, $f:ty) => (
7453a54e 1275 #[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1276 impl ShlAssign<$f> for $t {
1277 #[inline]
1278 fn shl_assign(&mut self, other: $f) {
1279 *self <<= other
1280 }
1281 }
1282 )
1283}
1284
b039eaaf
SL
1285macro_rules! shl_assign_impl_all {
1286 ($($t:ty)*) => ($(
1287 shl_assign_impl! { $t, u8 }
1288 shl_assign_impl! { $t, u16 }
1289 shl_assign_impl! { $t, u32 }
1290 shl_assign_impl! { $t, u64 }
1291 shl_assign_impl! { $t, usize }
1292
1293 shl_assign_impl! { $t, i8 }
1294 shl_assign_impl! { $t, i16 }
1295 shl_assign_impl! { $t, i32 }
1296 shl_assign_impl! { $t, i64 }
1297 shl_assign_impl! { $t, isize }
1298 )*)
1299}
1300
b039eaaf
SL
1301shl_assign_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
1302
1303/// The `ShrAssign` trait is used to specify the functionality of `>>=`.
1304///
1305/// # Examples
1306///
1307/// A trivial implementation of `ShrAssign`. When `Foo >>= Foo` happens, it ends up
1308/// calling `shr_assign`, and therefore, `main` prints `Shifting right!`.
1309///
1310/// ```
b039eaaf
SL
1311/// use std::ops::ShrAssign;
1312///
b039eaaf
SL
1313/// struct Foo;
1314///
1315/// impl ShrAssign<Foo> for Foo {
1316/// fn shr_assign(&mut self, _rhs: Foo) {
1317/// println!("Shifting right!");
1318/// }
1319/// }
1320///
92a42be0 1321/// # #[allow(unused_assignments)]
b039eaaf
SL
1322/// fn main() {
1323/// let mut foo = Foo;
1324/// foo >>= Foo;
1325/// }
1326/// ```
b039eaaf 1327#[lang = "shr_assign"]
7453a54e 1328#[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1329pub trait ShrAssign<Rhs=Self> {
1330 /// The method for the `>>=` operator
7453a54e 1331 #[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1332 fn shr_assign(&mut self, Rhs);
1333}
1334
b039eaaf
SL
1335macro_rules! shr_assign_impl {
1336 ($t:ty, $f:ty) => (
7453a54e 1337 #[stable(feature = "op_assign_traits", since = "1.8.0")]
b039eaaf
SL
1338 impl ShrAssign<$f> for $t {
1339 #[inline]
1340 fn shr_assign(&mut self, other: $f) {
1341 *self >>= other
1342 }
1343 }
1344 )
1345}
1346
b039eaaf
SL
1347macro_rules! shr_assign_impl_all {
1348 ($($t:ty)*) => ($(
1349 shr_assign_impl! { $t, u8 }
1350 shr_assign_impl! { $t, u16 }
1351 shr_assign_impl! { $t, u32 }
1352 shr_assign_impl! { $t, u64 }
1353 shr_assign_impl! { $t, usize }
1354
1355 shr_assign_impl! { $t, i8 }
1356 shr_assign_impl! { $t, i16 }
1357 shr_assign_impl! { $t, i32 }
1358 shr_assign_impl! { $t, i64 }
1359 shr_assign_impl! { $t, isize }
1360 )*)
1361}
1362
b039eaaf
SL
1363shr_assign_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
1364
1a4d82fc
JJ
1365/// The `Index` trait is used to specify the functionality of indexing operations
1366/// like `arr[idx]` when used in an immutable context.
1367///
c34b1796 1368/// # Examples
1a4d82fc 1369///
85aaf69f 1370/// A trivial implementation of `Index`. When `Foo[Bar]` happens, it ends up
1a4d82fc
JJ
1371/// calling `index`, and therefore, `main` prints `Indexing!`.
1372///
1373/// ```
1a4d82fc
JJ
1374/// use std::ops::Index;
1375///
c34b1796 1376/// #[derive(Copy, Clone)]
1a4d82fc 1377/// struct Foo;
85aaf69f 1378/// struct Bar;
1a4d82fc 1379///
85aaf69f 1380/// impl Index<Bar> for Foo {
1a4d82fc
JJ
1381/// type Output = Foo;
1382///
c34b1796 1383/// fn index<'a>(&'a self, _index: Bar) -> &'a Foo {
1a4d82fc
JJ
1384/// println!("Indexing!");
1385/// self
1386/// }
1387/// }
1388///
1389/// fn main() {
85aaf69f 1390/// Foo[Bar];
1a4d82fc
JJ
1391/// }
1392/// ```
d9579d0f 1393#[lang = "index"]
85aaf69f
SL
1394#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
1395#[stable(feature = "rust1", since = "1.0.0")]
1396pub trait Index<Idx: ?Sized> {
c34b1796
AL
1397 /// The returned type after indexing
1398 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
1399 type Output: ?Sized;
1400
1401 /// The method for the indexing (`Foo[Bar]`) operation
85aaf69f 1402 #[stable(feature = "rust1", since = "1.0.0")]
e9174d1e 1403 fn index(&self, index: Idx) -> &Self::Output;
1a4d82fc
JJ
1404}
1405
1406/// The `IndexMut` trait is used to specify the functionality of indexing
1407/// operations like `arr[idx]`, when used in a mutable context.
1408///
c34b1796 1409/// # Examples
1a4d82fc 1410///
85aaf69f 1411/// A trivial implementation of `IndexMut`. When `Foo[Bar]` happens, it ends up
1a4d82fc
JJ
1412/// calling `index_mut`, and therefore, `main` prints `Indexing!`.
1413///
1414/// ```
85aaf69f 1415/// use std::ops::{Index, IndexMut};
1a4d82fc 1416///
c34b1796 1417/// #[derive(Copy, Clone)]
1a4d82fc 1418/// struct Foo;
85aaf69f 1419/// struct Bar;
1a4d82fc 1420///
85aaf69f 1421/// impl Index<Bar> for Foo {
1a4d82fc
JJ
1422/// type Output = Foo;
1423///
c34b1796 1424/// fn index<'a>(&'a self, _index: Bar) -> &'a Foo {
85aaf69f
SL
1425/// self
1426/// }
1427/// }
1428///
1429/// impl IndexMut<Bar> for Foo {
c34b1796 1430/// fn index_mut<'a>(&'a mut self, _index: Bar) -> &'a mut Foo {
1a4d82fc
JJ
1431/// println!("Indexing!");
1432/// self
1433/// }
1434/// }
1435///
1436/// fn main() {
85aaf69f 1437/// &mut Foo[Bar];
1a4d82fc
JJ
1438/// }
1439/// ```
d9579d0f 1440#[lang = "index_mut"]
85aaf69f
SL
1441#[rustc_on_unimplemented = "the type `{Self}` cannot be mutably indexed by `{Idx}`"]
1442#[stable(feature = "rust1", since = "1.0.0")]
1443pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
1a4d82fc 1444 /// The method for the indexing (`Foo[Bar]`) operation
85aaf69f 1445 #[stable(feature = "rust1", since = "1.0.0")]
e9174d1e 1446 fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
1a4d82fc
JJ
1447}
1448
54a0048b
SL
1449/// An unbounded range. Use `..` (two dots) for its shorthand.
1450///
1451/// Its primary use case is slicing index. It cannot serve as an iterator
1452/// because it doesn't have a starting point.
1453///
1454/// # Examples
1455///
1456/// ```
1457/// fn main() {
1458/// assert_eq!((..), std::ops::RangeFull);
1459///
1460/// let arr = [0, 1, 2, 3];
1461/// assert_eq!(arr[ .. ], [0,1,2,3]); // RangeFull
1462/// assert_eq!(arr[ ..3], [0,1,2 ]);
1463/// assert_eq!(arr[1.. ], [ 1,2,3]);
1464/// assert_eq!(arr[1..3], [ 1,2 ]);
1465/// }
1466/// ```
85aaf69f 1467#[derive(Copy, Clone, PartialEq, Eq)]
85aaf69f
SL
1468#[stable(feature = "rust1", since = "1.0.0")]
1469pub struct RangeFull;
1a4d82fc 1470
85aaf69f
SL
1471#[stable(feature = "rust1", since = "1.0.0")]
1472impl fmt::Debug for RangeFull {
1a4d82fc 1473 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
d9579d0f 1474 write!(fmt, "..")
1a4d82fc
JJ
1475 }
1476}
1477
54a0048b
SL
1478/// A (half-open) range which is bounded at both ends: { x | start <= x < end }.
1479/// Use `start..end` (two dots) for its shorthand.
1480///
1481/// See the [`contains()`](#method.contains) method for its characterization.
1482///
1483/// # Examples
1484///
1485/// ```
1486/// #![feature(iter_arith)]
1487/// fn main() {
1488/// assert_eq!((3..5), std::ops::Range{ start: 3, end: 5 });
1489/// assert_eq!(3+4+5, (3..6).sum());
1490///
1491/// let arr = [0, 1, 2, 3];
1492/// assert_eq!(arr[ .. ], [0,1,2,3]);
1493/// assert_eq!(arr[ ..3], [0,1,2 ]);
1494/// assert_eq!(arr[1.. ], [ 1,2,3]);
1495/// assert_eq!(arr[1..3], [ 1,2 ]); // Range
1496/// }
1497/// ```
85aaf69f 1498#[derive(Clone, PartialEq, Eq)]
85aaf69f 1499#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
1500pub struct Range<Idx> {
1501 /// The lower bound of the range (inclusive).
c34b1796 1502 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
1503 pub start: Idx,
1504 /// The upper bound of the range (exclusive).
c34b1796 1505 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
1506 pub end: Idx,
1507}
1508
85aaf69f
SL
1509#[stable(feature = "rust1", since = "1.0.0")]
1510impl<Idx: fmt::Debug> fmt::Debug for Range<Idx> {
1a4d82fc
JJ
1511 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1512 write!(fmt, "{:?}..{:?}", self.start, self.end)
1513 }
1514}
1515
54a0048b
SL
1516#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
1517impl<Idx: PartialOrd<Idx>> Range<Idx> {
1518 /// # Examples
1519 ///
1520 /// ```
1521 /// #![feature(range_contains)]
1522 /// fn main() {
1523 /// assert!( ! (3..5).contains(2));
1524 /// assert!( (3..5).contains(3));
1525 /// assert!( (3..5).contains(4));
1526 /// assert!( ! (3..5).contains(5));
1527 ///
1528 /// assert!( ! (3..3).contains(3));
1529 /// assert!( ! (3..2).contains(3));
1530 /// }
1531 /// ```
1532 pub fn contains(&self, item: Idx) -> bool {
1533 (self.start <= item) && (item < self.end)
1534 }
1535}
1536
1537/// A range which is only bounded below: { x | start <= x }.
1538/// Use `start..` for its shorthand.
1539///
1540/// See the [`contains()`](#method.contains) method for its characterization.
1541///
1542/// # Examples
1543///
1544/// ```
1545/// #![feature(iter_arith)]
1546/// fn main() {
1547/// assert_eq!((2..), std::ops::RangeFrom{ start: 2 });
1548/// assert_eq!(2+3+4, (2..).take(3).sum());
1549///
1550/// let arr = [0, 1, 2, 3];
1551/// assert_eq!(arr[ .. ], [0,1,2,3]);
1552/// assert_eq!(arr[ ..3], [0,1,2 ]);
1553/// assert_eq!(arr[1.. ], [ 1,2,3]); // RangeFrom
1554/// assert_eq!(arr[1..3], [ 1,2 ]);
1555/// }
1556/// ```
85aaf69f 1557#[derive(Clone, PartialEq, Eq)]
85aaf69f 1558#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
1559pub struct RangeFrom<Idx> {
1560 /// The lower bound of the range (inclusive).
c34b1796 1561 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
1562 pub start: Idx,
1563}
1564
85aaf69f
SL
1565#[stable(feature = "rust1", since = "1.0.0")]
1566impl<Idx: fmt::Debug> fmt::Debug for RangeFrom<Idx> {
1a4d82fc
JJ
1567 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1568 write!(fmt, "{:?}..", self.start)
1569 }
1570}
1571
54a0048b
SL
1572#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
1573impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
1574 /// # Examples
1575 ///
1576 /// ```
1577 /// #![feature(range_contains)]
1578 /// fn main() {
1579 /// assert!( ! (3..).contains(2));
1580 /// assert!( (3..).contains(3));
1581 /// assert!( (3..).contains(1_000_000_000));
1582 /// }
1583 /// ```
1584 pub fn contains(&self, item: Idx) -> bool {
1585 (self.start <= item)
1586 }
1587}
1588
1589/// A range which is only bounded above: { x | x < end }.
1590/// Use `..end` (two dots) for its shorthand.
1591///
1592/// See the [`contains()`](#method.contains) method for its characterization.
1593///
1594/// It cannot serve as an iterator because it doesn't have a starting point.
1595/// ```
1596/// fn main() {
1597/// assert_eq!((..5), std::ops::RangeTo{ end: 5 });
1598///
1599/// let arr = [0, 1, 2, 3];
1600/// assert_eq!(arr[ .. ], [0,1,2,3]);
1601/// assert_eq!(arr[ ..3], [0,1,2 ]); // RangeTo
1602/// assert_eq!(arr[1.. ], [ 1,2,3]);
1603/// assert_eq!(arr[1..3], [ 1,2 ]);
1604/// }
1605/// ```
85aaf69f 1606#[derive(Copy, Clone, PartialEq, Eq)]
85aaf69f 1607#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
1608pub struct RangeTo<Idx> {
1609 /// The upper bound of the range (exclusive).
c34b1796 1610 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
1611 pub end: Idx,
1612}
1613
85aaf69f
SL
1614#[stable(feature = "rust1", since = "1.0.0")]
1615impl<Idx: fmt::Debug> fmt::Debug for RangeTo<Idx> {
1a4d82fc
JJ
1616 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1617 write!(fmt, "..{:?}", self.end)
1618 }
1619}
1620
54a0048b
SL
1621#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
1622impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
1623 /// # Examples
1624 ///
1625 /// ```
1626 /// #![feature(range_contains)]
1627 /// fn main() {
1628 /// assert!( (..5).contains(-1_000_000_000));
1629 /// assert!( (..5).contains(4));
1630 /// assert!( ! (..5).contains(5));
1631 /// }
1632 /// ```
1633 pub fn contains(&self, item: Idx) -> bool {
1634 (item < self.end)
1635 }
1636}
1637
1638/// An inclusive range which is bounded at both ends: { x | start <= x <= end }.
1639/// Use `start...end` (three dots) for its shorthand.
1640///
1641/// See the [`contains()`](#method.contains) method for its characterization.
1642///
1643/// # Examples
1644///
1645/// ```
1646/// #![feature(inclusive_range,inclusive_range_syntax,iter_arith)]
1647/// fn main() {
1648/// assert_eq!((3...5), std::ops::RangeInclusive::NonEmpty{ start: 3, end: 5 });
1649/// assert_eq!(3+4+5, (3...5).sum());
1650///
1651/// let arr = [0, 1, 2, 3];
1652/// assert_eq!(arr[ ...2], [0,1,2 ]);
1653/// assert_eq!(arr[1...2], [ 1,2 ]); // RangeInclusive
1654/// }
1655/// ```
1656#[derive(Copy, Clone, PartialEq, Eq)]
1657#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
1658pub enum RangeInclusive<Idx> {
1659 /// Empty range (iteration has finished)
1660 #[unstable(feature = "inclusive_range",
1661 reason = "recently added, follows RFC",
1662 issue = "28237")]
1663 Empty {
1664 /// The point at which iteration finished
1665 #[unstable(feature = "inclusive_range",
1666 reason = "recently added, follows RFC",
1667 issue = "28237")]
1668 at: Idx
1669 },
1670 /// Non-empty range (iteration will yield value(s))
1671 #[unstable(feature = "inclusive_range",
1672 reason = "recently added, follows RFC",
1673 issue = "28237")]
1674 NonEmpty {
1675 /// The lower bound of the range (inclusive).
1676 #[unstable(feature = "inclusive_range",
1677 reason = "recently added, follows RFC",
1678 issue = "28237")]
1679 start: Idx,
1680 /// The upper bound of the range (inclusive).
1681 #[unstable(feature = "inclusive_range",
1682 reason = "recently added, follows RFC",
1683 issue = "28237")]
1684 end: Idx,
1685 },
1686}
1687
1688#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
1689impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> {
1690 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1691 use self::RangeInclusive::*;
1692
1693 match *self {
1694 Empty { ref at } => write!(fmt, "[empty range @ {:?}]", at),
1695 NonEmpty { ref start, ref end } => write!(fmt, "{:?}...{:?}", start, end),
1696 }
1697 }
1698}
1699
1700#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
1701impl<Idx: PartialOrd + One + Sub<Output=Idx>> From<Range<Idx>> for RangeInclusive<Idx> {
1702 fn from(range: Range<Idx>) -> RangeInclusive<Idx> {
1703 use self::RangeInclusive::*;
1704
1705 if range.start < range.end {
1706 NonEmpty {
1707 start: range.start,
1708 end: range.end - Idx::one() // can't underflow because end > start >= MIN
1709 }
1710 } else {
1711 Empty {
1712 at: range.start
1713 }
1714 }
1715 }
1716}
1717
1718#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
1719impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
1720 /// # Examples
1721 ///
1722 /// ```
1723 /// #![feature(range_contains,inclusive_range_syntax)]
1724 /// fn main() {
1725 /// assert!( ! (3...5).contains(2));
1726 /// assert!( (3...5).contains(3));
1727 /// assert!( (3...5).contains(4));
1728 /// assert!( (3...5).contains(5));
1729 /// assert!( ! (3...5).contains(6));
1730 ///
1731 /// assert!( (3...3).contains(3));
1732 /// assert!( ! (3...2).contains(3));
1733 /// }
1734 /// ```
1735 pub fn contains(&self, item: Idx) -> bool {
1736 if let &RangeInclusive::NonEmpty{ref start, ref end} = self {
1737 (*start <= item) && (item <= *end)
1738 } else { false }
1739 }
1740}
1741
1742/// An inclusive range which is only bounded above: { x | x <= end }.
1743/// Use `...end` (three dots) for its shorthand.
1744///
1745/// See the [`contains()`](#method.contains) method for its characterization.
1746///
1747/// It cannot serve as an iterator because it doesn't have a starting point.
1748///
1749/// # Examples
1750///
1751/// ```
1752/// #![feature(inclusive_range,inclusive_range_syntax)]
1753/// fn main() {
1754/// assert_eq!((...5), std::ops::RangeToInclusive{ end: 5 });
1755///
1756/// let arr = [0, 1, 2, 3];
1757/// assert_eq!(arr[ ...2], [0,1,2 ]); // RangeToInclusive
1758/// assert_eq!(arr[1...2], [ 1,2 ]);
1759/// }
1760/// ```
1761#[derive(Copy, Clone, PartialEq, Eq)]
1762#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
1763pub struct RangeToInclusive<Idx> {
1764 /// The upper bound of the range (inclusive)
1765 #[unstable(feature = "inclusive_range",
1766 reason = "recently added, follows RFC",
1767 issue = "28237")]
1768 pub end: Idx,
1769}
1770
1771#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
1772impl<Idx: fmt::Debug> fmt::Debug for RangeToInclusive<Idx> {
1773 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1774 write!(fmt, "...{:?}", self.end)
1775 }
1776}
1777
1778#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
1779impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
1780 /// # Examples
1781 ///
1782 /// ```
1783 /// #![feature(range_contains,inclusive_range_syntax)]
1784 /// fn main() {
1785 /// assert!( (...5).contains(-1_000_000_000));
1786 /// assert!( (...5).contains(5));
1787 /// assert!( ! (...5).contains(6));
1788 /// }
1789 /// ```
1790 pub fn contains(&self, item: Idx) -> bool {
1791 (item <= self.end)
1792 }
1793}
1794
1795// RangeToInclusive<Idx> cannot impl From<RangeTo<Idx>>
1796// because underflow would be possible with (..0).into()
1797
1a4d82fc 1798/// The `Deref` trait is used to specify the functionality of dereferencing
9cc50fc6 1799/// operations, like `*v`.
1a4d82fc 1800///
c1a9b12d
SL
1801/// `Deref` also enables ['`Deref` coercions'][coercions].
1802///
1803/// [coercions]: ../../book/deref-coercions.html
1804///
c34b1796 1805/// # Examples
1a4d82fc
JJ
1806///
1807/// A struct with a single field which is accessible via dereferencing the
1808/// struct.
1809///
1810/// ```
1a4d82fc
JJ
1811/// use std::ops::Deref;
1812///
1813/// struct DerefExample<T> {
1814/// value: T
1815/// }
1816///
1817/// impl<T> Deref for DerefExample<T> {
1818/// type Target = T;
1819///
b039eaaf 1820/// fn deref(&self) -> &T {
1a4d82fc
JJ
1821/// &self.value
1822/// }
1823/// }
1824///
1825/// fn main() {
1826/// let x = DerefExample { value: 'a' };
1827/// assert_eq!('a', *x);
1828/// }
1829/// ```
d9579d0f 1830#[lang = "deref"]
85aaf69f 1831#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 1832pub trait Deref {
c34b1796 1833 /// The resulting type after dereferencing
85aaf69f 1834 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
1835 type Target: ?Sized;
1836
1837 /// The method called to dereference a value
85aaf69f 1838 #[stable(feature = "rust1", since = "1.0.0")]
e9174d1e 1839 fn deref(&self) -> &Self::Target;
1a4d82fc
JJ
1840}
1841
85aaf69f 1842#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
1843impl<'a, T: ?Sized> Deref for &'a T {
1844 type Target = T;
1845
1846 fn deref(&self) -> &T { *self }
1847}
1848
85aaf69f 1849#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
1850impl<'a, T: ?Sized> Deref for &'a mut T {
1851 type Target = T;
1852
1853 fn deref(&self) -> &T { *self }
1854}
1855
1856/// The `DerefMut` trait is used to specify the functionality of dereferencing
1857/// mutably like `*v = 1;`
1858///
c1a9b12d
SL
1859/// `DerefMut` also enables ['`Deref` coercions'][coercions].
1860///
1861/// [coercions]: ../../book/deref-coercions.html
1862///
c34b1796 1863/// # Examples
1a4d82fc
JJ
1864///
1865/// A struct with a single field which is modifiable via dereferencing the
1866/// struct.
1867///
1868/// ```
1a4d82fc
JJ
1869/// use std::ops::{Deref, DerefMut};
1870///
1871/// struct DerefMutExample<T> {
1872/// value: T
1873/// }
1874///
1875/// impl<T> Deref for DerefMutExample<T> {
1876/// type Target = T;
1877///
1878/// fn deref<'a>(&'a self) -> &'a T {
1879/// &self.value
1880/// }
1881/// }
1882///
1883/// impl<T> DerefMut for DerefMutExample<T> {
1884/// fn deref_mut<'a>(&'a mut self) -> &'a mut T {
1885/// &mut self.value
1886/// }
1887/// }
1888///
1889/// fn main() {
1890/// let mut x = DerefMutExample { value: 'a' };
1891/// *x = 'b';
1892/// assert_eq!('b', *x);
1893/// }
1894/// ```
d9579d0f 1895#[lang = "deref_mut"]
85aaf69f 1896#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
1897pub trait DerefMut: Deref {
1898 /// The method called to mutably dereference a value
85aaf69f 1899 #[stable(feature = "rust1", since = "1.0.0")]
e9174d1e 1900 fn deref_mut(&mut self) -> &mut Self::Target;
1a4d82fc
JJ
1901}
1902
85aaf69f 1903#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
1904impl<'a, T: ?Sized> DerefMut for &'a mut T {
1905 fn deref_mut(&mut self) -> &mut T { *self }
1906}
1907
1908/// A version of the call operator that takes an immutable receiver.
d9579d0f 1909#[lang = "fn"]
85aaf69f
SL
1910#[stable(feature = "rust1", since = "1.0.0")]
1911#[rustc_paren_sugar]
c34b1796
AL
1912#[fundamental] // so that regex can rely that `&str: !FnMut`
1913pub trait Fn<Args> : FnMut<Args> {
1a4d82fc 1914 /// This is called when the call operator is used.
92a42be0 1915 #[unstable(feature = "fn_traits", issue = "29625")]
85aaf69f 1916 extern "rust-call" fn call(&self, args: Args) -> Self::Output;
1a4d82fc
JJ
1917}
1918
1919/// A version of the call operator that takes a mutable receiver.
d9579d0f 1920#[lang = "fn_mut"]
85aaf69f
SL
1921#[stable(feature = "rust1", since = "1.0.0")]
1922#[rustc_paren_sugar]
c34b1796
AL
1923#[fundamental] // so that regex can rely that `&str: !FnMut`
1924pub trait FnMut<Args> : FnOnce<Args> {
1a4d82fc 1925 /// This is called when the call operator is used.
92a42be0 1926 #[unstable(feature = "fn_traits", issue = "29625")]
85aaf69f 1927 extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
1a4d82fc
JJ
1928}
1929
1930/// A version of the call operator that takes a by-value receiver.
d9579d0f 1931#[lang = "fn_once"]
85aaf69f
SL
1932#[stable(feature = "rust1", since = "1.0.0")]
1933#[rustc_paren_sugar]
c34b1796 1934#[fundamental] // so that regex can rely that `&str: !FnMut`
85aaf69f 1935pub trait FnOnce<Args> {
c34b1796 1936 /// The returned type after the call operator is used.
92a42be0 1937 #[unstable(feature = "fn_traits", issue = "29625")]
85aaf69f
SL
1938 type Output;
1939
1a4d82fc 1940 /// This is called when the call operator is used.
92a42be0 1941 #[unstable(feature = "fn_traits", issue = "29625")]
85aaf69f 1942 extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
1a4d82fc
JJ
1943}
1944
c34b1796
AL
1945mod impls {
1946 use marker::Sized;
1947 use super::{Fn, FnMut, FnOnce};
85aaf69f 1948
92a42be0 1949 #[stable(feature = "rust1", since = "1.0.0")]
c34b1796
AL
1950 impl<'a,A,F:?Sized> Fn<A> for &'a F
1951 where F : Fn<A>
1952 {
1953 extern "rust-call" fn call(&self, args: A) -> F::Output {
1954 (**self).call(args)
1955 }
1a4d82fc 1956 }
1a4d82fc 1957
92a42be0 1958 #[stable(feature = "rust1", since = "1.0.0")]
c34b1796
AL
1959 impl<'a,A,F:?Sized> FnMut<A> for &'a F
1960 where F : Fn<A>
1961 {
1962 extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
1963 (**self).call(args)
1964 }
1965 }
1966
92a42be0 1967 #[stable(feature = "rust1", since = "1.0.0")]
c34b1796
AL
1968 impl<'a,A,F:?Sized> FnOnce<A> for &'a F
1969 where F : Fn<A>
1970 {
1971 type Output = F::Output;
1972
1973 extern "rust-call" fn call_once(self, args: A) -> F::Output {
1974 (*self).call(args)
1975 }
1976 }
85aaf69f 1977
92a42be0 1978 #[stable(feature = "rust1", since = "1.0.0")]
c34b1796
AL
1979 impl<'a,A,F:?Sized> FnMut<A> for &'a mut F
1980 where F : FnMut<A>
1981 {
1982 extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
1983 (*self).call_mut(args)
1984 }
1985 }
1986
92a42be0 1987 #[stable(feature = "rust1", since = "1.0.0")]
c34b1796
AL
1988 impl<'a,A,F:?Sized> FnOnce<A> for &'a mut F
1989 where F : FnMut<A>
1990 {
1991 type Output = F::Output;
1992 extern "rust-call" fn call_once(mut self, args: A) -> F::Output {
1993 (*self).call_mut(args)
1994 }
1a4d82fc
JJ
1995 }
1996}
d9579d0f
AL
1997
1998/// Trait that indicates that this is a pointer or a wrapper for one,
1999/// where unsizing can be performed on the pointee.
e9174d1e 2000#[unstable(feature = "coerce_unsized", issue = "27732")]
d9579d0f
AL
2001#[lang="coerce_unsized"]
2002pub trait CoerceUnsized<T> {
2003 // Empty.
2004}
2005
2006// &mut T -> &mut U
92a42be0 2007#[unstable(feature = "coerce_unsized", issue = "27732")]
d9579d0f
AL
2008impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
2009// &mut T -> &U
92a42be0 2010#[unstable(feature = "coerce_unsized", issue = "27732")]
d9579d0f
AL
2011impl<'a, 'b: 'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {}
2012// &mut T -> *mut U
92a42be0 2013#[unstable(feature = "coerce_unsized", issue = "27732")]
d9579d0f
AL
2014impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {}
2015// &mut T -> *const U
92a42be0 2016#[unstable(feature = "coerce_unsized", issue = "27732")]
d9579d0f
AL
2017impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {}
2018
2019// &T -> &U
92a42be0 2020#[unstable(feature = "coerce_unsized", issue = "27732")]
d9579d0f
AL
2021impl<'a, 'b: 'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
2022// &T -> *const U
92a42be0 2023#[unstable(feature = "coerce_unsized", issue = "27732")]
d9579d0f
AL
2024impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {}
2025
2026// *mut T -> *mut U
92a42be0 2027#[unstable(feature = "coerce_unsized", issue = "27732")]
d9579d0f
AL
2028impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
2029// *mut T -> *const U
92a42be0 2030#[unstable(feature = "coerce_unsized", issue = "27732")]
d9579d0f
AL
2031impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
2032
2033// *const T -> *const U
92a42be0 2034#[unstable(feature = "coerce_unsized", issue = "27732")]
d9579d0f 2035impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
c1a9b12d
SL
2036
2037/// Both `in (PLACE) EXPR` and `box EXPR` desugar into expressions
2038/// that allocate an intermediate "place" that holds uninitialized
2039/// state. The desugaring evaluates EXPR, and writes the result at
2040/// the address returned by the `pointer` method of this trait.
2041///
2042/// A `Place` can be thought of as a special representation for a
2043/// hypothetical `&uninit` reference (which Rust cannot currently
2044/// express directly). That is, it represents a pointer to
2045/// uninitialized storage.
2046///
2047/// The client is responsible for two steps: First, initializing the
2048/// payload (it can access its address via `pointer`). Second,
2049/// converting the agent to an instance of the owning pointer, via the
2050/// appropriate `finalize` method (see the `InPlace`.
2051///
2052/// If evaluating EXPR fails, then the destructor for the
2053/// implementation of Place to clean up any intermediate state
2054/// (e.g. deallocate box storage, pop a stack, etc).
e9174d1e 2055#[unstable(feature = "placement_new_protocol", issue = "27779")]
c1a9b12d
SL
2056pub trait Place<Data: ?Sized> {
2057 /// Returns the address where the input value will be written.
2058 /// Note that the data at this address is generally uninitialized,
2059 /// and thus one should use `ptr::write` for initializing it.
2060 fn pointer(&mut self) -> *mut Data;
2061}
2062
2063/// Interface to implementations of `in (PLACE) EXPR`.
2064///
2065/// `in (PLACE) EXPR` effectively desugars into:
2066///
2067/// ```rust,ignore
2068/// let p = PLACE;
2069/// let mut place = Placer::make_place(p);
2070/// let raw_place = Place::pointer(&mut place);
2071/// let value = EXPR;
2072/// unsafe {
2073/// std::ptr::write(raw_place, value);
2074/// InPlace::finalize(place)
2075/// }
2076/// ```
2077///
2078/// The type of `in (PLACE) EXPR` is derived from the type of `PLACE`;
2079/// if the type of `PLACE` is `P`, then the final type of the whole
2080/// expression is `P::Place::Owner` (see the `InPlace` and `Boxed`
2081/// traits).
2082///
2083/// Values for types implementing this trait usually are transient
2084/// intermediate values (e.g. the return value of `Vec::emplace_back`)
2085/// or `Copy`, since the `make_place` method takes `self` by value.
e9174d1e 2086#[unstable(feature = "placement_new_protocol", issue = "27779")]
c1a9b12d
SL
2087pub trait Placer<Data: ?Sized> {
2088 /// `Place` is the intermedate agent guarding the
2089 /// uninitialized state for `Data`.
2090 type Place: InPlace<Data>;
2091
2092 /// Creates a fresh place from `self`.
2093 fn make_place(self) -> Self::Place;
2094}
2095
2096/// Specialization of `Place` trait supporting `in (PLACE) EXPR`.
e9174d1e 2097#[unstable(feature = "placement_new_protocol", issue = "27779")]
c1a9b12d
SL
2098pub trait InPlace<Data: ?Sized>: Place<Data> {
2099 /// `Owner` is the type of the end value of `in (PLACE) EXPR`
2100 ///
2101 /// Note that when `in (PLACE) EXPR` is solely used for
2102 /// side-effecting an existing data-structure,
2103 /// e.g. `Vec::emplace_back`, then `Owner` need not carry any
2104 /// information at all (e.g. it can be the unit type `()` in that
2105 /// case).
2106 type Owner;
2107
2108 /// Converts self into the final value, shifting
2109 /// deallocation/cleanup responsibilities (if any remain), over to
2110 /// the returned instance of `Owner` and forgetting self.
2111 unsafe fn finalize(self) -> Self::Owner;
2112}
2113
2114/// Core trait for the `box EXPR` form.
2115///
2116/// `box EXPR` effectively desugars into:
2117///
2118/// ```rust,ignore
2119/// let mut place = BoxPlace::make_place();
2120/// let raw_place = Place::pointer(&mut place);
2121/// let value = EXPR;
2122/// unsafe {
2123/// ::std::ptr::write(raw_place, value);
2124/// Boxed::finalize(place)
2125/// }
2126/// ```
2127///
2128/// The type of `box EXPR` is supplied from its surrounding
2129/// context; in the above expansion, the result type `T` is used
2130/// to determine which implementation of `Boxed` to use, and that
2131/// `<T as Boxed>` in turn dictates determines which
2132/// implementation of `BoxPlace` to use, namely:
2133/// `<<T as Boxed>::Place as BoxPlace>`.
e9174d1e 2134#[unstable(feature = "placement_new_protocol", issue = "27779")]
c1a9b12d
SL
2135pub trait Boxed {
2136 /// The kind of data that is stored in this kind of box.
2137 type Data; /* (`Data` unused b/c cannot yet express below bound.) */
2138 /// The place that will negotiate the storage of the data.
2139 type Place: BoxPlace<Self::Data>;
2140
2141 /// Converts filled place into final owning value, shifting
2142 /// deallocation/cleanup responsibilities (if any remain), over to
2143 /// returned instance of `Self` and forgetting `filled`.
2144 unsafe fn finalize(filled: Self::Place) -> Self;
2145}
2146
2147/// Specialization of `Place` trait supporting `box EXPR`.
e9174d1e 2148#[unstable(feature = "placement_new_protocol", issue = "27779")]
c1a9b12d
SL
2149pub trait BoxPlace<Data: ?Sized> : Place<Data> {
2150 /// Creates a globally fresh place.
2151 fn make_place() -> Self;
2152}