]> git.lizzy.rs Git - rust.git/blob - src/libcore/ops/mod.rs
Move Index to module.
[rust.git] / src / libcore / ops / mod.rs
1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Overloadable operators.
12 //!
13 //! Implementing these traits allows you to overload certain operators.
14 //!
15 //! Some of these traits are imported by the prelude, so they are available in
16 //! every Rust program. Only operators backed by traits can be overloaded. For
17 //! example, the addition operator (`+`) can be overloaded through the [`Add`]
18 //! trait, but since the assignment operator (`=`) has no backing trait, there
19 //! is no way of overloading its semantics. Additionally, this module does not
20 //! provide any mechanism to create new operators. If traitless overloading or
21 //! custom operators are required, you should look toward macros or compiler
22 //! plugins to extend Rust's syntax.
23 //!
24 //! Note that the `&&` and `||` operators short-circuit, i.e. they only
25 //! evaluate their second operand if it contributes to the result. Since this
26 //! behavior is not enforceable by traits, `&&` and `||` are not supported as
27 //! overloadable operators.
28 //!
29 //! Many of the operators take their operands by value. In non-generic
30 //! contexts involving built-in types, this is usually not a problem.
31 //! However, using these operators in generic code, requires some
32 //! attention if values have to be reused as opposed to letting the operators
33 //! consume them. One option is to occasionally use [`clone`].
34 //! Another option is to rely on the types involved providing additional
35 //! operator implementations for references. For example, for a user-defined
36 //! type `T` which is supposed to support addition, it is probably a good
37 //! idea to have both `T` and `&T` implement the traits [`Add<T>`][`Add`] and
38 //! [`Add<&T>`][`Add`] so that generic code can be written without unnecessary
39 //! cloning.
40 //!
41 //! # Examples
42 //!
43 //! This example creates a `Point` struct that implements [`Add`] and [`Sub`],
44 //! and then demonstrates adding and subtracting two `Point`s.
45 //!
46 //! ```rust
47 //! use std::ops::{Add, Sub};
48 //!
49 //! #[derive(Debug)]
50 //! struct Point {
51 //!     x: i32,
52 //!     y: i32,
53 //! }
54 //!
55 //! impl Add for Point {
56 //!     type Output = Point;
57 //!
58 //!     fn add(self, other: Point) -> Point {
59 //!         Point {x: self.x + other.x, y: self.y + other.y}
60 //!     }
61 //! }
62 //!
63 //! impl Sub for Point {
64 //!     type Output = Point;
65 //!
66 //!     fn sub(self, other: Point) -> Point {
67 //!         Point {x: self.x - other.x, y: self.y - other.y}
68 //!     }
69 //! }
70 //! fn main() {
71 //!     println!("{:?}", Point {x: 1, y: 0} + Point {x: 2, y: 3});
72 //!     println!("{:?}", Point {x: 1, y: 0} - Point {x: 2, y: 3});
73 //! }
74 //! ```
75 //!
76 //! See the documentation for each trait for an example implementation.
77 //!
78 //! The [`Fn`], [`FnMut`], and [`FnOnce`] traits are implemented by types that can be
79 //! invoked like functions. Note that [`Fn`] takes `&self`, [`FnMut`] takes `&mut
80 //! self` and [`FnOnce`] takes `self`. These correspond to the three kinds of
81 //! methods that can be invoked on an instance: call-by-reference,
82 //! call-by-mutable-reference, and call-by-value. The most common use of these
83 //! traits is to act as bounds to higher-level functions that take functions or
84 //! closures as arguments.
85 //!
86 //! Taking a [`Fn`] as a parameter:
87 //!
88 //! ```rust
89 //! fn call_with_one<F>(func: F) -> usize
90 //!     where F: Fn(usize) -> usize
91 //! {
92 //!     func(1)
93 //! }
94 //!
95 //! let double = |x| x * 2;
96 //! assert_eq!(call_with_one(double), 2);
97 //! ```
98 //!
99 //! Taking a [`FnMut`] as a parameter:
100 //!
101 //! ```rust
102 //! fn do_twice<F>(mut func: F)
103 //!     where F: FnMut()
104 //! {
105 //!     func();
106 //!     func();
107 //! }
108 //!
109 //! let mut x: usize = 1;
110 //! {
111 //!     let add_two_to_x = || x += 2;
112 //!     do_twice(add_two_to_x);
113 //! }
114 //!
115 //! assert_eq!(x, 5);
116 //! ```
117 //!
118 //! Taking a [`FnOnce`] as a parameter:
119 //!
120 //! ```rust
121 //! fn consume_with_relish<F>(func: F)
122 //!     where F: FnOnce() -> String
123 //! {
124 //!     // `func` consumes its captured variables, so it cannot be run more
125 //!     // than once
126 //!     println!("Consumed: {}", func());
127 //!
128 //!     println!("Delicious!");
129 //!
130 //!     // Attempting to invoke `func()` again will throw a `use of moved
131 //!     // value` error for `func`
132 //! }
133 //!
134 //! let x = String::from("x");
135 //! let consume_and_return_x = move || x;
136 //! consume_with_relish(consume_and_return_x);
137 //!
138 //! // `consume_and_return_x` can no longer be invoked at this point
139 //! ```
140 //!
141 //! [`Fn`]: trait.Fn.html
142 //! [`FnMut`]: trait.FnMut.html
143 //! [`FnOnce`]: trait.FnOnce.html
144 //! [`Add`]: trait.Add.html
145 //! [`Sub`]: trait.Sub.html
146 //! [`clone`]: ../clone/trait.Clone.html#tymethod.clone
147
148 #![stable(feature = "rust1", since = "1.0.0")]
149
150 mod arith;
151 mod bit;
152 mod deref;
153 mod function;
154 mod index;
155 mod place;
156 mod range;
157 mod try;
158
159 #[stable(feature = "rust1", since = "1.0.0")]
160 pub use self::arith::{Add, Sub, Mul, Div, Rem, Neg};
161 #[stable(feature = "op_assign_traits", since = "1.8.0")]
162 pub use self::arith::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
163
164 #[stable(feature = "rust1", since = "1.0.0")]
165 pub use self::bit::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
166 #[stable(feature = "op_assign_traits", since = "1.8.0")]
167 pub use self::bit::{BitAndAssign, BitOrAssign, BitXorAssign, ShlAssign, ShrAssign};
168
169 #[stable(feature = "rust1", since = "1.0.0")]
170 pub use self::deref::{Deref, DerefMut};
171
172 #[stable(feature = "rust1", since = "1.0.0")]
173 pub use self::function::{Fn, FnMut, FnOnce};
174
175 #[stable(feature = "rust1", since = "1.0.0")]
176 pub use self::index::{Index, IndexMut};
177
178 #[stable(feature = "rust1", since = "1.0.0")]
179 pub use self::range::{Range, RangeFrom, RangeFull, RangeTo};
180
181 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
182 pub use self::range::{RangeInclusive, RangeToInclusive};
183
184 #[unstable(feature = "question_mark_carrier", issue = "31436")]
185 #[cfg(stage0)]
186 pub use self::try::Carrier;
187 #[unstable(feature = "try_trait", issue = "42327")]
188 pub use self::try::Try;
189
190 #[unstable(feature = "placement_new_protocol", issue = "27779")]
191 pub use self::place::{Place, Placer, InPlace, Boxed, BoxPlace};
192
193 use marker::Unsize;
194
195 /// The `Drop` trait is used to run some code when a value goes out of scope.
196 /// This is sometimes called a 'destructor'.
197 ///
198 /// When a value goes out of scope, if it implements this trait, it will have
199 /// its `drop` method called. Then any fields the value contains will also
200 /// be dropped recursively.
201 ///
202 /// Because of the recursive dropping, you do not need to implement this trait
203 /// unless your type needs its own destructor logic.
204 ///
205 /// # Examples
206 ///
207 /// A trivial implementation of `Drop`. The `drop` method is called when `_x`
208 /// goes out of scope, and therefore `main` prints `Dropping!`.
209 ///
210 /// ```
211 /// struct HasDrop;
212 ///
213 /// impl Drop for HasDrop {
214 ///     fn drop(&mut self) {
215 ///         println!("Dropping!");
216 ///     }
217 /// }
218 ///
219 /// fn main() {
220 ///     let _x = HasDrop;
221 /// }
222 /// ```
223 ///
224 /// Showing the recursive nature of `Drop`. When `outer` goes out of scope, the
225 /// `drop` method will be called first for `Outer`, then for `Inner`. Therefore
226 /// `main` prints `Dropping Outer!` and then `Dropping Inner!`.
227 ///
228 /// ```
229 /// struct Inner;
230 /// struct Outer(Inner);
231 ///
232 /// impl Drop for Inner {
233 ///     fn drop(&mut self) {
234 ///         println!("Dropping Inner!");
235 ///     }
236 /// }
237 ///
238 /// impl Drop for Outer {
239 ///     fn drop(&mut self) {
240 ///         println!("Dropping Outer!");
241 ///     }
242 /// }
243 ///
244 /// fn main() {
245 ///     let _x = Outer(Inner);
246 /// }
247 /// ```
248 ///
249 /// Because variables are dropped in the reverse order they are declared,
250 /// `main` will print `Declared second!` and then `Declared first!`.
251 ///
252 /// ```
253 /// struct PrintOnDrop(&'static str);
254 ///
255 /// fn main() {
256 ///     let _first = PrintOnDrop("Declared first!");
257 ///     let _second = PrintOnDrop("Declared second!");
258 /// }
259 /// ```
260 #[lang = "drop"]
261 #[stable(feature = "rust1", since = "1.0.0")]
262 pub trait Drop {
263     /// A method called when the value goes out of scope.
264     ///
265     /// When this method has been called, `self` has not yet been deallocated.
266     /// If it were, `self` would be a dangling reference.
267     ///
268     /// After this function is over, the memory of `self` will be deallocated.
269     ///
270     /// This function cannot be called explicitly. This is compiler error
271     /// [E0040]. However, the [`std::mem::drop`] function in the prelude can be
272     /// used to call the argument's `Drop` implementation.
273     ///
274     /// [E0040]: ../../error-index.html#E0040
275     /// [`std::mem::drop`]: ../../std/mem/fn.drop.html
276     ///
277     /// # Panics
278     ///
279     /// Given that a `panic!` will call `drop()` as it unwinds, any `panic!` in
280     /// a `drop()` implementation will likely abort.
281     #[stable(feature = "rust1", since = "1.0.0")]
282     fn drop(&mut self);
283 }
284
285 /// Trait that indicates that this is a pointer or a wrapper for one,
286 /// where unsizing can be performed on the pointee.
287 ///
288 /// See the [DST coercion RfC][dst-coerce] and [the nomicon entry on coercion][nomicon-coerce]
289 /// for more details.
290 ///
291 /// For builtin pointer types, pointers to `T` will coerce to pointers to `U` if `T: Unsize<U>`
292 /// by converting from a thin pointer to a fat pointer.
293 ///
294 /// For custom types, the coercion here works by coercing `Foo<T>` to `Foo<U>`
295 /// provided an impl of `CoerceUnsized<Foo<U>> for Foo<T>` exists.
296 /// Such an impl can only be written if `Foo<T>` has only a single non-phantomdata
297 /// field involving `T`. If the type of that field is `Bar<T>`, an implementation
298 /// of `CoerceUnsized<Bar<U>> for Bar<T>` must exist. The coercion will work by
299 /// by coercing the `Bar<T>` field into `Bar<U>` and filling in the rest of the fields
300 /// from `Foo<T>` to create a `Foo<U>`. This will effectively drill down to a pointer
301 /// field and coerce that.
302 ///
303 /// Generally, for smart pointers you will implement
304 /// `CoerceUnsized<Ptr<U>> for Ptr<T> where T: Unsize<U>, U: ?Sized`, with an
305 /// optional `?Sized` bound on `T` itself. For wrapper types that directly embed `T`
306 /// like `Cell<T>` and `RefCell<T>`, you
307 /// can directly implement `CoerceUnsized<Wrap<U>> for Wrap<T> where T: CoerceUnsized<U>`.
308 /// This will let coercions of types like `Cell<Box<T>>` work.
309 ///
310 /// [`Unsize`][unsize] is used to mark types which can be coerced to DSTs if behind
311 /// pointers. It is implemented automatically by the compiler.
312 ///
313 /// [dst-coerce]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
314 /// [unsize]: ../marker/trait.Unsize.html
315 /// [nomicon-coerce]: ../../nomicon/coercions.html
316 #[unstable(feature = "coerce_unsized", issue = "27732")]
317 #[lang="coerce_unsized"]
318 pub trait CoerceUnsized<T> {
319     // Empty.
320 }
321
322 // &mut T -> &mut U
323 #[unstable(feature = "coerce_unsized", issue = "27732")]
324 impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
325 // &mut T -> &U
326 #[unstable(feature = "coerce_unsized", issue = "27732")]
327 impl<'a, 'b: 'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {}
328 // &mut T -> *mut U
329 #[unstable(feature = "coerce_unsized", issue = "27732")]
330 impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {}
331 // &mut T -> *const U
332 #[unstable(feature = "coerce_unsized", issue = "27732")]
333 impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {}
334
335 // &T -> &U
336 #[unstable(feature = "coerce_unsized", issue = "27732")]
337 impl<'a, 'b: 'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
338 // &T -> *const U
339 #[unstable(feature = "coerce_unsized", issue = "27732")]
340 impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {}
341
342 // *mut T -> *mut U
343 #[unstable(feature = "coerce_unsized", issue = "27732")]
344 impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
345 // *mut T -> *const U
346 #[unstable(feature = "coerce_unsized", issue = "27732")]
347 impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
348
349 // *const T -> *const U
350 #[unstable(feature = "coerce_unsized", issue = "27732")]
351 impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}