]>
Commit | Line | Data |
---|---|---|
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 | 70 | use cmp::PartialOrd; |
1a4d82fc | 71 | use fmt; |
54a0048b SL |
72 | use convert::From; |
73 | use marker::{Sized, Unsize}; | |
74 | use 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 | 99 | pub 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 | |
117 | macro_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 | |
133 | macro_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 | 194 | pub 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 | ||
204 | macro_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 | 218 | add_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 | 247 | pub 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 | ||
257 | macro_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 | 271 | sub_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 | 300 | pub 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 | ||
310 | macro_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 | 324 | mul_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 | 353 | pub 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 | 363 | macro_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 |
379 | div_impl_integer! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } |
380 | ||
381 | macro_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 | ||
395 | div_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 | 424 | pub 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 | 434 | macro_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 |
450 | rem_impl_integer! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } |
451 | ||
e9174d1e SL |
452 | macro_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 | 466 | rem_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 | 495 | pub 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 | ||
507 | macro_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 |
521 | macro_rules! neg_impl_numeric { |
522 | ($($t:ty)*) => { neg_impl_core!{ x => -x, $($t)*} } | |
1a4d82fc JJ |
523 | } |
524 | ||
c34b1796 AL |
525 | macro_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 } |
533 | neg_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 | 562 | pub 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 | ||
572 | macro_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 | 586 | not_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 | 615 | pub 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 | ||
625 | macro_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 | 639 | bitand_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 | 668 | pub 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 | ||
678 | macro_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 | 692 | bitor_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 | 721 | pub 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 | ||
731 | macro_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 | 745 | bitxor_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 | 774 | pub 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 | ||
784 | macro_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 | ||
800 | macro_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 | 816 | shl_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 | 845 | pub 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 | ||
855 | macro_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 | ||
871 | macro_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 | 887 | shr_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 |
915 | pub 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 |
921 | macro_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 |
931 | add_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 |
959 | pub 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 |
965 | macro_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 |
975 | sub_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 |
1003 | pub 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 |
1009 | macro_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 |
1019 | mul_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 |
1047 | pub 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 |
1053 | macro_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 |
1063 | div_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 |
1091 | pub 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 |
1097 | macro_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 |
1107 | rem_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 |
1135 | pub 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 |
1141 | macro_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 |
1151 | bitand_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 |
1179 | pub 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 |
1185 | macro_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 |
1195 | bitor_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 |
1223 | pub 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 |
1229 | macro_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 |
1239 | bitxor_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 |
1267 | pub 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 |
1273 | macro_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 |
1285 | macro_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 |
1301 | shl_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 |
1329 | pub 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 |
1335 | macro_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 |
1347 | macro_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 |
1363 | shr_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")] | |
1396 | pub 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")] | |
1443 | pub 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")] |
1469 | pub struct RangeFull; | |
1a4d82fc | 1470 | |
85aaf69f SL |
1471 | #[stable(feature = "rust1", since = "1.0.0")] |
1472 | impl 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 |
1500 | pub 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")] |
1510 | impl<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")] |
1517 | impl<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 |
1559 | pub 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")] |
1566 | impl<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")] |
1573 | impl<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 |
1608 | pub 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")] |
1615 | impl<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")] |
1622 | impl<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")] | |
1658 | pub 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")] | |
1689 | impl<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")] | |
1701 | impl<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")] | |
1719 | impl<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")] | |
1763 | pub 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")] | |
1772 | impl<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")] | |
1779 | impl<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 | 1832 | pub 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 |
1843 | impl<'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 |
1850 | impl<'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 |
1897 | pub 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 |
1904 | impl<'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` |
1913 | pub 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` |
1924 | pub 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 | 1935 | pub 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 |
1945 | mod 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"] |
2002 | pub trait CoerceUnsized<T> { | |
2003 | // Empty. | |
2004 | } | |
2005 | ||
2006 | // &mut T -> &mut U | |
92a42be0 | 2007 | #[unstable(feature = "coerce_unsized", issue = "27732")] |
d9579d0f AL |
2008 | impl<'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 |
2011 | impl<'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 |
2014 | impl<'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 |
2017 | impl<'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 |
2021 | impl<'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 |
2024 | impl<'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 |
2028 | impl<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 |
2031 | impl<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 | 2035 | impl<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 |
2056 | pub 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 |
2087 | pub 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 |
2098 | pub 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 |
2135 | pub 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 |
2149 | pub trait BoxPlace<Data: ?Sized> : Place<Data> { |
2150 | /// Creates a globally fresh place. | |
2151 | fn make_place() -> Self; | |
2152 | } |