rust/src/libcore/ops.rs

2166 lines
59 KiB
Rust
Raw Normal View History

// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Overloadable operators.
//!
//! Implementing these traits allows you to overload certain operators.
//!
//! Some of these traits are imported by the prelude, so they are available in
//! every Rust program. Only operators backed by traits can be overloaded. For
//! example, the addition operator (`+`) can be overloaded through the `Add`
//! trait, but since the assignment operator (`=`) has no backing trait, there
//! is no way of overloading its semantics. Additionally, this module does not
//! provide any mechanism to create new operators. If traitless overloading or
//! custom operators are required, you should look toward macros or compiler
//! plugins to extend Rust's syntax.
//!
//! Many of the operators take their operands by value. In non-generic
//! contexts involving built-in types, this is usually not a problem.
//! However, using these operators in generic code, requires some
//! attention if values have to be reused as opposed to letting the operators
//! consume them. One option is to occasionally use `clone()`.
//! Another option is to rely on the types involved providing additional
//! operator implementations for references. For example, for a user-defined
//! type `T` which is supposed to support addition, it is probably a good
//! idea to have both `T` and `&T` implement the traits `Add<T>` and `Add<&T>`
//! so that generic code can be written without unnecessary cloning.
//!
//! # Examples
//!
//! This example creates a `Point` struct that implements `Add` and `Sub`, and
//! then demonstrates adding and subtracting two `Point`s.
//!
//! ```rust
//! use std::ops::{Add, Sub};
//!
2015-01-28 08:34:18 -05:00
//! #[derive(Debug)]
//! struct Point {
2015-02-15 10:22:43 -05:00
//! x: i32,
//! y: i32,
//! }
//!
2014-12-31 15:45:13 -05:00
//! impl Add for Point {
//! type Output = Point;
//!
2014-12-01 19:10:12 -05:00
//! fn add(self, other: Point) -> Point {
//! Point {x: self.x + other.x, y: self.y + other.y}
//! }
//! }
//!
2014-12-31 15:45:13 -05:00
//! impl Sub for Point {
//! type Output = Point;
//!
2014-12-01 19:10:12 -05:00
//! fn sub(self, other: Point) -> Point {
//! Point {x: self.x - other.x, y: self.y - other.y}
//! }
//! }
//! fn main() {
2015-01-06 16:16:35 -08:00
//! println!("{:?}", Point {x: 1, y: 0} + Point {x: 2, y: 3});
//! println!("{:?}", Point {x: 1, y: 0} - Point {x: 2, y: 3});
//! }
//! ```
//!
//! See the documentation for each trait for a minimum implementation that
//! prints something to the screen.
2015-01-23 21:48:20 -08:00
#![stable(feature = "rust1", since = "1.0.0")]
use cmp::PartialOrd;
2015-01-07 17:21:09 +13:00
use fmt;
use marker::{Sized, Unsize};
/// The `Drop` trait is used to run some code when a value goes out of scope.
/// This is sometimes called a 'destructor'.
///
/// # Examples
///
/// A trivial implementation of `Drop`. The `drop` method is called when `_x`
/// goes out of scope, and therefore `main` prints `Dropping!`.
///
/// ```
/// struct HasDrop;
///
/// impl Drop for HasDrop {
/// fn drop(&mut self) {
/// println!("Dropping!");
/// }
/// }
///
/// fn main() {
/// let _x = HasDrop;
/// }
/// ```
#[lang = "drop"]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Drop {
/// A method called when the value goes out of scope.
2016-01-04 12:19:48 -05:00
///
/// When this method has been called, `self` has not yet been deallocated.
/// If it were, `self` would be a dangling reference.
///
/// After this function is over, the memory of `self` will be deallocated.
///
/// # Panics
///
/// Given that a `panic!` will call `drop()` as it unwinds, any `panic!` in
/// a `drop()` implementation will likely abort.
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2013-09-16 21:18:07 -04:00
fn drop(&mut self);
}
// implements the unary operator "op &T"
// based on "op T" where T is expected to be `Copy`able
macro_rules! forward_ref_unop {
(impl $imp:ident, $method:ident for $t:ty) => {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> $imp for &'a $t {
type Output = <$t as $imp>::Output;
#[inline]
fn $method(self) -> <$t as $imp>::Output {
$imp::$method(*self)
}
}
}
}
// implements binary operators "&T op U", "T op &U", "&T op &U"
// based on "T op U" where T and U are expected to be `Copy`able
macro_rules! forward_ref_binop {
(impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> $imp<$u> for &'a $t {
type Output = <$t as $imp<$u>>::Output;
#[inline]
fn $method(self, other: $u) -> <$t as $imp<$u>>::Output {
$imp::$method(*self, other)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> $imp<&'a $u> for $t {
type Output = <$t as $imp<$u>>::Output;
#[inline]
fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
$imp::$method(self, *other)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b> $imp<&'a $u> for &'b $t {
type Output = <$t as $imp<$u>>::Output;
#[inline]
fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
$imp::$method(*self, *other)
}
}
}
}
/// The `Add` trait is used to specify the functionality of `+`.
///
/// # Examples
///
/// A trivial implementation of `Add`. When `Foo + Foo` happens, it ends up
/// calling `add`, and therefore, `main` prints `Adding!`.
///
/// ```
/// use std::ops::Add;
///
/// struct Foo;
///
2014-12-31 15:45:13 -05:00
/// impl Add for Foo {
/// type Output = Foo;
///
2014-12-01 19:10:12 -05:00
/// fn add(self, _rhs: Foo) -> Foo {
/// println!("Adding!");
/// self
/// }
/// }
///
/// fn main() {
/// Foo + Foo;
/// }
/// ```
#[lang = "add"]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
pub trait Add<RHS=Self> {
/// The resulting type after applying the `+` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
type Output;
/// The method for the `+` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
fn add(self, rhs: RHS) -> Self::Output;
}
macro_rules! add_impl {
($($t:ty)*) => ($(
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
impl Add for $t {
type Output = $t;
#[inline]
#[rustc_inherit_overflow_checks]
fn add(self, other: $t) -> $t { self + other }
}
forward_ref_binop! { impl Add, add for $t, $t }
)*)
}
2015-02-15 10:22:43 -05:00
add_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
/// The `Sub` trait is used to specify the functionality of `-`.
///
/// # Examples
///
/// A trivial implementation of `Sub`. When `Foo - Foo` happens, it ends up
/// calling `sub`, and therefore, `main` prints `Subtracting!`.
///
/// ```
/// use std::ops::Sub;
///
/// struct Foo;
///
2014-12-31 15:45:13 -05:00
/// impl Sub for Foo {
/// type Output = Foo;
///
2014-12-01 19:10:12 -05:00
/// fn sub(self, _rhs: Foo) -> Foo {
/// println!("Subtracting!");
2014-12-01 19:10:12 -05:00
/// self
/// }
/// }
///
/// fn main() {
/// Foo - Foo;
/// }
/// ```
#[lang = "sub"]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
pub trait Sub<RHS=Self> {
/// The resulting type after applying the `-` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
type Output;
/// The method for the `-` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
fn sub(self, rhs: RHS) -> Self::Output;
}
macro_rules! sub_impl {
($($t:ty)*) => ($(
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
impl Sub for $t {
type Output = $t;
#[inline]
#[rustc_inherit_overflow_checks]
fn sub(self, other: $t) -> $t { self - other }
}
forward_ref_binop! { impl Sub, sub for $t, $t }
)*)
}
2015-02-15 10:22:43 -05:00
sub_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
/// The `Mul` trait is used to specify the functionality of `*`.
///
/// # Examples
///
/// A trivial implementation of `Mul`. When `Foo * Foo` happens, it ends up
/// calling `mul`, and therefore, `main` prints `Multiplying!`.
///
/// ```
/// use std::ops::Mul;
///
/// struct Foo;
///
2014-12-31 15:45:13 -05:00
/// impl Mul for Foo {
/// type Output = Foo;
///
2014-12-01 19:10:12 -05:00
/// fn mul(self, _rhs: Foo) -> Foo {
/// println!("Multiplying!");
2014-12-01 19:10:12 -05:00
/// self
/// }
/// }
///
/// fn main() {
/// Foo * Foo;
/// }
/// ```
#[lang = "mul"]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
pub trait Mul<RHS=Self> {
/// The resulting type after applying the `*` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
type Output;
/// The method for the `*` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
fn mul(self, rhs: RHS) -> Self::Output;
}
macro_rules! mul_impl {
($($t:ty)*) => ($(
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
impl Mul for $t {
type Output = $t;
#[inline]
#[rustc_inherit_overflow_checks]
fn mul(self, other: $t) -> $t { self * other }
}
forward_ref_binop! { impl Mul, mul for $t, $t }
)*)
}
2015-02-15 10:22:43 -05:00
mul_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
/// The `Div` trait is used to specify the functionality of `/`.
///
/// # Examples
///
/// A trivial implementation of `Div`. When `Foo / Foo` happens, it ends up
/// calling `div`, and therefore, `main` prints `Dividing!`.
///
/// ```
/// use std::ops::Div;
///
/// struct Foo;
///
2014-12-31 15:45:13 -05:00
/// impl Div for Foo {
/// type Output = Foo;
///
2014-12-01 19:10:12 -05:00
/// fn div(self, _rhs: Foo) -> Foo {
/// println!("Dividing!");
2014-12-01 19:10:12 -05:00
/// self
/// }
/// }
///
/// fn main() {
/// Foo / Foo;
/// }
/// ```
#[lang = "div"]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
pub trait Div<RHS=Self> {
/// The resulting type after applying the `/` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
type Output;
/// The method for the `/` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
fn div(self, rhs: RHS) -> Self::Output;
}
macro_rules! div_impl_integer {
($($t:ty)*) => ($(
/// This operation rounds towards zero, truncating any
/// fractional part of the exact result.
#[stable(feature = "rust1", since = "1.0.0")]
impl Div for $t {
type Output = $t;
#[inline]
fn div(self, other: $t) -> $t { self / other }
}
forward_ref_binop! { impl Div, div for $t, $t }
)*)
}
div_impl_integer! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
macro_rules! div_impl_float {
($($t:ty)*) => ($(
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
impl Div for $t {
type Output = $t;
#[inline]
fn div(self, other: $t) -> $t { self / other }
}
forward_ref_binop! { impl Div, div for $t, $t }
)*)
}
div_impl_float! { f32 f64 }
/// The `Rem` trait is used to specify the functionality of `%`.
///
/// # Examples
///
/// A trivial implementation of `Rem`. When `Foo % Foo` happens, it ends up
/// calling `rem`, and therefore, `main` prints `Remainder-ing!`.
///
/// ```
/// use std::ops::Rem;
///
/// struct Foo;
///
2014-12-31 15:45:13 -05:00
/// impl Rem for Foo {
/// type Output = Foo;
///
2014-12-01 19:10:12 -05:00
/// fn rem(self, _rhs: Foo) -> Foo {
/// println!("Remainder-ing!");
2014-12-01 19:10:12 -05:00
/// self
/// }
/// }
///
/// fn main() {
/// Foo % Foo;
/// }
/// ```
#[lang = "rem"]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
pub trait Rem<RHS=Self> {
/// The resulting type after applying the `%` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
type Output = Self;
/// The method for the `%` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
fn rem(self, rhs: RHS) -> Self::Output;
}
macro_rules! rem_impl_integer {
($($t:ty)*) => ($(
/// This operation satisfies `n % d == n - (n / d) * d`. The
/// result has the same sign as the left operand.
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
impl Rem for $t {
type Output = $t;
#[inline]
fn rem(self, other: $t) -> $t { self % other }
}
forward_ref_binop! { impl Rem, rem for $t, $t }
)*)
}
rem_impl_integer! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
2014-12-31 15:45:13 -05:00
macro_rules! rem_impl_float {
($($t:ty)*) => ($(
#[stable(feature = "rust1", since = "1.0.0")]
impl Rem for $t {
type Output = $t;
#[inline]
fn rem(self, other: $t) -> $t { self % other }
}
forward_ref_binop! { impl Rem, rem for $t, $t }
)*)
}
rem_impl_float! { f32 f64 }
/// The `Neg` trait is used to specify the functionality of unary `-`.
///
/// # Examples
///
/// A trivial implementation of `Neg`. When `-Foo` happens, it ends up calling
/// `neg`, and therefore, `main` prints `Negating!`.
///
/// ```
/// use std::ops::Neg;
///
/// struct Foo;
///
2015-01-02 22:56:24 -05:00
/// impl Neg for Foo {
/// type Output = Foo;
///
/// fn neg(self) -> Foo {
/// println!("Negating!");
/// self
/// }
/// }
///
/// fn main() {
/// -Foo;
/// }
/// ```
#[lang = "neg"]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-02 22:56:24 -05:00
pub trait Neg {
/// The resulting type after applying the `-` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-02 22:56:24 -05:00
type Output;
/// The method for the unary `-` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-02 22:56:24 -05:00
fn neg(self) -> Self::Output;
}
macro_rules! neg_impl_core {
($id:ident => $body:expr, $($t:ty)*) => ($(
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-02 22:56:24 -05:00
impl Neg for $t {
type Output = $t;
#[inline]
#[rustc_inherit_overflow_checks]
fn neg(self) -> $t { let $id = self; $body }
}
forward_ref_unop! { impl Neg, neg for $t }
)*)
}
macro_rules! neg_impl_numeric {
($($t:ty)*) => { neg_impl_core!{ x => -x, $($t)*} }
}
macro_rules! neg_impl_unsigned {
($($t:ty)*) => {
neg_impl_core!{ x => {
!x.wrapping_add(1)
}, $($t)*} }
}
// neg_impl_unsigned! { usize u8 u16 u32 u64 }
neg_impl_numeric! { isize i8 i16 i32 i64 f32 f64 }
/// The `Not` trait is used to specify the functionality of unary `!`.
///
/// # Examples
///
/// A trivial implementation of `Not`. When `!Foo` happens, it ends up calling
/// `not`, and therefore, `main` prints `Not-ing!`.
///
/// ```
/// use std::ops::Not;
///
/// struct Foo;
///
2015-01-02 22:56:24 -05:00
/// impl Not for Foo {
/// type Output = Foo;
///
/// fn not(self) -> Foo {
/// println!("Not-ing!");
/// self
/// }
/// }
///
/// fn main() {
/// !Foo;
/// }
/// ```
#[lang = "not"]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-02 22:56:24 -05:00
pub trait Not {
/// The resulting type after applying the `!` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-02 22:56:24 -05:00
type Output;
/// The method for the unary `!` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-02 22:56:24 -05:00
fn not(self) -> Self::Output;
}
macro_rules! not_impl {
($($t:ty)*) => ($(
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-02 22:56:24 -05:00
impl Not for $t {
type Output = $t;
#[inline]
fn not(self) -> $t { !self }
}
forward_ref_unop! { impl Not, not for $t }
)*)
}
2015-02-15 10:22:43 -05:00
not_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
/// The `BitAnd` trait is used to specify the functionality of `&`.
///
/// # Examples
///
/// A trivial implementation of `BitAnd`. When `Foo & Foo` happens, it ends up
/// calling `bitand`, and therefore, `main` prints `Bitwise And-ing!`.
///
/// ```
/// use std::ops::BitAnd;
///
/// struct Foo;
///
2014-12-31 15:45:13 -05:00
/// impl BitAnd for Foo {
/// type Output = Foo;
///
2014-12-01 19:10:12 -05:00
/// fn bitand(self, _rhs: Foo) -> Foo {
/// println!("Bitwise And-ing!");
2014-12-01 19:10:12 -05:00
/// self
/// }
/// }
///
/// fn main() {
/// Foo & Foo;
/// }
/// ```
#[lang = "bitand"]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
pub trait BitAnd<RHS=Self> {
/// The resulting type after applying the `&` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
type Output;
/// The method for the `&` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
fn bitand(self, rhs: RHS) -> Self::Output;
}
macro_rules! bitand_impl {
($($t:ty)*) => ($(
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
impl BitAnd for $t {
type Output = $t;
#[inline]
fn bitand(self, rhs: $t) -> $t { self & rhs }
}
forward_ref_binop! { impl BitAnd, bitand for $t, $t }
)*)
}
2015-02-15 10:22:43 -05:00
bitand_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
/// The `BitOr` trait is used to specify the functionality of `|`.
///
/// # Examples
///
/// A trivial implementation of `BitOr`. When `Foo | Foo` happens, it ends up
/// calling `bitor`, and therefore, `main` prints `Bitwise Or-ing!`.
///
/// ```
/// use std::ops::BitOr;
///
/// struct Foo;
///
2014-12-31 15:45:13 -05:00
/// impl BitOr for Foo {
/// type Output = Foo;
///
2014-12-01 19:10:12 -05:00
/// fn bitor(self, _rhs: Foo) -> Foo {
/// println!("Bitwise Or-ing!");
2014-12-01 19:10:12 -05:00
/// self
/// }
/// }
///
/// fn main() {
/// Foo | Foo;
/// }
/// ```
#[lang = "bitor"]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
pub trait BitOr<RHS=Self> {
/// The resulting type after applying the `|` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
type Output;
/// The method for the `|` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
fn bitor(self, rhs: RHS) -> Self::Output;
}
macro_rules! bitor_impl {
($($t:ty)*) => ($(
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
impl BitOr for $t {
type Output = $t;
#[inline]
fn bitor(self, rhs: $t) -> $t { self | rhs }
}
forward_ref_binop! { impl BitOr, bitor for $t, $t }
)*)
}
2015-02-15 10:22:43 -05:00
bitor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
/// The `BitXor` trait is used to specify the functionality of `^`.
///
/// # Examples
///
/// A trivial implementation of `BitXor`. When `Foo ^ Foo` happens, it ends up
/// calling `bitxor`, and therefore, `main` prints `Bitwise Xor-ing!`.
///
/// ```
/// use std::ops::BitXor;
///
/// struct Foo;
///
2014-12-31 15:45:13 -05:00
/// impl BitXor for Foo {
/// type Output = Foo;
///
2014-12-01 19:10:12 -05:00
/// fn bitxor(self, _rhs: Foo) -> Foo {
/// println!("Bitwise Xor-ing!");
2014-12-01 19:10:12 -05:00
/// self
/// }
/// }
///
/// fn main() {
/// Foo ^ Foo;
/// }
/// ```
#[lang = "bitxor"]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
pub trait BitXor<RHS=Self> {
/// The resulting type after applying the `^` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
type Output;
/// The method for the `^` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
fn bitxor(self, rhs: RHS) -> Self::Output;
}
macro_rules! bitxor_impl {
($($t:ty)*) => ($(
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
impl BitXor for $t {
type Output = $t;
#[inline]
fn bitxor(self, other: $t) -> $t { self ^ other }
}
forward_ref_binop! { impl BitXor, bitxor for $t, $t }
)*)
}
2015-02-15 10:22:43 -05:00
bitxor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
/// The `Shl` trait is used to specify the functionality of `<<`.
///
/// # Examples
///
/// A trivial implementation of `Shl`. When `Foo << Foo` happens, it ends up
/// calling `shl`, and therefore, `main` prints `Shifting left!`.
///
/// ```
/// use std::ops::Shl;
///
/// struct Foo;
///
2014-12-31 15:45:13 -05:00
/// impl Shl<Foo> for Foo {
/// type Output = Foo;
///
2014-12-01 19:10:12 -05:00
/// fn shl(self, _rhs: Foo) -> Foo {
/// println!("Shifting left!");
2014-12-01 19:10:12 -05:00
/// self
/// }
/// }
///
/// fn main() {
/// Foo << Foo;
/// }
/// ```
#[lang = "shl"]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
pub trait Shl<RHS> {
/// The resulting type after applying the `<<` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
type Output;
/// The method for the `<<` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
fn shl(self, rhs: RHS) -> Self::Output;
}
macro_rules! shl_impl {
($t:ty, $f:ty) => (
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl Shl<$f> for $t {
2014-12-31 15:45:13 -05:00
type Output = $t;
#[inline]
#[rustc_inherit_overflow_checks]
fn shl(self, other: $f) -> $t {
self << other
}
}
forward_ref_binop! { impl Shl, shl for $t, $f }
)
}
macro_rules! shl_impl_all {
($($t:ty)*) => ($(
shl_impl! { $t, u8 }
shl_impl! { $t, u16 }
shl_impl! { $t, u32 }
shl_impl! { $t, u64 }
shl_impl! { $t, usize }
shl_impl! { $t, i8 }
shl_impl! { $t, i16 }
shl_impl! { $t, i32 }
shl_impl! { $t, i64 }
shl_impl! { $t, isize }
)*)
}
shl_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
/// The `Shr` trait is used to specify the functionality of `>>`.
///
/// # Examples
///
/// A trivial implementation of `Shr`. When `Foo >> Foo` happens, it ends up
/// calling `shr`, and therefore, `main` prints `Shifting right!`.
///
/// ```
/// use std::ops::Shr;
///
/// struct Foo;
///
2014-12-31 15:45:13 -05:00
/// impl Shr<Foo> for Foo {
/// type Output = Foo;
///
2014-12-01 19:10:12 -05:00
/// fn shr(self, _rhs: Foo) -> Foo {
/// println!("Shifting right!");
2014-12-01 19:10:12 -05:00
/// self
/// }
/// }
///
/// fn main() {
/// Foo >> Foo;
/// }
/// ```
#[lang = "shr"]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
pub trait Shr<RHS> {
/// The resulting type after applying the `>>` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
type Output;
/// The method for the `>>` operator
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-31 15:45:13 -05:00
fn shr(self, rhs: RHS) -> Self::Output;
}
macro_rules! shr_impl {
($t:ty, $f:ty) => (
2015-11-16 19:54:28 +03:00
#[stable(feature = "rust1", since = "1.0.0")]
impl Shr<$f> for $t {
2014-12-31 15:45:13 -05:00
type Output = $t;
#[inline]
#[rustc_inherit_overflow_checks]
fn shr(self, other: $f) -> $t {
self >> other
}
}
forward_ref_binop! { impl Shr, shr for $t, $f }
)
}
macro_rules! shr_impl_all {
($($t:ty)*) => ($(
shr_impl! { $t, u8 }
shr_impl! { $t, u16 }
shr_impl! { $t, u32 }
shr_impl! { $t, u64 }
shr_impl! { $t, usize }
shr_impl! { $t, i8 }
shr_impl! { $t, i16 }
shr_impl! { $t, i32 }
shr_impl! { $t, i64 }
shr_impl! { $t, isize }
)*)
}
shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
2015-09-10 19:16:57 -05:00
/// The `AddAssign` trait is used to specify the functionality of `+=`.
///
/// # Examples
///
/// A trivial implementation of `AddAssign`. When `Foo += Foo` happens, it ends up
/// calling `add_assign`, and therefore, `main` prints `Adding!`.
///
/// ```
/// use std::ops::AddAssign;
///
/// struct Foo;
///
/// impl AddAssign for Foo {
/// fn add_assign(&mut self, _rhs: Foo) {
/// println!("Adding!");
/// }
/// }
///
2015-11-03 15:27:03 +00:00
/// # #[allow(unused_assignments)]
2015-09-10 19:16:57 -05:00
/// fn main() {
/// let mut foo = Foo;
/// foo += Foo;
/// }
/// ```
#[lang = "add_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
pub trait AddAssign<Rhs=Self> {
/// The method for the `+=` operator
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
fn add_assign(&mut self, Rhs);
}
macro_rules! add_assign_impl {
($($t:ty)+) => ($(
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
impl AddAssign for $t {
#[inline]
#[rustc_inherit_overflow_checks]
2015-09-10 19:16:57 -05:00
fn add_assign(&mut self, other: $t) { *self += other }
}
)+)
}
add_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
/// The `SubAssign` trait is used to specify the functionality of `-=`.
///
/// # Examples
///
/// A trivial implementation of `SubAssign`. When `Foo -= Foo` happens, it ends up
/// calling `sub_assign`, and therefore, `main` prints `Subtracting!`.
///
/// ```
/// use std::ops::SubAssign;
///
/// struct Foo;
///
/// impl SubAssign for Foo {
/// fn sub_assign(&mut self, _rhs: Foo) {
/// println!("Subtracting!");
/// }
/// }
///
2015-11-03 15:27:03 +00:00
/// # #[allow(unused_assignments)]
2015-09-10 19:16:57 -05:00
/// fn main() {
/// let mut foo = Foo;
/// foo -= Foo;
/// }
/// ```
#[lang = "sub_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
pub trait SubAssign<Rhs=Self> {
/// The method for the `-=` operator
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
fn sub_assign(&mut self, Rhs);
}
macro_rules! sub_assign_impl {
($($t:ty)+) => ($(
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
impl SubAssign for $t {
#[inline]
#[rustc_inherit_overflow_checks]
2015-09-10 19:16:57 -05:00
fn sub_assign(&mut self, other: $t) { *self -= other }
}
)+)
}
sub_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
/// The `MulAssign` trait is used to specify the functionality of `*=`.
///
/// # Examples
///
/// A trivial implementation of `MulAssign`. When `Foo *= Foo` happens, it ends up
/// calling `mul_assign`, and therefore, `main` prints `Multiplying!`.
///
/// ```
/// use std::ops::MulAssign;
///
/// struct Foo;
///
/// impl MulAssign for Foo {
/// fn mul_assign(&mut self, _rhs: Foo) {
/// println!("Multiplying!");
/// }
/// }
///
2015-11-03 15:27:03 +00:00
/// # #[allow(unused_assignments)]
2015-09-10 19:16:57 -05:00
/// fn main() {
/// let mut foo = Foo;
/// foo *= Foo;
/// }
/// ```
#[lang = "mul_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
pub trait MulAssign<Rhs=Self> {
/// The method for the `*=` operator
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
fn mul_assign(&mut self, Rhs);
}
macro_rules! mul_assign_impl {
($($t:ty)+) => ($(
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
impl MulAssign for $t {
#[inline]
#[rustc_inherit_overflow_checks]
2015-09-10 19:16:57 -05:00
fn mul_assign(&mut self, other: $t) { *self *= other }
}
)+)
}
mul_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
/// The `DivAssign` trait is used to specify the functionality of `/=`.
///
/// # Examples
///
/// A trivial implementation of `DivAssign`. When `Foo /= Foo` happens, it ends up
/// calling `div_assign`, and therefore, `main` prints `Dividing!`.
///
/// ```
/// use std::ops::DivAssign;
///
/// struct Foo;
///
/// impl DivAssign for Foo {
/// fn div_assign(&mut self, _rhs: Foo) {
/// println!("Dividing!");
/// }
/// }
///
2015-11-03 15:27:03 +00:00
/// # #[allow(unused_assignments)]
2015-09-10 19:16:57 -05:00
/// fn main() {
/// let mut foo = Foo;
/// foo /= Foo;
/// }
/// ```
#[lang = "div_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
pub trait DivAssign<Rhs=Self> {
/// The method for the `/=` operator
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
fn div_assign(&mut self, Rhs);
}
macro_rules! div_assign_impl {
($($t:ty)+) => ($(
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
impl DivAssign for $t {
#[inline]
fn div_assign(&mut self, other: $t) { *self /= other }
}
)+)
}
div_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
/// The `RemAssign` trait is used to specify the functionality of `%=`.
///
/// # Examples
///
/// A trivial implementation of `RemAssign`. When `Foo %= Foo` happens, it ends up
/// calling `rem_assign`, and therefore, `main` prints `Remainder-ing!`.
///
/// ```
/// use std::ops::RemAssign;
///
/// struct Foo;
///
/// impl RemAssign for Foo {
/// fn rem_assign(&mut self, _rhs: Foo) {
/// println!("Remainder-ing!");
/// }
/// }
///
2015-11-03 15:27:03 +00:00
/// # #[allow(unused_assignments)]
2015-09-10 19:16:57 -05:00
/// fn main() {
/// let mut foo = Foo;
/// foo %= Foo;
/// }
/// ```
#[lang = "rem_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
pub trait RemAssign<Rhs=Self> {
/// The method for the `%=` operator
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
fn rem_assign(&mut self, Rhs);
}
macro_rules! rem_assign_impl {
($($t:ty)+) => ($(
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
impl RemAssign for $t {
#[inline]
fn rem_assign(&mut self, other: $t) { *self %= other }
}
)+)
}
rem_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
/// The `BitAndAssign` trait is used to specify the functionality of `&=`.
///
/// # Examples
///
/// A trivial implementation of `BitAndAssign`. When `Foo &= Foo` happens, it ends up
/// calling `bitand_assign`, and therefore, `main` prints `Bitwise And-ing!`.
///
/// ```
/// use std::ops::BitAndAssign;
///
/// struct Foo;
///
/// impl BitAndAssign for Foo {
/// fn bitand_assign(&mut self, _rhs: Foo) {
/// println!("Bitwise And-ing!");
/// }
/// }
///
2015-11-03 15:27:03 +00:00
/// # #[allow(unused_assignments)]
2015-09-10 19:16:57 -05:00
/// fn main() {
/// let mut foo = Foo;
/// foo &= Foo;
/// }
/// ```
#[lang = "bitand_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
pub trait BitAndAssign<Rhs=Self> {
/// The method for the `&` operator
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
fn bitand_assign(&mut self, Rhs);
}
macro_rules! bitand_assign_impl {
($($t:ty)+) => ($(
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
impl BitAndAssign for $t {
#[inline]
fn bitand_assign(&mut self, other: $t) { *self &= other }
}
)+)
}
bitand_assign_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
/// The `BitOrAssign` trait is used to specify the functionality of `|=`.
///
/// # Examples
///
/// A trivial implementation of `BitOrAssign`. When `Foo |= Foo` happens, it ends up
/// calling `bitor_assign`, and therefore, `main` prints `Bitwise Or-ing!`.
///
/// ```
/// use std::ops::BitOrAssign;
///
/// struct Foo;
///
/// impl BitOrAssign for Foo {
/// fn bitor_assign(&mut self, _rhs: Foo) {
/// println!("Bitwise Or-ing!");
/// }
/// }
///
2015-11-03 15:27:03 +00:00
/// # #[allow(unused_assignments)]
2015-09-10 19:16:57 -05:00
/// fn main() {
/// let mut foo = Foo;
/// foo |= Foo;
/// }
/// ```
#[lang = "bitor_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
pub trait BitOrAssign<Rhs=Self> {
/// The method for the `|=` operator
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
fn bitor_assign(&mut self, Rhs);
}
macro_rules! bitor_assign_impl {
($($t:ty)+) => ($(
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
impl BitOrAssign for $t {
#[inline]
fn bitor_assign(&mut self, other: $t) { *self |= other }
}
)+)
}
bitor_assign_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
/// The `BitXorAssign` trait is used to specify the functionality of `^=`.
///
/// # Examples
///
/// A trivial implementation of `BitXorAssign`. When `Foo ^= Foo` happens, it ends up
/// calling `bitxor_assign`, and therefore, `main` prints `Bitwise Xor-ing!`.
///
/// ```
/// use std::ops::BitXorAssign;
///
/// struct Foo;
///
/// impl BitXorAssign for Foo {
/// fn bitxor_assign(&mut self, _rhs: Foo) {
/// println!("Bitwise Xor-ing!");
/// }
/// }
///
2015-11-03 15:27:03 +00:00
/// # #[allow(unused_assignments)]
2015-09-10 19:16:57 -05:00
/// fn main() {
/// let mut foo = Foo;
/// foo ^= Foo;
/// }
/// ```
#[lang = "bitxor_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
pub trait BitXorAssign<Rhs=Self> {
/// The method for the `^=` operator
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
fn bitxor_assign(&mut self, Rhs);
}
macro_rules! bitxor_assign_impl {
($($t:ty)+) => ($(
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
impl BitXorAssign for $t {
#[inline]
fn bitxor_assign(&mut self, other: $t) { *self ^= other }
}
)+)
}
bitxor_assign_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
/// The `ShlAssign` trait is used to specify the functionality of `<<=`.
///
/// # Examples
///
/// A trivial implementation of `ShlAssign`. When `Foo <<= Foo` happens, it ends up
/// calling `shl_assign`, and therefore, `main` prints `Shifting left!`.
///
/// ```
/// use std::ops::ShlAssign;
///
/// struct Foo;
///
/// impl ShlAssign<Foo> for Foo {
/// fn shl_assign(&mut self, _rhs: Foo) {
/// println!("Shifting left!");
/// }
/// }
///
2015-11-03 15:27:03 +00:00
/// # #[allow(unused_assignments)]
2015-09-10 19:16:57 -05:00
/// fn main() {
/// let mut foo = Foo;
/// foo <<= Foo;
/// }
/// ```
#[lang = "shl_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
pub trait ShlAssign<Rhs> {
/// The method for the `<<=` operator
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
fn shl_assign(&mut self, Rhs);
}
macro_rules! shl_assign_impl {
($t:ty, $f:ty) => (
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
impl ShlAssign<$f> for $t {
#[inline]
#[rustc_inherit_overflow_checks]
2015-09-10 19:16:57 -05:00
fn shl_assign(&mut self, other: $f) {
*self <<= other
}
}
)
}
macro_rules! shl_assign_impl_all {
($($t:ty)*) => ($(
shl_assign_impl! { $t, u8 }
shl_assign_impl! { $t, u16 }
shl_assign_impl! { $t, u32 }
shl_assign_impl! { $t, u64 }
shl_assign_impl! { $t, usize }
shl_assign_impl! { $t, i8 }
shl_assign_impl! { $t, i16 }
shl_assign_impl! { $t, i32 }
shl_assign_impl! { $t, i64 }
shl_assign_impl! { $t, isize }
)*)
}
shl_assign_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
/// The `ShrAssign` trait is used to specify the functionality of `>>=`.
///
/// # Examples
///
/// A trivial implementation of `ShrAssign`. When `Foo >>= Foo` happens, it ends up
/// calling `shr_assign`, and therefore, `main` prints `Shifting right!`.
///
/// ```
/// use std::ops::ShrAssign;
///
/// struct Foo;
///
/// impl ShrAssign<Foo> for Foo {
/// fn shr_assign(&mut self, _rhs: Foo) {
/// println!("Shifting right!");
/// }
/// }
///
2015-11-03 15:27:03 +00:00
/// # #[allow(unused_assignments)]
2015-09-10 19:16:57 -05:00
/// fn main() {
/// let mut foo = Foo;
/// foo >>= Foo;
/// }
/// ```
#[lang = "shr_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
pub trait ShrAssign<Rhs=Self> {
/// The method for the `>>=` operator
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
fn shr_assign(&mut self, Rhs);
}
macro_rules! shr_assign_impl {
($t:ty, $f:ty) => (
#[stable(feature = "op_assign_traits", since = "1.8.0")]
2015-09-10 19:16:57 -05:00
impl ShrAssign<$f> for $t {
#[inline]
#[rustc_inherit_overflow_checks]
2015-09-10 19:16:57 -05:00
fn shr_assign(&mut self, other: $f) {
*self >>= other
}
}
)
}
macro_rules! shr_assign_impl_all {
($($t:ty)*) => ($(
shr_assign_impl! { $t, u8 }
shr_assign_impl! { $t, u16 }
shr_assign_impl! { $t, u32 }
shr_assign_impl! { $t, u64 }
shr_assign_impl! { $t, usize }
shr_assign_impl! { $t, i8 }
shr_assign_impl! { $t, i16 }
shr_assign_impl! { $t, i32 }
shr_assign_impl! { $t, i64 }
shr_assign_impl! { $t, isize }
)*)
}
shr_assign_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
/// The `Index` trait is used to specify the functionality of indexing operations
/// like `arr[idx]` when used in an immutable context.
///
/// # Examples
///
/// A trivial implementation of `Index`. When `Foo[Bar]` happens, it ends up
/// calling `index`, and therefore, `main` prints `Indexing!`.
///
/// ```
/// use std::ops::Index;
///
/// #[derive(Copy, Clone)]
/// struct Foo;
/// struct Bar;
///
/// impl Index<Bar> for Foo {
2015-01-03 09:46:29 -05:00
/// type Output = Foo;
///
/// fn index<'a>(&'a self, _index: Bar) -> &'a Foo {
/// println!("Indexing!");
/// self
/// }
/// }
///
/// fn main() {
/// Foo[Bar];
/// }
/// ```
#[lang = "index"]
#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Index<Idx: ?Sized> {
/// The returned type after indexing
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-06 10:16:49 +13:00
type Output: ?Sized;
2015-01-03 09:46:29 -05:00
/// The method for the indexing (`Foo[Bar]`) operation
#[stable(feature = "rust1", since = "1.0.0")]
2015-09-03 15:19:08 +05:30
fn index(&self, index: Idx) -> &Self::Output;
2015-01-03 09:46:29 -05:00
}
/// The `IndexMut` trait is used to specify the functionality of indexing
/// operations like `arr[idx]`, when used in a mutable context.
///
/// # Examples
///
/// A trivial implementation of `IndexMut`. When `Foo[Bar]` happens, it ends up
/// calling `index_mut`, and therefore, `main` prints `Indexing!`.
///
/// ```
/// use std::ops::{Index, IndexMut};
///
/// #[derive(Copy, Clone)]
/// struct Foo;
/// struct Bar;
///
/// impl Index<Bar> for Foo {
2015-01-03 09:46:29 -05:00
/// type Output = Foo;
///
/// fn index<'a>(&'a self, _index: Bar) -> &'a Foo {
/// self
/// }
/// }
///
/// impl IndexMut<Bar> for Foo {
/// fn index_mut<'a>(&'a mut self, _index: Bar) -> &'a mut Foo {
/// println!("Indexing!");
/// self
/// }
/// }
///
/// fn main() {
/// &mut Foo[Bar];
/// }
/// ```
#[lang = "index_mut"]
#[rustc_on_unimplemented = "the type `{Self}` cannot be mutably indexed by `{Idx}`"]
#[stable(feature = "rust1", since = "1.0.0")]
pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
/// The method for the indexing (`Foo[Bar]`) operation
#[stable(feature = "rust1", since = "1.0.0")]
2015-09-03 15:19:08 +05:30
fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
}
/// An unbounded range. Use `..` (two dots) for its shorthand.
///
/// Its primary use case is slicing index. It cannot serve as an iterator
/// because it doesn't have a starting point.
///
/// # Examples
///
/// The `..` syntax is a `RangeFull`:
///
/// ```
/// assert_eq!((..), std::ops::RangeFull);
/// ```
///
/// It does not have an `IntoIterator` implementation, so you can't use it in a
/// `for` loop directly. This won't compile:
///
/// ```ignore
/// for i in .. {
/// // ...
/// }
/// ```
///
/// Used as a slicing index, `RangeFull` produces the full array as a slice.
///
/// ```
/// let arr = [0, 1, 2, 3];
/// assert_eq!(arr[ .. ], [0,1,2,3]); // RangeFull
/// assert_eq!(arr[ ..3], [0,1,2 ]);
/// assert_eq!(arr[1.. ], [ 1,2,3]);
/// assert_eq!(arr[1..3], [ 1,2 ]);
/// ```
2016-06-09 10:52:36 -04:00
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
2015-01-28 17:06:46 +13:00
#[stable(feature = "rust1", since = "1.0.0")]
pub struct RangeFull;
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Debug for RangeFull {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "..")
2015-01-28 17:06:46 +13:00
}
}
/// A (half-open) range which is bounded at both ends: { x | start <= x < end }.
/// Use `start..end` (two dots) for its shorthand.
///
/// See the [`contains()`](#method.contains) method for its characterization.
///
/// # Examples
///
/// ```
/// fn main() {
/// assert_eq!((3..5), std::ops::Range{ start: 3, end: 5 });
/// assert_eq!(3+4+5, (3..6).sum());
///
/// let arr = [0, 1, 2, 3];
/// assert_eq!(arr[ .. ], [0,1,2,3]);
/// assert_eq!(arr[ ..3], [0,1,2 ]);
/// assert_eq!(arr[1.. ], [ 1,2,3]);
/// assert_eq!(arr[1..3], [ 1,2 ]); // Range
/// }
/// ```
2016-06-09 10:52:36 -04:00
#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-13 16:58:48 +13:00
pub struct Range<Idx> {
/// The lower bound of the range (inclusive).
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-13 16:58:48 +13:00
pub start: Idx,
/// The upper bound of the range (exclusive).
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-13 16:58:48 +13:00
pub end: Idx,
}
#[stable(feature = "rust1", since = "1.0.0")]
std: Rename Show/String to Debug/Display This commit is an implementation of [RFC 565][rfc] which is a stabilization of the `std::fmt` module and the implementations of various formatting traits. Specifically, the following changes were performed: [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0565-show-string-guidelines.md * The `Show` trait is now deprecated, it was renamed to `Debug` * The `String` trait is now deprecated, it was renamed to `Display` * Many `Debug` and `Display` implementations were audited in accordance with the RFC and audited implementations now have the `#[stable]` attribute * Integers and floats no longer print a suffix * Smart pointers no longer print details that they are a smart pointer * Paths with `Debug` are now quoted and escape characters * The `unwrap` methods on `Result` now require `Display` instead of `Debug` * The `Error` trait no longer has a `detail` method and now requires that `Display` must be implemented. With the loss of `String`, this has moved into libcore. * `impl<E: Error> FromError<E> for Box<Error>` now exists * `derive(Show)` has been renamed to `derive(Debug)`. This is not currently warned about due to warnings being emitted on stage1+ While backwards compatibility is attempted to be maintained with a blanket implementation of `Display` for the old `String` trait (and the same for `Show`/`Debug`) this is still a breaking change due to primitives no longer implementing `String` as well as modifications such as `unwrap` and the `Error` trait. Most code is fairly straightforward to update with a rename or tweaks of method calls. [breaking-change] Closes #21436
2015-01-20 15:45:07 -08:00
impl<Idx: fmt::Debug> fmt::Debug for Range<Idx> {
2015-01-07 17:21:09 +13:00
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "{:?}..{:?}", self.start, self.end)
}
}
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
impl<Idx: PartialOrd<Idx>> Range<Idx> {
/// # Examples
///
/// ```
/// #![feature(range_contains)]
/// fn main() {
/// assert!( ! (3..5).contains(2));
/// assert!( (3..5).contains(3));
/// assert!( (3..5).contains(4));
/// assert!( ! (3..5).contains(5));
///
/// assert!( ! (3..3).contains(3));
/// assert!( ! (3..2).contains(3));
/// }
/// ```
pub fn contains(&self, item: Idx) -> bool {
(self.start <= item) && (item < self.end)
}
}
/// A range which is only bounded below: { x | start <= x }.
/// Use `start..` for its shorthand.
///
/// See the [`contains()`](#method.contains) method for its characterization.
///
/// Note: Currently, no overflow checking is done for the iterator
/// implementation; if you use an integer range and the integer overflows, it
/// might panic in debug mode or create an endless loop in release mode. This
/// overflow behavior might change in the future.
///
/// # Examples
///
/// ```
/// fn main() {
/// assert_eq!((2..), std::ops::RangeFrom{ start: 2 });
/// assert_eq!(2+3+4, (2..).take(3).sum());
///
/// let arr = [0, 1, 2, 3];
/// assert_eq!(arr[ .. ], [0,1,2,3]);
/// assert_eq!(arr[ ..3], [0,1,2 ]);
/// assert_eq!(arr[1.. ], [ 1,2,3]); // RangeFrom
/// assert_eq!(arr[1..3], [ 1,2 ]);
/// }
/// ```
2016-06-09 10:52:36 -04:00
#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-13 16:58:48 +13:00
pub struct RangeFrom<Idx> {
/// The lower bound of the range (inclusive).
#[stable(feature = "rust1", since = "1.0.0")]
2014-12-13 16:58:48 +13:00
pub start: Idx,
}
#[stable(feature = "rust1", since = "1.0.0")]
std: Rename Show/String to Debug/Display This commit is an implementation of [RFC 565][rfc] which is a stabilization of the `std::fmt` module and the implementations of various formatting traits. Specifically, the following changes were performed: [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0565-show-string-guidelines.md * The `Show` trait is now deprecated, it was renamed to `Debug` * The `String` trait is now deprecated, it was renamed to `Display` * Many `Debug` and `Display` implementations were audited in accordance with the RFC and audited implementations now have the `#[stable]` attribute * Integers and floats no longer print a suffix * Smart pointers no longer print details that they are a smart pointer * Paths with `Debug` are now quoted and escape characters * The `unwrap` methods on `Result` now require `Display` instead of `Debug` * The `Error` trait no longer has a `detail` method and now requires that `Display` must be implemented. With the loss of `String`, this has moved into libcore. * `impl<E: Error> FromError<E> for Box<Error>` now exists * `derive(Show)` has been renamed to `derive(Debug)`. This is not currently warned about due to warnings being emitted on stage1+ While backwards compatibility is attempted to be maintained with a blanket implementation of `Display` for the old `String` trait (and the same for `Show`/`Debug`) this is still a breaking change due to primitives no longer implementing `String` as well as modifications such as `unwrap` and the `Error` trait. Most code is fairly straightforward to update with a rename or tweaks of method calls. [breaking-change] Closes #21436
2015-01-20 15:45:07 -08:00
impl<Idx: fmt::Debug> fmt::Debug for RangeFrom<Idx> {
2015-01-07 17:21:09 +13:00
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "{:?}..", self.start)
}
}
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
/// # Examples
///
/// ```
/// #![feature(range_contains)]
/// fn main() {
/// assert!( ! (3..).contains(2));
/// assert!( (3..).contains(3));
/// assert!( (3..).contains(1_000_000_000));
/// }
/// ```
pub fn contains(&self, item: Idx) -> bool {
(self.start <= item)
}
}
/// A range which is only bounded above: { x | x < end }.
/// Use `..end` (two dots) for its shorthand.
///
/// See the [`contains()`](#method.contains) method for its characterization.
///
/// It cannot serve as an iterator because it doesn't have a starting point.
2016-06-19 14:23:30 +02:00
///
/// ```
/// fn main() {
/// assert_eq!((..5), std::ops::RangeTo{ end: 5 });
///
/// let arr = [0, 1, 2, 3];
/// assert_eq!(arr[ .. ], [0,1,2,3]);
/// assert_eq!(arr[ ..3], [0,1,2 ]); // RangeTo
/// assert_eq!(arr[1.. ], [ 1,2,3]);
/// assert_eq!(arr[1..3], [ 1,2 ]);
/// }
/// ```
2016-06-09 10:52:36 -04:00
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct RangeTo<Idx> {
/// The upper bound of the range (exclusive).
#[stable(feature = "rust1", since = "1.0.0")]
pub end: Idx,
}
#[stable(feature = "rust1", since = "1.0.0")]
std: Rename Show/String to Debug/Display This commit is an implementation of [RFC 565][rfc] which is a stabilization of the `std::fmt` module and the implementations of various formatting traits. Specifically, the following changes were performed: [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0565-show-string-guidelines.md * The `Show` trait is now deprecated, it was renamed to `Debug` * The `String` trait is now deprecated, it was renamed to `Display` * Many `Debug` and `Display` implementations were audited in accordance with the RFC and audited implementations now have the `#[stable]` attribute * Integers and floats no longer print a suffix * Smart pointers no longer print details that they are a smart pointer * Paths with `Debug` are now quoted and escape characters * The `unwrap` methods on `Result` now require `Display` instead of `Debug` * The `Error` trait no longer has a `detail` method and now requires that `Display` must be implemented. With the loss of `String`, this has moved into libcore. * `impl<E: Error> FromError<E> for Box<Error>` now exists * `derive(Show)` has been renamed to `derive(Debug)`. This is not currently warned about due to warnings being emitted on stage1+ While backwards compatibility is attempted to be maintained with a blanket implementation of `Display` for the old `String` trait (and the same for `Show`/`Debug`) this is still a breaking change due to primitives no longer implementing `String` as well as modifications such as `unwrap` and the `Error` trait. Most code is fairly straightforward to update with a rename or tweaks of method calls. [breaking-change] Closes #21436
2015-01-20 15:45:07 -08:00
impl<Idx: fmt::Debug> fmt::Debug for RangeTo<Idx> {
2015-01-07 17:21:09 +13:00
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "..{:?}", self.end)
}
}
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
/// # Examples
///
/// ```
/// #![feature(range_contains)]
/// fn main() {
/// assert!( (..5).contains(-1_000_000_000));
/// assert!( (..5).contains(4));
/// assert!( ! (..5).contains(5));
/// }
/// ```
pub fn contains(&self, item: Idx) -> bool {
(item < self.end)
}
}
/// An inclusive range which is bounded at both ends: { x | start <= x <= end }.
/// Use `start...end` (three dots) for its shorthand.
///
/// See the [`contains()`](#method.contains) method for its characterization.
///
/// # Examples
///
/// ```
/// #![feature(inclusive_range,inclusive_range_syntax)]
/// fn main() {
/// assert_eq!((3...5), std::ops::RangeInclusive::NonEmpty{ start: 3, end: 5 });
/// assert_eq!(3+4+5, (3...5).sum());
///
/// let arr = [0, 1, 2, 3];
/// assert_eq!(arr[ ...2], [0,1,2 ]);
/// assert_eq!(arr[1...2], [ 1,2 ]); // RangeInclusive
/// }
/// ```
#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
pub enum RangeInclusive<Idx> {
/// Empty range (iteration has finished)
2016-03-04 18:39:25 -05:00
#[unstable(feature = "inclusive_range",
reason = "recently added, follows RFC",
issue = "28237")]
Empty {
/// The point at which iteration finished
2016-03-04 18:39:25 -05:00
#[unstable(feature = "inclusive_range",
reason = "recently added, follows RFC",
issue = "28237")]
at: Idx
},
/// Non-empty range (iteration will yield value(s))
2016-03-04 18:39:25 -05:00
#[unstable(feature = "inclusive_range",
reason = "recently added, follows RFC",
issue = "28237")]
NonEmpty {
/// The lower bound of the range (inclusive).
2016-03-04 18:39:25 -05:00
#[unstable(feature = "inclusive_range",
reason = "recently added, follows RFC",
issue = "28237")]
start: Idx,
/// The upper bound of the range (inclusive).
2016-03-04 18:39:25 -05:00
#[unstable(feature = "inclusive_range",
reason = "recently added, follows RFC",
issue = "28237")]
end: Idx,
},
}
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
use self::RangeInclusive::*;
match *self {
Empty { ref at } => write!(fmt, "[empty range @ {:?}]", at),
NonEmpty { ref start, ref end } => write!(fmt, "{:?}...{:?}", start, end),
}
}
}
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
/// # Examples
///
/// ```
/// #![feature(range_contains,inclusive_range_syntax)]
/// fn main() {
/// assert!( ! (3...5).contains(2));
/// assert!( (3...5).contains(3));
/// assert!( (3...5).contains(4));
/// assert!( (3...5).contains(5));
/// assert!( ! (3...5).contains(6));
///
/// assert!( (3...3).contains(3));
/// assert!( ! (3...2).contains(3));
/// }
/// ```
pub fn contains(&self, item: Idx) -> bool {
if let &RangeInclusive::NonEmpty{ref start, ref end} = self {
(*start <= item) && (item <= *end)
} else { false }
}
}
/// An inclusive range which is only bounded above: { x | x <= end }.
/// Use `...end` (three dots) for its shorthand.
///
/// See the [`contains()`](#method.contains) method for its characterization.
///
/// It cannot serve as an iterator because it doesn't have a starting point.
///
/// # Examples
///
/// ```
/// #![feature(inclusive_range,inclusive_range_syntax)]
/// fn main() {
/// assert_eq!((...5), std::ops::RangeToInclusive{ end: 5 });
///
/// let arr = [0, 1, 2, 3];
/// assert_eq!(arr[ ...2], [0,1,2 ]); // RangeToInclusive
/// assert_eq!(arr[1...2], [ 1,2 ]);
/// }
/// ```
2016-06-09 10:52:36 -04:00
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
pub struct RangeToInclusive<Idx> {
/// The upper bound of the range (inclusive)
#[unstable(feature = "inclusive_range",
reason = "recently added, follows RFC",
issue = "28237")]
pub end: Idx,
}
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
impl<Idx: fmt::Debug> fmt::Debug for RangeToInclusive<Idx> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "...{:?}", self.end)
}
}
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
/// # Examples
///
/// ```
/// #![feature(range_contains,inclusive_range_syntax)]
/// fn main() {
/// assert!( (...5).contains(-1_000_000_000));
/// assert!( (...5).contains(5));
/// assert!( ! (...5).contains(6));
/// }
/// ```
pub fn contains(&self, item: Idx) -> bool {
(item <= self.end)
}
}
// RangeToInclusive<Idx> cannot impl From<RangeTo<Idx>>
// because underflow would be possible with (..0).into()
/// The `Deref` trait is used to specify the functionality of dereferencing
/// operations, like `*v`.
///
/// `Deref` also enables ['`Deref` coercions'][coercions].
///
/// [coercions]: ../../book/deref-coercions.html
///
/// # Examples
///
/// A struct with a single field which is accessible via dereferencing the
/// struct.
///
/// ```
/// use std::ops::Deref;
///
/// struct DerefExample<T> {
/// value: T
/// }
///
2015-01-01 14:53:20 -05:00
/// impl<T> Deref for DerefExample<T> {
/// type Target = T;
///
2015-09-26 20:40:22 +02:00
/// fn deref(&self) -> &T {
/// &self.value
/// }
/// }
///
/// fn main() {
/// let x = DerefExample { value: 'a' };
/// assert_eq!('a', *x);
/// }
/// ```
#[lang = "deref"]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-04 21:39:02 -05:00
pub trait Deref {
/// The resulting type after dereferencing
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-06 10:16:49 +13:00
type Target: ?Sized;
2015-01-01 14:53:20 -05:00
/// The method called to dereference a value
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-09-03 15:19:08 +05:30
fn deref(&self) -> &Self::Target;
2014-02-26 23:02:35 +02:00
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-06 10:16:49 +13:00
impl<'a, T: ?Sized> Deref for &'a T {
2015-01-01 14:53:20 -05:00
type Target = T;
fn deref(&self) -> &T { *self }
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-06 10:16:49 +13:00
impl<'a, T: ?Sized> Deref for &'a mut T {
2015-01-01 14:53:20 -05:00
type Target = T;
fn deref(&self) -> &T { *self }
}
/// The `DerefMut` trait is used to specify the functionality of dereferencing
/// mutably like `*v = 1;`
///
/// `DerefMut` also enables ['`Deref` coercions'][coercions].
///
/// [coercions]: ../../book/deref-coercions.html
///
/// # Examples
///
/// A struct with a single field which is modifiable via dereferencing the
/// struct.
///
/// ```
/// use std::ops::{Deref, DerefMut};
///
/// struct DerefMutExample<T> {
/// value: T
/// }
///
2015-01-01 14:53:20 -05:00
/// impl<T> Deref for DerefMutExample<T> {
/// type Target = T;
///
/// fn deref<'a>(&'a self) -> &'a T {
/// &self.value
/// }
/// }
///
2015-01-01 14:53:20 -05:00
/// impl<T> DerefMut for DerefMutExample<T> {
/// fn deref_mut<'a>(&'a mut self) -> &'a mut T {
/// &mut self.value
/// }
/// }
///
/// fn main() {
/// let mut x = DerefMutExample { value: 'a' };
/// *x = 'b';
/// assert_eq!('b', *x);
/// }
/// ```
#[lang = "deref_mut"]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub trait DerefMut: Deref {
/// The method called to mutably dereference a value
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-09-03 15:19:08 +05:30
fn deref_mut(&mut self) -> &mut Self::Target;
2014-02-26 23:02:35 +02:00
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-06 10:16:49 +13:00
impl<'a, T: ?Sized> DerefMut for &'a mut T {
fn deref_mut(&mut self) -> &mut T { *self }
}
/// A version of the call operator that takes an immutable receiver.
#[lang = "fn"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_paren_sugar]
#[fundamental] // so that regex can rely that `&str: !FnMut`
pub trait Fn<Args> : FnMut<Args> {
/// This is called when the call operator is used.
std: Stabilize APIs for the 1.6 release This commit is the standard API stabilization commit for the 1.6 release cycle. The list of issues and APIs below have all been through their cycle-long FCP and the libs team decisions are listed below Stabilized APIs * `Read::read_exact` * `ErrorKind::UnexpectedEof` (renamed from `UnexpectedEOF`) * libcore -- this was a bit of a nuanced stabilization, the crate itself is now marked as `#[stable]` and the methods appearing via traits for primitives like `char` and `str` are now also marked as stable. Note that the extension traits themeselves are marked as unstable as they're imported via the prelude. The `try!` macro was also moved from the standard library into libcore to have the same interface. Otherwise the functions all have copied stability from the standard library now. * The `#![no_std]` attribute * `fs::DirBuilder` * `fs::DirBuilder::new` * `fs::DirBuilder::recursive` * `fs::DirBuilder::create` * `os::unix::fs::DirBuilderExt` * `os::unix::fs::DirBuilderExt::mode` * `vec::Drain` * `vec::Vec::drain` * `string::Drain` * `string::String::drain` * `vec_deque::Drain` * `vec_deque::VecDeque::drain` * `collections::hash_map::Drain` * `collections::hash_map::HashMap::drain` * `collections::hash_set::Drain` * `collections::hash_set::HashSet::drain` * `collections::binary_heap::Drain` * `collections::binary_heap::BinaryHeap::drain` * `Vec::extend_from_slice` (renamed from `push_all`) * `Mutex::get_mut` * `Mutex::into_inner` * `RwLock::get_mut` * `RwLock::into_inner` * `Iterator::min_by_key` (renamed from `min_by`) * `Iterator::max_by_key` (renamed from `max_by`) Deprecated APIs * `ErrorKind::UnexpectedEOF` (renamed to `UnexpectedEof`) * `OsString::from_bytes` * `OsStr::to_cstring` * `OsStr::to_bytes` * `fs::walk_dir` and `fs::WalkDir` * `path::Components::peek` * `slice::bytes::MutableByteVector` * `slice::bytes::copy_memory` * `Vec::push_all` (renamed to `extend_from_slice`) * `Duration::span` * `IpAddr` * `SocketAddr::ip` * `Read::tee` * `io::Tee` * `Write::broadcast` * `io::Broadcast` * `Iterator::min_by` (renamed to `min_by_key`) * `Iterator::max_by` (renamed to `max_by_key`) * `net::lookup_addr` New APIs (still unstable) * `<[T]>::sort_by_key` (added to mirror `min_by_key`) Closes #27585 Closes #27704 Closes #27707 Closes #27710 Closes #27711 Closes #27727 Closes #27740 Closes #27744 Closes #27799 Closes #27801 cc #27801 (doesn't close as `Chars` is still unstable) Closes #28968
2015-12-02 17:31:49 -08:00
#[unstable(feature = "fn_traits", issue = "29625")]
extern "rust-call" fn call(&self, args: Args) -> Self::Output;
}
/// A version of the call operator that takes a mutable receiver.
#[lang = "fn_mut"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_paren_sugar]
#[fundamental] // so that regex can rely that `&str: !FnMut`
pub trait FnMut<Args> : FnOnce<Args> {
/// This is called when the call operator is used.
std: Stabilize APIs for the 1.6 release This commit is the standard API stabilization commit for the 1.6 release cycle. The list of issues and APIs below have all been through their cycle-long FCP and the libs team decisions are listed below Stabilized APIs * `Read::read_exact` * `ErrorKind::UnexpectedEof` (renamed from `UnexpectedEOF`) * libcore -- this was a bit of a nuanced stabilization, the crate itself is now marked as `#[stable]` and the methods appearing via traits for primitives like `char` and `str` are now also marked as stable. Note that the extension traits themeselves are marked as unstable as they're imported via the prelude. The `try!` macro was also moved from the standard library into libcore to have the same interface. Otherwise the functions all have copied stability from the standard library now. * The `#![no_std]` attribute * `fs::DirBuilder` * `fs::DirBuilder::new` * `fs::DirBuilder::recursive` * `fs::DirBuilder::create` * `os::unix::fs::DirBuilderExt` * `os::unix::fs::DirBuilderExt::mode` * `vec::Drain` * `vec::Vec::drain` * `string::Drain` * `string::String::drain` * `vec_deque::Drain` * `vec_deque::VecDeque::drain` * `collections::hash_map::Drain` * `collections::hash_map::HashMap::drain` * `collections::hash_set::Drain` * `collections::hash_set::HashSet::drain` * `collections::binary_heap::Drain` * `collections::binary_heap::BinaryHeap::drain` * `Vec::extend_from_slice` (renamed from `push_all`) * `Mutex::get_mut` * `Mutex::into_inner` * `RwLock::get_mut` * `RwLock::into_inner` * `Iterator::min_by_key` (renamed from `min_by`) * `Iterator::max_by_key` (renamed from `max_by`) Deprecated APIs * `ErrorKind::UnexpectedEOF` (renamed to `UnexpectedEof`) * `OsString::from_bytes` * `OsStr::to_cstring` * `OsStr::to_bytes` * `fs::walk_dir` and `fs::WalkDir` * `path::Components::peek` * `slice::bytes::MutableByteVector` * `slice::bytes::copy_memory` * `Vec::push_all` (renamed to `extend_from_slice`) * `Duration::span` * `IpAddr` * `SocketAddr::ip` * `Read::tee` * `io::Tee` * `Write::broadcast` * `io::Broadcast` * `Iterator::min_by` (renamed to `min_by_key`) * `Iterator::max_by` (renamed to `max_by_key`) * `net::lookup_addr` New APIs (still unstable) * `<[T]>::sort_by_key` (added to mirror `min_by_key`) Closes #27585 Closes #27704 Closes #27707 Closes #27710 Closes #27711 Closes #27727 Closes #27740 Closes #27744 Closes #27799 Closes #27801 cc #27801 (doesn't close as `Chars` is still unstable) Closes #28968
2015-12-02 17:31:49 -08:00
#[unstable(feature = "fn_traits", issue = "29625")]
extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
}
/// A version of the call operator that takes a by-value receiver.
#[lang = "fn_once"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_paren_sugar]
#[fundamental] // so that regex can rely that `&str: !FnMut`
pub trait FnOnce<Args> {
/// The returned type after the call operator is used.
#[stable(feature = "fn_once_output", since = "1.12.0")]
type Output;
/// This is called when the call operator is used.
std: Stabilize APIs for the 1.6 release This commit is the standard API stabilization commit for the 1.6 release cycle. The list of issues and APIs below have all been through their cycle-long FCP and the libs team decisions are listed below Stabilized APIs * `Read::read_exact` * `ErrorKind::UnexpectedEof` (renamed from `UnexpectedEOF`) * libcore -- this was a bit of a nuanced stabilization, the crate itself is now marked as `#[stable]` and the methods appearing via traits for primitives like `char` and `str` are now also marked as stable. Note that the extension traits themeselves are marked as unstable as they're imported via the prelude. The `try!` macro was also moved from the standard library into libcore to have the same interface. Otherwise the functions all have copied stability from the standard library now. * The `#![no_std]` attribute * `fs::DirBuilder` * `fs::DirBuilder::new` * `fs::DirBuilder::recursive` * `fs::DirBuilder::create` * `os::unix::fs::DirBuilderExt` * `os::unix::fs::DirBuilderExt::mode` * `vec::Drain` * `vec::Vec::drain` * `string::Drain` * `string::String::drain` * `vec_deque::Drain` * `vec_deque::VecDeque::drain` * `collections::hash_map::Drain` * `collections::hash_map::HashMap::drain` * `collections::hash_set::Drain` * `collections::hash_set::HashSet::drain` * `collections::binary_heap::Drain` * `collections::binary_heap::BinaryHeap::drain` * `Vec::extend_from_slice` (renamed from `push_all`) * `Mutex::get_mut` * `Mutex::into_inner` * `RwLock::get_mut` * `RwLock::into_inner` * `Iterator::min_by_key` (renamed from `min_by`) * `Iterator::max_by_key` (renamed from `max_by`) Deprecated APIs * `ErrorKind::UnexpectedEOF` (renamed to `UnexpectedEof`) * `OsString::from_bytes` * `OsStr::to_cstring` * `OsStr::to_bytes` * `fs::walk_dir` and `fs::WalkDir` * `path::Components::peek` * `slice::bytes::MutableByteVector` * `slice::bytes::copy_memory` * `Vec::push_all` (renamed to `extend_from_slice`) * `Duration::span` * `IpAddr` * `SocketAddr::ip` * `Read::tee` * `io::Tee` * `Write::broadcast` * `io::Broadcast` * `Iterator::min_by` (renamed to `min_by_key`) * `Iterator::max_by` (renamed to `max_by_key`) * `net::lookup_addr` New APIs (still unstable) * `<[T]>::sort_by_key` (added to mirror `min_by_key`) Closes #27585 Closes #27704 Closes #27707 Closes #27710 Closes #27711 Closes #27727 Closes #27740 Closes #27744 Closes #27799 Closes #27801 cc #27801 (doesn't close as `Chars` is still unstable) Closes #28968
2015-12-02 17:31:49 -08:00
#[unstable(feature = "fn_traits", issue = "29625")]
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}
mod impls {
use marker::Sized;
use super::{Fn, FnMut, FnOnce};
2015-11-16 19:54:28 +03:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a,A,F:?Sized> Fn<A> for &'a F
where F : Fn<A>
{
extern "rust-call" fn call(&self, args: A) -> F::Output {
(**self).call(args)
}
}
2015-11-16 19:54:28 +03:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a,A,F:?Sized> FnMut<A> for &'a F
where F : Fn<A>
{
extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
(**self).call(args)
}
}
2015-11-16 19:54:28 +03:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a,A,F:?Sized> FnOnce<A> for &'a F
where F : Fn<A>
{
type Output = F::Output;
extern "rust-call" fn call_once(self, args: A) -> F::Output {
(*self).call(args)
}
}
2015-11-16 19:54:28 +03:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a,A,F:?Sized> FnMut<A> for &'a mut F
where F : FnMut<A>
{
extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
(*self).call_mut(args)
}
}
2015-11-16 19:54:28 +03:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a,A,F:?Sized> FnOnce<A> for &'a mut F
where F : FnMut<A>
{
type Output = F::Output;
extern "rust-call" fn call_once(mut self, args: A) -> F::Output {
(*self).call_mut(args)
}
}
}
/// Trait that indicates that this is a pointer or a wrapper for one,
/// where unsizing can be performed on the pointee.
#[unstable(feature = "coerce_unsized", issue = "27732")]
#[lang="coerce_unsized"]
pub trait CoerceUnsized<T> {
// Empty.
}
2015-05-12 14:41:08 +12:00
// &mut T -> &mut U
2015-11-16 19:54:28 +03:00
#[unstable(feature = "coerce_unsized", issue = "27732")]
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
2015-05-12 14:41:08 +12:00
// &mut T -> &U
2015-11-16 19:54:28 +03:00
#[unstable(feature = "coerce_unsized", issue = "27732")]
impl<'a, 'b: 'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {}
2015-05-12 14:41:08 +12:00
// &mut T -> *mut U
2015-11-16 19:54:28 +03:00
#[unstable(feature = "coerce_unsized", issue = "27732")]
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {}
2015-05-12 14:41:08 +12:00
// &mut T -> *const U
2015-11-16 19:54:28 +03:00
#[unstable(feature = "coerce_unsized", issue = "27732")]
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {}
2015-05-12 14:41:08 +12:00
// &T -> &U
2015-11-16 19:54:28 +03:00
#[unstable(feature = "coerce_unsized", issue = "27732")]
impl<'a, 'b: 'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
2015-05-12 14:41:08 +12:00
// &T -> *const U
2015-11-16 19:54:28 +03:00
#[unstable(feature = "coerce_unsized", issue = "27732")]
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {}
2015-05-12 14:41:08 +12:00
// *mut T -> *mut U
2015-11-16 19:54:28 +03:00
#[unstable(feature = "coerce_unsized", issue = "27732")]
impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
2015-05-12 14:41:08 +12:00
// *mut T -> *const U
2015-11-16 19:54:28 +03:00
#[unstable(feature = "coerce_unsized", issue = "27732")]
impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
2015-05-12 14:41:08 +12:00
// *const T -> *const U
2015-11-16 19:54:28 +03:00
#[unstable(feature = "coerce_unsized", issue = "27732")]
impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
/// Both `in (PLACE) EXPR` and `box EXPR` desugar into expressions
/// that allocate an intermediate "place" that holds uninitialized
/// state. The desugaring evaluates EXPR, and writes the result at
/// the address returned by the `pointer` method of this trait.
///
/// A `Place` can be thought of as a special representation for a
/// hypothetical `&uninit` reference (which Rust cannot currently
/// express directly). That is, it represents a pointer to
/// uninitialized storage.
///
/// The client is responsible for two steps: First, initializing the
/// payload (it can access its address via `pointer`). Second,
/// converting the agent to an instance of the owning pointer, via the
/// appropriate `finalize` method (see the `InPlace`.
///
/// If evaluating EXPR fails, then the destructor for the
/// implementation of Place to clean up any intermediate state
/// (e.g. deallocate box storage, pop a stack, etc).
#[unstable(feature = "placement_new_protocol", issue = "27779")]
pub trait Place<Data: ?Sized> {
/// Returns the address where the input value will be written.
/// Note that the data at this address is generally uninitialized,
/// and thus one should use `ptr::write` for initializing it.
fn pointer(&mut self) -> *mut Data;
}
/// Interface to implementations of `in (PLACE) EXPR`.
///
/// `in (PLACE) EXPR` effectively desugars into:
///
/// ```rust,ignore
/// let p = PLACE;
/// let mut place = Placer::make_place(p);
/// let raw_place = Place::pointer(&mut place);
/// let value = EXPR;
/// unsafe {
/// std::ptr::write(raw_place, value);
/// InPlace::finalize(place)
/// }
/// ```
///
/// The type of `in (PLACE) EXPR` is derived from the type of `PLACE`;
/// if the type of `PLACE` is `P`, then the final type of the whole
/// expression is `P::Place::Owner` (see the `InPlace` and `Boxed`
/// traits).
///
/// Values for types implementing this trait usually are transient
/// intermediate values (e.g. the return value of `Vec::emplace_back`)
/// or `Copy`, since the `make_place` method takes `self` by value.
#[unstable(feature = "placement_new_protocol", issue = "27779")]
pub trait Placer<Data: ?Sized> {
/// `Place` is the intermedate agent guarding the
/// uninitialized state for `Data`.
type Place: InPlace<Data>;
/// Creates a fresh place from `self`.
fn make_place(self) -> Self::Place;
}
/// Specialization of `Place` trait supporting `in (PLACE) EXPR`.
#[unstable(feature = "placement_new_protocol", issue = "27779")]
pub trait InPlace<Data: ?Sized>: Place<Data> {
/// `Owner` is the type of the end value of `in (PLACE) EXPR`
///
/// Note that when `in (PLACE) EXPR` is solely used for
/// side-effecting an existing data-structure,
/// e.g. `Vec::emplace_back`, then `Owner` need not carry any
/// information at all (e.g. it can be the unit type `()` in that
/// case).
type Owner;
/// Converts self into the final value, shifting
/// deallocation/cleanup responsibilities (if any remain), over to
/// the returned instance of `Owner` and forgetting self.
unsafe fn finalize(self) -> Self::Owner;
}
/// Core trait for the `box EXPR` form.
///
/// `box EXPR` effectively desugars into:
///
/// ```rust,ignore
/// let mut place = BoxPlace::make_place();
/// let raw_place = Place::pointer(&mut place);
/// let value = EXPR;
/// unsafe {
/// ::std::ptr::write(raw_place, value);
/// Boxed::finalize(place)
/// }
/// ```
///
/// The type of `box EXPR` is supplied from its surrounding
/// context; in the above expansion, the result type `T` is used
/// to determine which implementation of `Boxed` to use, and that
/// `<T as Boxed>` in turn dictates determines which
/// implementation of `BoxPlace` to use, namely:
/// `<<T as Boxed>::Place as BoxPlace>`.
#[unstable(feature = "placement_new_protocol", issue = "27779")]
pub trait Boxed {
/// The kind of data that is stored in this kind of box.
type Data; /* (`Data` unused b/c cannot yet express below bound.) */
/// The place that will negotiate the storage of the data.
type Place: BoxPlace<Self::Data>;
/// Converts filled place into final owning value, shifting
/// deallocation/cleanup responsibilities (if any remain), over to
/// returned instance of `Self` and forgetting `filled`.
unsafe fn finalize(filled: Self::Place) -> Self;
}
/// Specialization of `Place` trait supporting `box EXPR`.
#[unstable(feature = "placement_new_protocol", issue = "27779")]
pub trait BoxPlace<Data: ?Sized> : Place<Data> {
/// Creates a globally fresh place.
fn make_place() -> Self;
}