// 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 or the MIT license // , 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` 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}; //! //! #[derive(Debug)] //! struct Point { //! x: i32, //! y: i32, //! } //! //! impl Add for Point { //! type Output = Point; //! //! fn add(self, other: Point) -> Point { //! Point {x: self.x + other.x, y: self.y + other.y} //! } //! } //! //! impl Sub for Point { //! type Output = Point; //! //! fn sub(self, other: Point) -> Point { //! Point {x: self.x - other.x, y: self.y - other.y} //! } //! } //! fn main() { //! 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. #![stable(feature = "rust1", since = "1.0.0")] use cmp::PartialOrd; 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"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Drop { /// A method called when the value goes out of scope. /// /// 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. #[stable(feature = "rust1", since = "1.0.0")] 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; /// /// impl Add for Foo { /// type Output = Foo; /// /// fn add(self, _rhs: Foo) -> Foo { /// println!("Adding!"); /// self /// } /// } /// /// fn main() { /// Foo + Foo; /// } /// ``` #[lang = "add"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Add { /// The resulting type after applying the `+` operator #[stable(feature = "rust1", since = "1.0.0")] type Output; /// The method for the `+` operator #[stable(feature = "rust1", since = "1.0.0")] fn add(self, rhs: RHS) -> Self::Output; } macro_rules! add_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] 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 } )*) } 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; /// /// impl Sub for Foo { /// type Output = Foo; /// /// fn sub(self, _rhs: Foo) -> Foo { /// println!("Subtracting!"); /// self /// } /// } /// /// fn main() { /// Foo - Foo; /// } /// ``` #[lang = "sub"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Sub { /// The resulting type after applying the `-` operator #[stable(feature = "rust1", since = "1.0.0")] type Output; /// The method for the `-` operator #[stable(feature = "rust1", since = "1.0.0")] fn sub(self, rhs: RHS) -> Self::Output; } macro_rules! sub_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] 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 } )*) } 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; /// /// impl Mul for Foo { /// type Output = Foo; /// /// fn mul(self, _rhs: Foo) -> Foo { /// println!("Multiplying!"); /// self /// } /// } /// /// fn main() { /// Foo * Foo; /// } /// ``` #[lang = "mul"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Mul { /// The resulting type after applying the `*` operator #[stable(feature = "rust1", since = "1.0.0")] type Output; /// The method for the `*` operator #[stable(feature = "rust1", since = "1.0.0")] fn mul(self, rhs: RHS) -> Self::Output; } macro_rules! mul_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] 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 } )*) } 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; /// /// impl Div for Foo { /// type Output = Foo; /// /// fn div(self, _rhs: Foo) -> Foo { /// println!("Dividing!"); /// self /// } /// } /// /// fn main() { /// Foo / Foo; /// } /// ``` #[lang = "div"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Div { /// The resulting type after applying the `/` operator #[stable(feature = "rust1", since = "1.0.0")] type Output; /// The method for the `/` operator #[stable(feature = "rust1", since = "1.0.0")] 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)*) => ($( #[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_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; /// /// impl Rem for Foo { /// type Output = Foo; /// /// fn rem(self, _rhs: Foo) -> Foo { /// println!("Remainder-ing!"); /// self /// } /// } /// /// fn main() { /// Foo % Foo; /// } /// ``` #[lang = "rem"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Rem { /// The resulting type after applying the `%` operator #[stable(feature = "rust1", since = "1.0.0")] type Output = Self; /// The method for the `%` operator #[stable(feature = "rust1", since = "1.0.0")] 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. #[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_integer! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } 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; /// /// impl Neg for Foo { /// type Output = Foo; /// /// fn neg(self) -> Foo { /// println!("Negating!"); /// self /// } /// } /// /// fn main() { /// -Foo; /// } /// ``` #[lang = "neg"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Neg { /// The resulting type after applying the `-` operator #[stable(feature = "rust1", since = "1.0.0")] type Output; /// The method for the unary `-` operator #[stable(feature = "rust1", since = "1.0.0")] fn neg(self) -> Self::Output; } macro_rules! neg_impl_core { ($id:ident => $body:expr, $($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] 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; /// /// impl Not for Foo { /// type Output = Foo; /// /// fn not(self) -> Foo { /// println!("Not-ing!"); /// self /// } /// } /// /// fn main() { /// !Foo; /// } /// ``` #[lang = "not"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Not { /// The resulting type after applying the `!` operator #[stable(feature = "rust1", since = "1.0.0")] type Output; /// The method for the unary `!` operator #[stable(feature = "rust1", since = "1.0.0")] fn not(self) -> Self::Output; } macro_rules! not_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] impl Not for $t { type Output = $t; #[inline] fn not(self) -> $t { !self } } forward_ref_unop! { impl Not, not for $t } )*) } 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; /// /// impl BitAnd for Foo { /// type Output = Foo; /// /// fn bitand(self, _rhs: Foo) -> Foo { /// println!("Bitwise And-ing!"); /// self /// } /// } /// /// fn main() { /// Foo & Foo; /// } /// ``` #[lang = "bitand"] #[stable(feature = "rust1", since = "1.0.0")] pub trait BitAnd { /// The resulting type after applying the `&` operator #[stable(feature = "rust1", since = "1.0.0")] type Output; /// The method for the `&` operator #[stable(feature = "rust1", since = "1.0.0")] fn bitand(self, rhs: RHS) -> Self::Output; } macro_rules! bitand_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] 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 } )*) } 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; /// /// impl BitOr for Foo { /// type Output = Foo; /// /// fn bitor(self, _rhs: Foo) -> Foo { /// println!("Bitwise Or-ing!"); /// self /// } /// } /// /// fn main() { /// Foo | Foo; /// } /// ``` #[lang = "bitor"] #[stable(feature = "rust1", since = "1.0.0")] pub trait BitOr { /// The resulting type after applying the `|` operator #[stable(feature = "rust1", since = "1.0.0")] type Output; /// The method for the `|` operator #[stable(feature = "rust1", since = "1.0.0")] fn bitor(self, rhs: RHS) -> Self::Output; } macro_rules! bitor_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] 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 } )*) } 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; /// /// impl BitXor for Foo { /// type Output = Foo; /// /// fn bitxor(self, _rhs: Foo) -> Foo { /// println!("Bitwise Xor-ing!"); /// self /// } /// } /// /// fn main() { /// Foo ^ Foo; /// } /// ``` #[lang = "bitxor"] #[stable(feature = "rust1", since = "1.0.0")] pub trait BitXor { /// The resulting type after applying the `^` operator #[stable(feature = "rust1", since = "1.0.0")] type Output; /// The method for the `^` operator #[stable(feature = "rust1", since = "1.0.0")] fn bitxor(self, rhs: RHS) -> Self::Output; } macro_rules! bitxor_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] 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 } )*) } 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; /// /// impl Shl for Foo { /// type Output = Foo; /// /// fn shl(self, _rhs: Foo) -> Foo { /// println!("Shifting left!"); /// self /// } /// } /// /// fn main() { /// Foo << Foo; /// } /// ``` #[lang = "shl"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Shl { /// The resulting type after applying the `<<` operator #[stable(feature = "rust1", since = "1.0.0")] type Output; /// The method for the `<<` operator #[stable(feature = "rust1", since = "1.0.0")] fn shl(self, rhs: RHS) -> Self::Output; } macro_rules! shl_impl { ($t:ty, $f:ty) => ( #[stable(feature = "rust1", since = "1.0.0")] impl Shl<$f> for $t { 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; /// /// impl Shr for Foo { /// type Output = Foo; /// /// fn shr(self, _rhs: Foo) -> Foo { /// println!("Shifting right!"); /// self /// } /// } /// /// fn main() { /// Foo >> Foo; /// } /// ``` #[lang = "shr"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Shr { /// The resulting type after applying the `>>` operator #[stable(feature = "rust1", since = "1.0.0")] type Output; /// The method for the `>>` operator #[stable(feature = "rust1", since = "1.0.0")] fn shr(self, rhs: RHS) -> Self::Output; } macro_rules! shr_impl { ($t:ty, $f:ty) => ( #[stable(feature = "rust1", since = "1.0.0")] impl Shr<$f> for $t { 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 } /// 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!"); /// } /// } /// /// # #[allow(unused_assignments)] /// fn main() { /// let mut foo = Foo; /// foo += Foo; /// } /// ``` #[lang = "add_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] pub trait AddAssign { /// The method for the `+=` operator #[stable(feature = "op_assign_traits", since = "1.8.0")] fn add_assign(&mut self, Rhs); } macro_rules! add_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] impl AddAssign for $t { #[inline] #[rustc_inherit_overflow_checks] 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!"); /// } /// } /// /// # #[allow(unused_assignments)] /// fn main() { /// let mut foo = Foo; /// foo -= Foo; /// } /// ``` #[lang = "sub_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] pub trait SubAssign { /// The method for the `-=` operator #[stable(feature = "op_assign_traits", since = "1.8.0")] fn sub_assign(&mut self, Rhs); } macro_rules! sub_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] impl SubAssign for $t { #[inline] #[rustc_inherit_overflow_checks] 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!"); /// } /// } /// /// # #[allow(unused_assignments)] /// fn main() { /// let mut foo = Foo; /// foo *= Foo; /// } /// ``` #[lang = "mul_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] pub trait MulAssign { /// The method for the `*=` operator #[stable(feature = "op_assign_traits", since = "1.8.0")] fn mul_assign(&mut self, Rhs); } macro_rules! mul_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] impl MulAssign for $t { #[inline] #[rustc_inherit_overflow_checks] 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!"); /// } /// } /// /// # #[allow(unused_assignments)] /// fn main() { /// let mut foo = Foo; /// foo /= Foo; /// } /// ``` #[lang = "div_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] pub trait DivAssign { /// The method for the `/=` operator #[stable(feature = "op_assign_traits", since = "1.8.0")] fn div_assign(&mut self, Rhs); } macro_rules! div_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] 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!"); /// } /// } /// /// # #[allow(unused_assignments)] /// fn main() { /// let mut foo = Foo; /// foo %= Foo; /// } /// ``` #[lang = "rem_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] pub trait RemAssign { /// The method for the `%=` operator #[stable(feature = "op_assign_traits", since = "1.8.0")] fn rem_assign(&mut self, Rhs); } macro_rules! rem_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] 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!"); /// } /// } /// /// # #[allow(unused_assignments)] /// fn main() { /// let mut foo = Foo; /// foo &= Foo; /// } /// ``` #[lang = "bitand_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] pub trait BitAndAssign { /// The method for the `&` operator #[stable(feature = "op_assign_traits", since = "1.8.0")] fn bitand_assign(&mut self, Rhs); } macro_rules! bitand_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] 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!"); /// } /// } /// /// # #[allow(unused_assignments)] /// fn main() { /// let mut foo = Foo; /// foo |= Foo; /// } /// ``` #[lang = "bitor_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] pub trait BitOrAssign { /// The method for the `|=` operator #[stable(feature = "op_assign_traits", since = "1.8.0")] fn bitor_assign(&mut self, Rhs); } macro_rules! bitor_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] 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!"); /// } /// } /// /// # #[allow(unused_assignments)] /// fn main() { /// let mut foo = Foo; /// foo ^= Foo; /// } /// ``` #[lang = "bitxor_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] pub trait BitXorAssign { /// The method for the `^=` operator #[stable(feature = "op_assign_traits", since = "1.8.0")] fn bitxor_assign(&mut self, Rhs); } macro_rules! bitxor_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] 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 for Foo { /// fn shl_assign(&mut self, _rhs: Foo) { /// println!("Shifting left!"); /// } /// } /// /// # #[allow(unused_assignments)] /// fn main() { /// let mut foo = Foo; /// foo <<= Foo; /// } /// ``` #[lang = "shl_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] pub trait ShlAssign { /// The method for the `<<=` operator #[stable(feature = "op_assign_traits", since = "1.8.0")] fn shl_assign(&mut self, Rhs); } macro_rules! shl_assign_impl { ($t:ty, $f:ty) => ( #[stable(feature = "op_assign_traits", since = "1.8.0")] impl ShlAssign<$f> for $t { #[inline] #[rustc_inherit_overflow_checks] 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 for Foo { /// fn shr_assign(&mut self, _rhs: Foo) { /// println!("Shifting right!"); /// } /// } /// /// # #[allow(unused_assignments)] /// fn main() { /// let mut foo = Foo; /// foo >>= Foo; /// } /// ``` #[lang = "shr_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] pub trait ShrAssign { /// The method for the `>>=` operator #[stable(feature = "op_assign_traits", since = "1.8.0")] fn shr_assign(&mut self, Rhs); } macro_rules! shr_assign_impl { ($t:ty, $f:ty) => ( #[stable(feature = "op_assign_traits", since = "1.8.0")] impl ShrAssign<$f> for $t { #[inline] #[rustc_inherit_overflow_checks] 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 for Foo { /// 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 { /// The returned type after indexing #[stable(feature = "rust1", since = "1.0.0")] type Output: ?Sized; /// The method for the indexing (`Foo[Bar]`) operation #[stable(feature = "rust1", since = "1.0.0")] fn index(&self, index: Idx) -> &Self::Output; } /// 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 for Foo { /// type Output = Foo; /// /// fn index<'a>(&'a self, _index: Bar) -> &'a Foo { /// self /// } /// } /// /// impl IndexMut 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: Index { /// The method for the indexing (`Foo[Bar]`) operation #[stable(feature = "rust1", since = "1.0.0")] 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 ]); /// ``` #[derive(Copy, Clone, PartialEq, Eq, Hash)] #[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, "..") } } /// 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 /// } /// ``` #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct Range { /// The lower bound of the range (inclusive). #[stable(feature = "rust1", since = "1.0.0")] pub start: 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")] impl fmt::Debug for Range { 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> Range { /// # 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 ]); /// } /// ``` #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeFrom { /// The lower bound of the range (inclusive). #[stable(feature = "rust1", since = "1.0.0")] pub start: Idx, } #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for RangeFrom { 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> RangeFrom { /// # 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. /// /// ``` /// 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 ]); /// } /// ``` #[derive(Copy, Clone, PartialEq, Eq, Hash)] #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeTo { /// The upper bound of the range (exclusive). #[stable(feature = "rust1", since = "1.0.0")] pub end: Idx, } #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for RangeTo { 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> RangeTo { /// # 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 { /// Empty range (iteration has finished) #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] Empty { /// The point at which iteration finished #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] at: Idx }, /// Non-empty range (iteration will yield value(s)) #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] NonEmpty { /// The lower bound of the range (inclusive). #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] start: Idx, /// The upper bound of the range (inclusive). #[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 fmt::Debug for RangeInclusive { 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> RangeInclusive { /// # 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 ]); /// } /// ``` #[derive(Copy, Clone, PartialEq, Eq, Hash)] #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] pub struct RangeToInclusive { /// 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 fmt::Debug for RangeToInclusive { 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> RangeToInclusive { /// # 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 cannot impl From> // 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 { /// value: T /// } /// /// impl Deref for DerefExample { /// type Target = T; /// /// fn deref(&self) -> &T { /// &self.value /// } /// } /// /// fn main() { /// let x = DerefExample { value: 'a' }; /// assert_eq!('a', *x); /// } /// ``` #[lang = "deref"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Deref { /// The resulting type after dereferencing #[stable(feature = "rust1", since = "1.0.0")] type Target: ?Sized; /// The method called to dereference a value #[stable(feature = "rust1", since = "1.0.0")] fn deref(&self) -> &Self::Target; } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T: ?Sized> Deref for &'a T { type Target = T; fn deref(&self) -> &T { *self } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T: ?Sized> Deref for &'a mut T { 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 { /// value: T /// } /// /// impl Deref for DerefMutExample { /// type Target = T; /// /// fn deref<'a>(&'a self) -> &'a T { /// &self.value /// } /// } /// /// impl DerefMut for DerefMutExample { /// 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"] #[stable(feature = "rust1", since = "1.0.0")] pub trait DerefMut: Deref { /// The method called to mutably dereference a value #[stable(feature = "rust1", since = "1.0.0")] fn deref_mut(&mut self) -> &mut Self::Target; } #[stable(feature = "rust1", since = "1.0.0")] 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 : FnMut { /// This is called when the call operator is used. #[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 : FnOnce { /// This is called when the call operator is used. #[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 { /// 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. #[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}; #[stable(feature = "rust1", since = "1.0.0")] impl<'a,A,F:?Sized> Fn for &'a F where F : Fn { extern "rust-call" fn call(&self, args: A) -> F::Output { (**self).call(args) } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a,A,F:?Sized> FnMut for &'a F where F : Fn { extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output { (**self).call(args) } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a,A,F:?Sized> FnOnce for &'a F where F : Fn { type Output = F::Output; extern "rust-call" fn call_once(self, args: A) -> F::Output { (*self).call(args) } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a,A,F:?Sized> FnMut for &'a mut F where F : FnMut { extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output { (*self).call_mut(args) } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a,A,F:?Sized> FnOnce for &'a mut F where F : FnMut { 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 { // Empty. } // &mut T -> &mut U #[unstable(feature = "coerce_unsized", issue = "27732")] impl<'a, T: ?Sized+Unsize, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {} // &mut T -> &U #[unstable(feature = "coerce_unsized", issue = "27732")] impl<'a, 'b: 'a, T: ?Sized+Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {} // &mut T -> *mut U #[unstable(feature = "coerce_unsized", issue = "27732")] impl<'a, T: ?Sized+Unsize, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {} // &mut T -> *const U #[unstable(feature = "coerce_unsized", issue = "27732")] impl<'a, T: ?Sized+Unsize, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {} // &T -> &U #[unstable(feature = "coerce_unsized", issue = "27732")] impl<'a, 'b: 'a, T: ?Sized+Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} // &T -> *const U #[unstable(feature = "coerce_unsized", issue = "27732")] impl<'a, T: ?Sized+Unsize, U: ?Sized> CoerceUnsized<*const U> for &'a T {} // *mut T -> *mut U #[unstable(feature = "coerce_unsized", issue = "27732")] impl, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} // *mut T -> *const U #[unstable(feature = "coerce_unsized", issue = "27732")] impl, U: ?Sized> CoerceUnsized<*const U> for *mut T {} // *const T -> *const U #[unstable(feature = "coerce_unsized", issue = "27732")] impl, 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 { /// 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 { /// `Place` is the intermedate agent guarding the /// uninitialized state for `Data`. type Place: InPlace; /// 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: Place { /// `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 /// `` in turn dictates determines which /// implementation of `BoxPlace` to use, namely: /// `<::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; /// 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 : Place { /// Creates a globally fresh place. fn make_place() -> Self; }