Auto merge of #43724 - lukaramu:std-ops-docs, r=QuietMisdreavus
Improve std::ops docs Fixes #29365. (This fixes all but one point from @steveklabnik's list, but that point was referring to examples of implementing range traits, but there are no range traits in std::ops.) The main changes are quite a bit of copyediting, adding more "real" examples for some of the traits, incorporating some guidance from the API docs, more linking (cross-docs and to the book & reference), cleaning up examples, moving things around, and so on. Refer to the commit messages for more details. Note: I decided to link to the second edition of the book since I think it's more appropriate now for the sections I linked, if this is not okay, please say so!
This commit is contained in:
commit
f774bced50
8 changed files with 612 additions and 526 deletions
|
@ -10,15 +10,20 @@
|
|||
|
||||
/// The addition operator `+`.
|
||||
///
|
||||
/// Note that `RHS` is `Self` by default, but this is not mandatory. For
|
||||
/// example, [`std::time::SystemTime`] implements `Add<Duration>`, which permits
|
||||
/// operations of the form `SystemTime = SystemTime + Duration`.
|
||||
///
|
||||
/// [`std::time::SystemTime`]: ../../std/time/struct.SystemTime.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// This example creates a `Point` struct that implements the `Add` trait, and
|
||||
/// then demonstrates adding two `Point`s.
|
||||
/// ## `Add`able points
|
||||
///
|
||||
/// ```
|
||||
/// use std::ops::Add;
|
||||
///
|
||||
/// #[derive(Debug)]
|
||||
/// #[derive(Debug, PartialEq)]
|
||||
/// struct Point {
|
||||
/// x: i32,
|
||||
/// y: i32,
|
||||
|
@ -35,31 +40,25 @@
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// impl PartialEq for Point {
|
||||
/// fn eq(&self, other: &Self) -> bool {
|
||||
/// self.x == other.x && self.y == other.y
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
|
||||
/// Point { x: 3, y: 3 });
|
||||
/// }
|
||||
/// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
|
||||
/// Point { x: 3, y: 3 });
|
||||
/// ```
|
||||
///
|
||||
/// ## Implementing `Add` with generics
|
||||
///
|
||||
/// Here is an example of the same `Point` struct implementing the `Add` trait
|
||||
/// using generics.
|
||||
///
|
||||
/// ```
|
||||
/// use std::ops::Add;
|
||||
///
|
||||
/// #[derive(Debug)]
|
||||
/// #[derive(Debug, PartialEq)]
|
||||
/// struct Point<T> {
|
||||
/// x: T,
|
||||
/// y: T,
|
||||
/// }
|
||||
///
|
||||
/// // Notice that the implementation uses the `Output` associated type
|
||||
/// // Notice that the implementation uses the associated type `Output`.
|
||||
/// impl<T: Add<Output=T>> Add for Point<T> {
|
||||
/// type Output = Point<T>;
|
||||
///
|
||||
|
@ -71,32 +70,18 @@
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// impl<T: PartialEq> PartialEq for Point<T> {
|
||||
/// fn eq(&self, other: &Self) -> bool {
|
||||
/// self.x == other.x && self.y == other.y
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
|
||||
/// Point { x: 3, y: 3 });
|
||||
/// }
|
||||
/// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
|
||||
/// Point { x: 3, y: 3 });
|
||||
/// ```
|
||||
///
|
||||
/// Note that `RHS = Self` by default, but this is not mandatory. For example,
|
||||
/// [std::time::SystemTime] implements `Add<Duration>`, which permits
|
||||
/// operations of the form `SystemTime = SystemTime + Duration`.
|
||||
///
|
||||
/// [std::time::SystemTime]: ../../std/time/struct.SystemTime.html
|
||||
#[lang = "add"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented = "no implementation for `{Self} + {RHS}`"]
|
||||
pub trait Add<RHS=Self> {
|
||||
/// The resulting type after applying the `+` operator
|
||||
/// The resulting type after applying the `+` operator.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
type Output;
|
||||
|
||||
/// The method for the `+` operator
|
||||
/// Performs the `+` operation.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn add(self, rhs: RHS) -> Self::Output;
|
||||
}
|
||||
|
@ -120,15 +105,20 @@ add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
|
||||
/// The subtraction operator `-`.
|
||||
///
|
||||
/// Note that `RHS` is `Self` by default, but this is not mandatory. For
|
||||
/// example, [`std::time::SystemTime`] implements `Sub<Duration>`, which permits
|
||||
/// operations of the form `SystemTime = SystemTime - Duration`.
|
||||
///
|
||||
/// [`std::time::SystemTime`]: ../../std/time/struct.SystemTime.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// This example creates a `Point` struct that implements the `Sub` trait, and
|
||||
/// then demonstrates subtracting two `Point`s.
|
||||
/// ## `Sub`tractable points
|
||||
///
|
||||
/// ```
|
||||
/// use std::ops::Sub;
|
||||
///
|
||||
/// #[derive(Debug)]
|
||||
/// #[derive(Debug, PartialEq)]
|
||||
/// struct Point {
|
||||
/// x: i32,
|
||||
/// y: i32,
|
||||
|
@ -145,31 +135,25 @@ add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// impl PartialEq for Point {
|
||||
/// fn eq(&self, other: &Self) -> bool {
|
||||
/// self.x == other.x && self.y == other.y
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// assert_eq!(Point { x: 3, y: 3 } - Point { x: 2, y: 3 },
|
||||
/// Point { x: 1, y: 0 });
|
||||
/// }
|
||||
/// assert_eq!(Point { x: 3, y: 3 } - Point { x: 2, y: 3 },
|
||||
/// Point { x: 1, y: 0 });
|
||||
/// ```
|
||||
///
|
||||
/// ## Implementing `Sub` with generics
|
||||
///
|
||||
/// Here is an example of the same `Point` struct implementing the `Sub` trait
|
||||
/// using generics.
|
||||
///
|
||||
/// ```
|
||||
/// use std::ops::Sub;
|
||||
///
|
||||
/// #[derive(Debug)]
|
||||
/// #[derive(Debug, PartialEq)]
|
||||
/// struct Point<T> {
|
||||
/// x: T,
|
||||
/// y: T,
|
||||
/// }
|
||||
///
|
||||
/// // Notice that the implementation uses the `Output` associated type
|
||||
/// // Notice that the implementation uses the associated type `Output`.
|
||||
/// impl<T: Sub<Output=T>> Sub for Point<T> {
|
||||
/// type Output = Point<T>;
|
||||
///
|
||||
|
@ -181,32 +165,18 @@ add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// impl<T: PartialEq> PartialEq for Point<T> {
|
||||
/// fn eq(&self, other: &Self) -> bool {
|
||||
/// self.x == other.x && self.y == other.y
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// assert_eq!(Point { x: 2, y: 3 } - Point { x: 1, y: 0 },
|
||||
/// Point { x: 1, y: 3 });
|
||||
/// }
|
||||
/// assert_eq!(Point { x: 2, y: 3 } - Point { x: 1, y: 0 },
|
||||
/// Point { x: 1, y: 3 });
|
||||
/// ```
|
||||
///
|
||||
/// Note that `RHS = Self` by default, but this is not mandatory. For example,
|
||||
/// [std::time::SystemTime] implements `Sub<Duration>`, which permits
|
||||
/// operations of the form `SystemTime = SystemTime - Duration`.
|
||||
///
|
||||
/// [std::time::SystemTime]: ../../std/time/struct.SystemTime.html
|
||||
#[lang = "sub"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented = "no implementation for `{Self} - {RHS}`"]
|
||||
pub trait Sub<RHS=Self> {
|
||||
/// The resulting type after applying the `-` operator
|
||||
/// The resulting type after applying the `-` operator.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
type Output;
|
||||
|
||||
/// The method for the `-` operator
|
||||
/// Performs the `-` operation.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn sub(self, rhs: RHS) -> Self::Output;
|
||||
}
|
||||
|
@ -230,17 +200,19 @@ sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
|
||||
/// The multiplication operator `*`.
|
||||
///
|
||||
/// Note that `RHS` is `Self` by default, but this is not mandatory.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Implementing a `Mul`tipliable rational number struct:
|
||||
/// ## `Mul`tipliable rational numbers
|
||||
///
|
||||
/// ```
|
||||
/// use std::ops::Mul;
|
||||
///
|
||||
/// // The uniqueness of rational numbers in lowest terms is a consequence of
|
||||
/// // the fundamental theorem of arithmetic.
|
||||
/// #[derive(Eq)]
|
||||
/// #[derive(PartialEq, Debug)]
|
||||
/// // By the fundamental theorem of arithmetic, rational numbers in lowest
|
||||
/// // terms are unique. So, by keeping `Rational`s in reduced form, we can
|
||||
/// // derive `Eq` and `PartialEq`.
|
||||
/// #[derive(Debug, Eq, PartialEq)]
|
||||
/// struct Rational {
|
||||
/// nominator: usize,
|
||||
/// denominator: usize,
|
||||
|
@ -291,45 +263,37 @@ sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
/// Rational::new(1, 2));
|
||||
/// ```
|
||||
///
|
||||
/// Note that `RHS = Self` by default, but this is not mandatory. Here is an
|
||||
/// implementation which enables multiplication of vectors by scalars, as is
|
||||
/// done in linear algebra.
|
||||
/// ## Multiplying vectors by scalars as in linear algebra
|
||||
///
|
||||
/// ```
|
||||
/// use std::ops::Mul;
|
||||
///
|
||||
/// struct Scalar {value: usize};
|
||||
/// struct Scalar { value: usize }
|
||||
///
|
||||
/// #[derive(Debug)]
|
||||
/// struct Vector {value: Vec<usize>};
|
||||
/// #[derive(Debug, PartialEq)]
|
||||
/// struct Vector { value: Vec<usize> }
|
||||
///
|
||||
/// impl Mul<Vector> for Scalar {
|
||||
/// impl Mul<Scalar> for Vector {
|
||||
/// type Output = Vector;
|
||||
///
|
||||
/// fn mul(self, rhs: Vector) -> Vector {
|
||||
/// Vector {value: rhs.value.iter().map(|v| self.value * v).collect()}
|
||||
/// fn mul(self, rhs: Scalar) -> Vector {
|
||||
/// Vector { value: self.value.iter().map(|v| v * rhs.value).collect() }
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// impl PartialEq<Vector> for Vector {
|
||||
/// fn eq(&self, other: &Self) -> bool {
|
||||
/// self.value == other.value
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// let scalar = Scalar{value: 3};
|
||||
/// let vector = Vector{value: vec![2, 4, 6]};
|
||||
/// assert_eq!(scalar * vector, Vector{value: vec![6, 12, 18]});
|
||||
/// let vector = Vector { value: vec![2, 4, 6] };
|
||||
/// let scalar = Scalar { value: 3 };
|
||||
/// assert_eq!(vector * scalar, Vector { value: vec![6, 12, 18] });
|
||||
/// ```
|
||||
#[lang = "mul"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented = "no implementation for `{Self} * {RHS}`"]
|
||||
pub trait Mul<RHS=Self> {
|
||||
/// The resulting type after applying the `*` operator
|
||||
/// The resulting type after applying the `*` operator.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
type Output;
|
||||
|
||||
/// The method for the `*` operator
|
||||
/// Performs the `*` operation.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn mul(self, rhs: RHS) -> Self::Output;
|
||||
}
|
||||
|
@ -353,17 +317,19 @@ mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
|
||||
/// The division operator `/`.
|
||||
///
|
||||
/// Note that `RHS` is `Self` by default, but this is not mandatory.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Implementing a `Div`idable rational number struct:
|
||||
/// ## `Div`idable rational numbers
|
||||
///
|
||||
/// ```
|
||||
/// use std::ops::Div;
|
||||
///
|
||||
/// // The uniqueness of rational numbers in lowest terms is a consequence of
|
||||
/// // the fundamental theorem of arithmetic.
|
||||
/// #[derive(Eq)]
|
||||
/// #[derive(PartialEq, Debug)]
|
||||
/// // By the fundamental theorem of arithmetic, rational numbers in lowest
|
||||
/// // terms are unique. So, by keeping `Rational`s in reduced form, we can
|
||||
/// // derive `Eq` and `PartialEq`.
|
||||
/// #[derive(Debug, Eq, PartialEq)]
|
||||
/// struct Rational {
|
||||
/// nominator: usize,
|
||||
/// denominator: usize,
|
||||
|
@ -413,52 +379,42 @@ mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
/// x
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// assert_eq!(Rational::new(1, 2), Rational::new(2, 4));
|
||||
/// assert_eq!(Rational::new(1, 2) / Rational::new(3, 4),
|
||||
/// Rational::new(2, 3));
|
||||
/// }
|
||||
/// assert_eq!(Rational::new(1, 2), Rational::new(2, 4));
|
||||
/// assert_eq!(Rational::new(1, 2) / Rational::new(3, 4),
|
||||
/// Rational::new(2, 3));
|
||||
/// ```
|
||||
///
|
||||
/// Note that `RHS = Self` by default, but this is not mandatory. Here is an
|
||||
/// implementation which enables division of vectors by scalars, as is done in
|
||||
/// linear algebra.
|
||||
/// ## Dividing vectors by scalars as in linear algebra
|
||||
///
|
||||
/// ```
|
||||
/// use std::ops::Div;
|
||||
///
|
||||
/// struct Scalar {value: f32};
|
||||
/// struct Scalar { value: f32 }
|
||||
///
|
||||
/// #[derive(Debug)]
|
||||
/// struct Vector {value: Vec<f32>};
|
||||
/// #[derive(Debug, PartialEq)]
|
||||
/// struct Vector { value: Vec<f32> }
|
||||
///
|
||||
/// impl Div<Scalar> for Vector {
|
||||
/// type Output = Vector;
|
||||
///
|
||||
/// fn div(self, rhs: Scalar) -> Vector {
|
||||
/// Vector {value: self.value.iter().map(|v| v / rhs.value).collect()}
|
||||
/// Vector { value: self.value.iter().map(|v| v / rhs.value).collect() }
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// impl PartialEq<Vector> for Vector {
|
||||
/// fn eq(&self, other: &Self) -> bool {
|
||||
/// self.value == other.value
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// let scalar = Scalar{value: 2f32};
|
||||
/// let vector = Vector{value: vec![2f32, 4f32, 6f32]};
|
||||
/// assert_eq!(vector / scalar, Vector{value: vec![1f32, 2f32, 3f32]});
|
||||
/// let scalar = Scalar { value: 2f32 };
|
||||
/// let vector = Vector { value: vec![2f32, 4f32, 6f32] };
|
||||
/// assert_eq!(vector / scalar, Vector { value: vec![1f32, 2f32, 3f32] });
|
||||
/// ```
|
||||
#[lang = "div"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented = "no implementation for `{Self} / {RHS}`"]
|
||||
pub trait Div<RHS=Self> {
|
||||
/// The resulting type after applying the `/` operator
|
||||
/// The resulting type after applying the `/` operator.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
type Output;
|
||||
|
||||
/// The method for the `/` operator
|
||||
/// Performs the `/` operation.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn div(self, rhs: RHS) -> Self::Output;
|
||||
}
|
||||
|
@ -499,6 +455,8 @@ div_impl_float! { f32 f64 }
|
|||
|
||||
/// The remainder operator `%`.
|
||||
///
|
||||
/// Note that `RHS` is `Self` by default, but this is not mandatory.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// This example implements `Rem` on a `SplitSlice` object. After `Rem` is
|
||||
|
@ -526,7 +484,7 @@ div_impl_float! { f32 f64 }
|
|||
/// }
|
||||
///
|
||||
/// // If we were to divide &[0, 1, 2, 3, 4, 5, 6, 7] into slices of size 3,
|
||||
/// // the remainder would be &[6, 7]
|
||||
/// // the remainder would be &[6, 7].
|
||||
/// assert_eq!(SplitSlice { slice: &[0, 1, 2, 3, 4, 5, 6, 7] } % 3,
|
||||
/// SplitSlice { slice: &[6, 7] });
|
||||
/// ```
|
||||
|
@ -534,11 +492,11 @@ div_impl_float! { f32 f64 }
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented = "no implementation for `{Self} % {RHS}`"]
|
||||
pub trait Rem<RHS=Self> {
|
||||
/// The resulting type after applying the `%` operator
|
||||
/// The resulting type after applying the `%` operator.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
type Output = Self;
|
||||
|
||||
/// The method for the `%` operator
|
||||
/// Performs the `%` operation.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn rem(self, rhs: RHS) -> Self::Output;
|
||||
}
|
||||
|
@ -607,21 +565,21 @@ rem_impl_float! { f32 f64 }
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // a negative positive is a negative
|
||||
/// // A negative positive is a negative.
|
||||
/// assert_eq!(-Sign::Positive, Sign::Negative);
|
||||
/// // a double negative is a positive
|
||||
/// // A double negative is a positive.
|
||||
/// assert_eq!(-Sign::Negative, Sign::Positive);
|
||||
/// // zero is its own negation
|
||||
/// // Zero is its own negation.
|
||||
/// assert_eq!(-Sign::Zero, Sign::Zero);
|
||||
/// ```
|
||||
#[lang = "neg"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait Neg {
|
||||
/// The resulting type after applying the `-` operator
|
||||
/// The resulting type after applying the `-` operator.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
type Output;
|
||||
|
||||
/// The method for the unary `-` operator
|
||||
/// Performs the unary `-` operation.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn neg(self) -> Self::Output;
|
||||
}
|
||||
|
@ -668,7 +626,7 @@ neg_impl_numeric! { isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
/// ```
|
||||
/// use std::ops::AddAssign;
|
||||
///
|
||||
/// #[derive(Debug)]
|
||||
/// #[derive(Debug, PartialEq)]
|
||||
/// struct Point {
|
||||
/// x: i32,
|
||||
/// y: i32,
|
||||
|
@ -683,12 +641,6 @@ neg_impl_numeric! { isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// impl PartialEq for Point {
|
||||
/// fn eq(&self, other: &Self) -> bool {
|
||||
/// self.x == other.x && self.y == other.y
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// let mut point = Point { x: 1, y: 0 };
|
||||
/// point += Point { x: 2, y: 3 };
|
||||
/// assert_eq!(point, Point { x: 3, y: 3 });
|
||||
|
@ -697,7 +649,7 @@ neg_impl_numeric! { isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
#[rustc_on_unimplemented = "no implementation for `{Self} += {Rhs}`"]
|
||||
pub trait AddAssign<Rhs=Self> {
|
||||
/// The method for the `+=` operator
|
||||
/// Performs the `+=` operation.
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
fn add_assign(&mut self, rhs: Rhs);
|
||||
}
|
||||
|
@ -725,7 +677,7 @@ add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
/// ```
|
||||
/// use std::ops::SubAssign;
|
||||
///
|
||||
/// #[derive(Debug)]
|
||||
/// #[derive(Debug, PartialEq)]
|
||||
/// struct Point {
|
||||
/// x: i32,
|
||||
/// y: i32,
|
||||
|
@ -740,12 +692,6 @@ add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// impl PartialEq for Point {
|
||||
/// fn eq(&self, other: &Self) -> bool {
|
||||
/// self.x == other.x && self.y == other.y
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// let mut point = Point { x: 3, y: 3 };
|
||||
/// point -= Point { x: 2, y: 3 };
|
||||
/// assert_eq!(point, Point {x: 1, y: 0});
|
||||
|
@ -754,7 +700,7 @@ add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
#[rustc_on_unimplemented = "no implementation for `{Self} -= {Rhs}`"]
|
||||
pub trait SubAssign<Rhs=Self> {
|
||||
/// The method for the `-=` operator
|
||||
/// Performs the `-=` operation.
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
fn sub_assign(&mut self, rhs: Rhs);
|
||||
}
|
||||
|
@ -776,31 +722,27 @@ sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
///
|
||||
/// # 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;
|
||||
/// #[derive(Debug, PartialEq)]
|
||||
/// struct Frequency { hertz: f64 }
|
||||
///
|
||||
/// impl MulAssign for Foo {
|
||||
/// fn mul_assign(&mut self, _rhs: Foo) {
|
||||
/// println!("Multiplying!");
|
||||
/// impl MulAssign<f64> for Frequency {
|
||||
/// fn mul_assign(&mut self, rhs: f64) {
|
||||
/// self.hertz *= rhs;
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// # #[allow(unused_assignments)]
|
||||
/// fn main() {
|
||||
/// let mut foo = Foo;
|
||||
/// foo *= Foo;
|
||||
/// }
|
||||
/// let mut frequency = Frequency { hertz: 50.0 };
|
||||
/// frequency *= 4.0;
|
||||
/// assert_eq!(Frequency { hertz: 200.0 }, frequency);
|
||||
/// ```
|
||||
#[lang = "mul_assign"]
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
#[rustc_on_unimplemented = "no implementation for `{Self} *= {Rhs}`"]
|
||||
pub trait MulAssign<Rhs=Self> {
|
||||
/// The method for the `*=` operator
|
||||
/// Performs the `*=` operation.
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
fn mul_assign(&mut self, rhs: Rhs);
|
||||
}
|
||||
|
@ -822,31 +764,27 @@ mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
///
|
||||
/// # 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;
|
||||
/// #[derive(Debug, PartialEq)]
|
||||
/// struct Frequency { hertz: f64 }
|
||||
///
|
||||
/// impl DivAssign for Foo {
|
||||
/// fn div_assign(&mut self, _rhs: Foo) {
|
||||
/// println!("Dividing!");
|
||||
/// impl DivAssign<f64> for Frequency {
|
||||
/// fn div_assign(&mut self, rhs: f64) {
|
||||
/// self.hertz /= rhs;
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// # #[allow(unused_assignments)]
|
||||
/// fn main() {
|
||||
/// let mut foo = Foo;
|
||||
/// foo /= Foo;
|
||||
/// }
|
||||
/// let mut frequency = Frequency { hertz: 200.0 };
|
||||
/// frequency /= 4.0;
|
||||
/// assert_eq!(Frequency { hertz: 50.0 }, frequency);
|
||||
/// ```
|
||||
#[lang = "div_assign"]
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
#[rustc_on_unimplemented = "no implementation for `{Self} /= {Rhs}`"]
|
||||
pub trait DivAssign<Rhs=Self> {
|
||||
/// The method for the `/=` operator
|
||||
/// Performs the `/=` operation.
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
fn div_assign(&mut self, rhs: Rhs);
|
||||
}
|
||||
|
@ -867,31 +805,31 @@ div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
|||
///
|
||||
/// # 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;
|
||||
/// struct CookieJar { cookies: u32 }
|
||||
///
|
||||
/// impl RemAssign for Foo {
|
||||
/// fn rem_assign(&mut self, _rhs: Foo) {
|
||||
/// println!("Remainder-ing!");
|
||||
/// impl RemAssign<u32> for CookieJar {
|
||||
/// fn rem_assign(&mut self, piles: u32) {
|
||||
/// self.cookies %= piles;
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// # #[allow(unused_assignments)]
|
||||
/// fn main() {
|
||||
/// let mut foo = Foo;
|
||||
/// foo %= Foo;
|
||||
/// }
|
||||
/// let mut jar = CookieJar { cookies: 31 };
|
||||
/// let piles = 4;
|
||||
///
|
||||
/// println!("Splitting up {} cookies into {} even piles!", jar.cookies, piles);
|
||||
///
|
||||
/// jar %= piles;
|
||||
///
|
||||
/// println!("{} cookies remain in the cookie jar!", jar.cookies);
|
||||
/// ```
|
||||
#[lang = "rem_assign"]
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
#[rustc_on_unimplemented = "no implementation for `{Self} %= {Rhs}`"]
|
||||
pub trait RemAssign<Rhs=Self> {
|
||||
/// The method for the `%=` operator
|
||||
/// Performs the `%=` operation.
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
fn rem_assign(&mut self, rhs: Rhs);
|
||||
}
|
||||
|
|
|
@ -41,11 +41,11 @@
|
|||
#[lang = "not"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait Not {
|
||||
/// The resulting type after applying the `!` operator
|
||||
/// The resulting type after applying the `!` operator.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
type Output;
|
||||
|
||||
/// The method for the unary `!` operator
|
||||
/// Performs the unary `!` operation.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn not(self) -> Self::Output;
|
||||
}
|
||||
|
@ -68,9 +68,11 @@ not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
|
||||
/// The bitwise AND operator `&`.
|
||||
///
|
||||
/// Note that `RHS` is `Self` by default, but this is not mandatory.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// In this example, the `&` operator is lifted to a trivial `Scalar` type.
|
||||
/// An implementation of `BitAnd` for a wrapper around `bool`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::ops::BitAnd;
|
||||
|
@ -87,16 +89,13 @@ not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// assert_eq!(Scalar(true) & Scalar(true), Scalar(true));
|
||||
/// assert_eq!(Scalar(true) & Scalar(false), Scalar(false));
|
||||
/// assert_eq!(Scalar(false) & Scalar(true), Scalar(false));
|
||||
/// assert_eq!(Scalar(false) & Scalar(false), Scalar(false));
|
||||
/// }
|
||||
/// assert_eq!(Scalar(true) & Scalar(true), Scalar(true));
|
||||
/// assert_eq!(Scalar(true) & Scalar(false), Scalar(false));
|
||||
/// assert_eq!(Scalar(false) & Scalar(true), Scalar(false));
|
||||
/// assert_eq!(Scalar(false) & Scalar(false), Scalar(false));
|
||||
/// ```
|
||||
///
|
||||
/// In this example, the `BitAnd` trait is implemented for a `BooleanVector`
|
||||
/// struct.
|
||||
/// An implementation of `BitAnd` for a wrapper around `Vec<bool>`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::ops::BitAnd;
|
||||
|
@ -114,22 +113,20 @@ not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let bv1 = BooleanVector(vec![true, true, false, false]);
|
||||
/// let bv2 = BooleanVector(vec![true, false, true, false]);
|
||||
/// let expected = BooleanVector(vec![true, false, false, false]);
|
||||
/// assert_eq!(bv1 & bv2, expected);
|
||||
/// }
|
||||
/// let bv1 = BooleanVector(vec![true, true, false, false]);
|
||||
/// let bv2 = BooleanVector(vec![true, false, true, false]);
|
||||
/// let expected = BooleanVector(vec![true, false, false, false]);
|
||||
/// assert_eq!(bv1 & bv2, expected);
|
||||
/// ```
|
||||
#[lang = "bitand"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented = "no implementation for `{Self} & {RHS}`"]
|
||||
pub trait BitAnd<RHS=Self> {
|
||||
/// The resulting type after applying the `&` operator
|
||||
/// The resulting type after applying the `&` operator.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
type Output;
|
||||
|
||||
/// The method for the `&` operator
|
||||
/// Performs the `&` operation.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn bitand(self, rhs: RHS) -> Self::Output;
|
||||
}
|
||||
|
@ -152,9 +149,11 @@ bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
|
||||
/// The bitwise OR operator `|`.
|
||||
///
|
||||
/// Note that `RHS` is `Self` by default, but this is not mandatory.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// In this example, the `|` operator is lifted to a trivial `Scalar` type.
|
||||
/// An implementation of `BitOr` for a wrapper around `bool`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::ops::BitOr;
|
||||
|
@ -171,16 +170,13 @@ bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// assert_eq!(Scalar(true) | Scalar(true), Scalar(true));
|
||||
/// assert_eq!(Scalar(true) | Scalar(false), Scalar(true));
|
||||
/// assert_eq!(Scalar(false) | Scalar(true), Scalar(true));
|
||||
/// assert_eq!(Scalar(false) | Scalar(false), Scalar(false));
|
||||
/// }
|
||||
/// assert_eq!(Scalar(true) | Scalar(true), Scalar(true));
|
||||
/// assert_eq!(Scalar(true) | Scalar(false), Scalar(true));
|
||||
/// assert_eq!(Scalar(false) | Scalar(true), Scalar(true));
|
||||
/// assert_eq!(Scalar(false) | Scalar(false), Scalar(false));
|
||||
/// ```
|
||||
///
|
||||
/// In this example, the `BitOr` trait is implemented for a `BooleanVector`
|
||||
/// struct.
|
||||
/// An implementation of `BitOr` for a wrapper around `Vec<bool>`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::ops::BitOr;
|
||||
|
@ -198,22 +194,20 @@ bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let bv1 = BooleanVector(vec![true, true, false, false]);
|
||||
/// let bv2 = BooleanVector(vec![true, false, true, false]);
|
||||
/// let expected = BooleanVector(vec![true, true, true, false]);
|
||||
/// assert_eq!(bv1 | bv2, expected);
|
||||
/// }
|
||||
/// let bv1 = BooleanVector(vec![true, true, false, false]);
|
||||
/// let bv2 = BooleanVector(vec![true, false, true, false]);
|
||||
/// let expected = BooleanVector(vec![true, true, true, false]);
|
||||
/// assert_eq!(bv1 | bv2, expected);
|
||||
/// ```
|
||||
#[lang = "bitor"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented = "no implementation for `{Self} | {RHS}`"]
|
||||
pub trait BitOr<RHS=Self> {
|
||||
/// The resulting type after applying the `|` operator
|
||||
/// The resulting type after applying the `|` operator.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
type Output;
|
||||
|
||||
/// The method for the `|` operator
|
||||
/// Performs the `|` operation.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn bitor(self, rhs: RHS) -> Self::Output;
|
||||
}
|
||||
|
@ -236,9 +230,11 @@ bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
|
||||
/// The bitwise XOR operator `^`.
|
||||
///
|
||||
/// Note that `RHS` is `Self` by default, but this is not mandatory.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// In this example, the `^` operator is lifted to a trivial `Scalar` type.
|
||||
/// An implementation of `BitXor` that lifts `^` to a wrapper around `bool`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::ops::BitXor;
|
||||
|
@ -255,16 +251,13 @@ bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// assert_eq!(Scalar(true) ^ Scalar(true), Scalar(false));
|
||||
/// assert_eq!(Scalar(true) ^ Scalar(false), Scalar(true));
|
||||
/// assert_eq!(Scalar(false) ^ Scalar(true), Scalar(true));
|
||||
/// assert_eq!(Scalar(false) ^ Scalar(false), Scalar(false));
|
||||
/// }
|
||||
/// assert_eq!(Scalar(true) ^ Scalar(true), Scalar(false));
|
||||
/// assert_eq!(Scalar(true) ^ Scalar(false), Scalar(true));
|
||||
/// assert_eq!(Scalar(false) ^ Scalar(true), Scalar(true));
|
||||
/// assert_eq!(Scalar(false) ^ Scalar(false), Scalar(false));
|
||||
/// ```
|
||||
///
|
||||
/// In this example, the `BitXor` trait is implemented for a `BooleanVector`
|
||||
/// struct.
|
||||
/// An implementation of `BitXor` trait for a wrapper around `Vec<bool>`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::ops::BitXor;
|
||||
|
@ -285,22 +278,20 @@ bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let bv1 = BooleanVector(vec![true, true, false, false]);
|
||||
/// let bv2 = BooleanVector(vec![true, false, true, false]);
|
||||
/// let expected = BooleanVector(vec![false, true, true, false]);
|
||||
/// assert_eq!(bv1 ^ bv2, expected);
|
||||
/// }
|
||||
/// let bv1 = BooleanVector(vec![true, true, false, false]);
|
||||
/// let bv2 = BooleanVector(vec![true, false, true, false]);
|
||||
/// let expected = BooleanVector(vec![false, true, true, false]);
|
||||
/// assert_eq!(bv1 ^ bv2, expected);
|
||||
/// ```
|
||||
#[lang = "bitxor"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented = "no implementation for `{Self} ^ {RHS}`"]
|
||||
pub trait BitXor<RHS=Self> {
|
||||
/// The resulting type after applying the `^` operator
|
||||
/// The resulting type after applying the `^` operator.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
type Output;
|
||||
|
||||
/// The method for the `^` operator
|
||||
/// Performs the `^` operation.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn bitxor(self, rhs: RHS) -> Self::Output;
|
||||
}
|
||||
|
@ -326,7 +317,7 @@ bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
/// # Examples
|
||||
///
|
||||
/// An implementation of `Shl` that lifts the `<<` operation on integers to a
|
||||
/// `Scalar` struct.
|
||||
/// wrapper around `usize`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::ops::Shl;
|
||||
|
@ -342,9 +333,8 @@ bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
/// Scalar(lhs << rhs)
|
||||
/// }
|
||||
/// }
|
||||
/// fn main() {
|
||||
/// assert_eq!(Scalar(4) << Scalar(2), Scalar(16));
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(Scalar(4) << Scalar(2), Scalar(16));
|
||||
/// ```
|
||||
///
|
||||
/// An implementation of `Shl` that spins a vector leftward by a given amount.
|
||||
|
@ -361,7 +351,7 @@ bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
/// type Output = Self;
|
||||
///
|
||||
/// fn shl(self, rhs: usize) -> SpinVector<T> {
|
||||
/// // rotate the vector by `rhs` places
|
||||
/// // Rotate the vector by `rhs` places.
|
||||
/// let (a, b) = self.vec.split_at(rhs);
|
||||
/// let mut spun_vector: Vec<T> = vec![];
|
||||
/// spun_vector.extend_from_slice(b);
|
||||
|
@ -370,20 +360,18 @@ bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// assert_eq!(SpinVector { vec: vec![0, 1, 2, 3, 4] } << 2,
|
||||
/// SpinVector { vec: vec![2, 3, 4, 0, 1] });
|
||||
/// }
|
||||
/// assert_eq!(SpinVector { vec: vec![0, 1, 2, 3, 4] } << 2,
|
||||
/// SpinVector { vec: vec![2, 3, 4, 0, 1] });
|
||||
/// ```
|
||||
#[lang = "shl"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented = "no implementation for `{Self} << {RHS}`"]
|
||||
pub trait Shl<RHS> {
|
||||
/// The resulting type after applying the `<<` operator
|
||||
/// The resulting type after applying the `<<` operator.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
type Output;
|
||||
|
||||
/// The method for the `<<` operator
|
||||
/// Performs the `<<` operation.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn shl(self, rhs: RHS) -> Self::Output;
|
||||
}
|
||||
|
@ -430,7 +418,7 @@ shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 }
|
|||
/// # Examples
|
||||
///
|
||||
/// An implementation of `Shr` that lifts the `>>` operation on integers to a
|
||||
/// `Scalar` struct.
|
||||
/// wrapper around `usize`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::ops::Shr;
|
||||
|
@ -446,9 +434,8 @@ shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 }
|
|||
/// Scalar(lhs >> rhs)
|
||||
/// }
|
||||
/// }
|
||||
/// fn main() {
|
||||
/// assert_eq!(Scalar(16) >> Scalar(2), Scalar(4));
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(Scalar(16) >> Scalar(2), Scalar(4));
|
||||
/// ```
|
||||
///
|
||||
/// An implementation of `Shr` that spins a vector rightward by a given amount.
|
||||
|
@ -465,7 +452,7 @@ shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 }
|
|||
/// type Output = Self;
|
||||
///
|
||||
/// fn shr(self, rhs: usize) -> SpinVector<T> {
|
||||
/// // rotate the vector by `rhs` places
|
||||
/// // Rotate the vector by `rhs` places.
|
||||
/// let (a, b) = self.vec.split_at(self.vec.len() - rhs);
|
||||
/// let mut spun_vector: Vec<T> = vec![];
|
||||
/// spun_vector.extend_from_slice(b);
|
||||
|
@ -474,20 +461,18 @@ shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 }
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// assert_eq!(SpinVector { vec: vec![0, 1, 2, 3, 4] } >> 2,
|
||||
/// SpinVector { vec: vec![3, 4, 0, 1, 2] });
|
||||
/// }
|
||||
/// assert_eq!(SpinVector { vec: vec![0, 1, 2, 3, 4] } >> 2,
|
||||
/// SpinVector { vec: vec![3, 4, 0, 1, 2] });
|
||||
/// ```
|
||||
#[lang = "shr"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented = "no implementation for `{Self} >> {RHS}`"]
|
||||
pub trait Shr<RHS> {
|
||||
/// The resulting type after applying the `>>` operator
|
||||
/// The resulting type after applying the `>>` operator.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
type Output;
|
||||
|
||||
/// The method for the `>>` operator
|
||||
/// Performs the `>>` operation.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn shr(self, rhs: RHS) -> Self::Output;
|
||||
}
|
||||
|
@ -533,7 +518,8 @@ shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// In this example, the `&=` operator is lifted to a trivial `Scalar` type.
|
||||
/// An implementation of `BitAndAssign` that lifts the `&=` operator to a
|
||||
/// wrapper around `bool`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::ops::BitAndAssign;
|
||||
|
@ -548,27 +534,25 @@ shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let mut scalar = Scalar(true);
|
||||
/// scalar &= Scalar(true);
|
||||
/// assert_eq!(scalar, Scalar(true));
|
||||
/// let mut scalar = Scalar(true);
|
||||
/// scalar &= Scalar(true);
|
||||
/// assert_eq!(scalar, Scalar(true));
|
||||
///
|
||||
/// let mut scalar = Scalar(true);
|
||||
/// scalar &= Scalar(false);
|
||||
/// assert_eq!(scalar, Scalar(false));
|
||||
/// let mut scalar = Scalar(true);
|
||||
/// scalar &= Scalar(false);
|
||||
/// assert_eq!(scalar, Scalar(false));
|
||||
///
|
||||
/// let mut scalar = Scalar(false);
|
||||
/// scalar &= Scalar(true);
|
||||
/// assert_eq!(scalar, Scalar(false));
|
||||
/// let mut scalar = Scalar(false);
|
||||
/// scalar &= Scalar(true);
|
||||
/// assert_eq!(scalar, Scalar(false));
|
||||
///
|
||||
/// let mut scalar = Scalar(false);
|
||||
/// scalar &= Scalar(false);
|
||||
/// assert_eq!(scalar, Scalar(false));
|
||||
/// }
|
||||
/// let mut scalar = Scalar(false);
|
||||
/// scalar &= Scalar(false);
|
||||
/// assert_eq!(scalar, Scalar(false));
|
||||
/// ```
|
||||
///
|
||||
/// In this example, the `BitAndAssign` trait is implemented for a
|
||||
/// `BooleanVector` struct.
|
||||
/// Here, the `BitAndAssign` trait is implemented for a wrapper around
|
||||
/// `Vec<bool>`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::ops::BitAndAssign;
|
||||
|
@ -577,7 +561,7 @@ shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
|
|||
/// struct BooleanVector(Vec<bool>);
|
||||
///
|
||||
/// impl BitAndAssign for BooleanVector {
|
||||
/// // rhs is the "right-hand side" of the expression `a &= b`
|
||||
/// // `rhs` is the "right-hand side" of the expression `a &= b`.
|
||||
/// fn bitand_assign(&mut self, rhs: Self) {
|
||||
/// assert_eq!(self.0.len(), rhs.0.len());
|
||||
/// *self = BooleanVector(self.0
|
||||
|
@ -588,18 +572,16 @@ shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let mut bv = BooleanVector(vec![true, true, false, false]);
|
||||
/// bv &= BooleanVector(vec![true, false, true, false]);
|
||||
/// let expected = BooleanVector(vec![true, false, false, false]);
|
||||
/// assert_eq!(bv, expected);
|
||||
/// }
|
||||
/// let mut bv = BooleanVector(vec![true, true, false, false]);
|
||||
/// bv &= BooleanVector(vec![true, false, true, false]);
|
||||
/// let expected = BooleanVector(vec![true, false, false, false]);
|
||||
/// assert_eq!(bv, expected);
|
||||
/// ```
|
||||
#[lang = "bitand_assign"]
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
#[rustc_on_unimplemented = "no implementation for `{Self} &= {Rhs}`"]
|
||||
pub trait BitAndAssign<Rhs=Self> {
|
||||
/// The method for the `&=` operator
|
||||
/// Performs the `&=` operation.
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
fn bitand_assign(&mut self, rhs: Rhs);
|
||||
}
|
||||
|
@ -620,31 +602,31 @@ bitand_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
///
|
||||
/// # 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;
|
||||
/// #[derive(Debug, PartialEq)]
|
||||
/// struct PersonalPreferences {
|
||||
/// likes_cats: bool,
|
||||
/// likes_dogs: bool,
|
||||
/// }
|
||||
///
|
||||
/// impl BitOrAssign for Foo {
|
||||
/// fn bitor_assign(&mut self, _rhs: Foo) {
|
||||
/// println!("Bitwise Or-ing!");
|
||||
/// impl BitOrAssign for PersonalPreferences {
|
||||
/// fn bitor_assign(&mut self, rhs: Self) {
|
||||
/// self.likes_cats |= rhs.likes_cats;
|
||||
/// self.likes_dogs |= rhs.likes_dogs;
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// # #[allow(unused_assignments)]
|
||||
/// fn main() {
|
||||
/// let mut foo = Foo;
|
||||
/// foo |= Foo;
|
||||
/// }
|
||||
/// let mut prefs = PersonalPreferences { likes_cats: true, likes_dogs: false };
|
||||
/// prefs |= PersonalPreferences { likes_cats: false, likes_dogs: true };
|
||||
/// assert_eq!(prefs, PersonalPreferences { likes_cats: true, likes_dogs: true });
|
||||
/// ```
|
||||
#[lang = "bitor_assign"]
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
#[rustc_on_unimplemented = "no implementation for `{Self} |= {Rhs}`"]
|
||||
pub trait BitOrAssign<Rhs=Self> {
|
||||
/// The method for the `|=` operator
|
||||
/// Performs the `|=` operation.
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
fn bitor_assign(&mut self, rhs: Rhs);
|
||||
}
|
||||
|
@ -665,31 +647,31 @@ bitor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
///
|
||||
/// # 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;
|
||||
/// #[derive(Debug, PartialEq)]
|
||||
/// struct Personality {
|
||||
/// has_soul: bool,
|
||||
/// likes_knitting: bool,
|
||||
/// }
|
||||
///
|
||||
/// impl BitXorAssign for Foo {
|
||||
/// fn bitxor_assign(&mut self, _rhs: Foo) {
|
||||
/// println!("Bitwise Xor-ing!");
|
||||
/// impl BitXorAssign for Personality {
|
||||
/// fn bitxor_assign(&mut self, rhs: Self) {
|
||||
/// self.has_soul ^= rhs.has_soul;
|
||||
/// self.likes_knitting ^= rhs.likes_knitting;
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// # #[allow(unused_assignments)]
|
||||
/// fn main() {
|
||||
/// let mut foo = Foo;
|
||||
/// foo ^= Foo;
|
||||
/// }
|
||||
/// let mut personality = Personality { has_soul: false, likes_knitting: true };
|
||||
/// personality ^= Personality { has_soul: true, likes_knitting: true };
|
||||
/// assert_eq!(personality, Personality { has_soul: true, likes_knitting: false});
|
||||
/// ```
|
||||
#[lang = "bitxor_assign"]
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
#[rustc_on_unimplemented = "no implementation for `{Self} ^= {Rhs}`"]
|
||||
pub trait BitXorAssign<Rhs=Self> {
|
||||
/// The method for the `^=` operator
|
||||
/// Performs the `^=` operation.
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
fn bitxor_assign(&mut self, rhs: Rhs);
|
||||
}
|
||||
|
@ -710,31 +692,29 @@ bitxor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// A trivial implementation of `ShlAssign`. When `Foo <<= Foo` happens, it ends up
|
||||
/// calling `shl_assign`, and therefore, `main` prints `Shifting left!`.
|
||||
/// An implementation of `ShlAssign` for a wrapper around `usize`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::ops::ShlAssign;
|
||||
///
|
||||
/// struct Foo;
|
||||
/// #[derive(Debug, PartialEq)]
|
||||
/// struct Scalar(usize);
|
||||
///
|
||||
/// impl ShlAssign<Foo> for Foo {
|
||||
/// fn shl_assign(&mut self, _rhs: Foo) {
|
||||
/// println!("Shifting left!");
|
||||
/// impl ShlAssign<usize> for Scalar {
|
||||
/// fn shl_assign(&mut self, rhs: usize) {
|
||||
/// self.0 <<= rhs;
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// # #[allow(unused_assignments)]
|
||||
/// fn main() {
|
||||
/// let mut foo = Foo;
|
||||
/// foo <<= Foo;
|
||||
/// }
|
||||
/// let mut scalar = Scalar(4);
|
||||
/// scalar <<= 2;
|
||||
/// assert_eq!(scalar, Scalar(16));
|
||||
/// ```
|
||||
#[lang = "shl_assign"]
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
#[rustc_on_unimplemented = "no implementation for `{Self} <<= {Rhs}`"]
|
||||
pub trait ShlAssign<Rhs> {
|
||||
/// The method for the `<<=` operator
|
||||
/// Performs the `<<=` operation.
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
fn shl_assign(&mut self, rhs: Rhs);
|
||||
}
|
||||
|
@ -776,31 +756,29 @@ shl_assign_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// A trivial implementation of `ShrAssign`. When `Foo >>= Foo` happens, it ends up
|
||||
/// calling `shr_assign`, and therefore, `main` prints `Shifting right!`.
|
||||
/// An implementation of `ShrAssign` for a wrapper around `usize`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::ops::ShrAssign;
|
||||
///
|
||||
/// struct Foo;
|
||||
/// #[derive(Debug, PartialEq)]
|
||||
/// struct Scalar(usize);
|
||||
///
|
||||
/// impl ShrAssign<Foo> for Foo {
|
||||
/// fn shr_assign(&mut self, _rhs: Foo) {
|
||||
/// println!("Shifting right!");
|
||||
/// impl ShrAssign<usize> for Scalar {
|
||||
/// fn shr_assign(&mut self, rhs: usize) {
|
||||
/// self.0 >>= rhs;
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// # #[allow(unused_assignments)]
|
||||
/// fn main() {
|
||||
/// let mut foo = Foo;
|
||||
/// foo >>= Foo;
|
||||
/// }
|
||||
/// let mut scalar = Scalar(16);
|
||||
/// scalar >>= 2;
|
||||
/// assert_eq!(scalar, Scalar(4));
|
||||
/// ```
|
||||
#[lang = "shr_assign"]
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
#[rustc_on_unimplemented = "no implementation for `{Self} >>= {Rhs}`"]
|
||||
pub trait ShrAssign<Rhs=Self> {
|
||||
/// The method for the `>>=` operator
|
||||
/// Performs the `>>=` operation.
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
fn shr_assign(&mut self, rhs: Rhs);
|
||||
}
|
||||
|
|
|
@ -8,16 +8,44 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/// The `Deref` trait is used to specify the functionality of dereferencing
|
||||
/// operations, like `*v`.
|
||||
/// Used for immutable dereferencing operations, like `*v`.
|
||||
///
|
||||
/// `Deref` also enables ['`Deref` coercions'][coercions].
|
||||
/// In addition to being used for explicit dereferencing operations with the
|
||||
/// (unary) `*` operator in immutable contexts, `Deref` is also used implicitly
|
||||
/// by the compiler in many circumstances. This mechanism is called
|
||||
/// ['`Deref` coercion'][more]. In mutable contexts, [`DerefMut`] is used.
|
||||
///
|
||||
/// [coercions]: ../../book/first-edition/deref-coercions.html
|
||||
/// Implementing `Deref` for smart pointers makes accessing the data behind them
|
||||
/// convenient, which is why they implement `Deref`. On the other hand, the
|
||||
/// rules regarding `Deref` and [`DerefMut`] were designed specifically to
|
||||
/// accomodate smart pointers. Because of this, **`Deref` should only be
|
||||
/// implemented for smart pointers** to avoid confusion.
|
||||
///
|
||||
/// For similar reasons, **this trait should never fail**. Failure during
|
||||
/// dereferencing can be extremely confusing when `Deref` is invoked implicitly.
|
||||
///
|
||||
/// # More on `Deref` coercion
|
||||
///
|
||||
/// If `T` implements `Deref<Target = U>`, and `x` is a value of type `T`, then:
|
||||
/// * In immutable contexts, `*x` on non-pointer types is equivalent to
|
||||
/// `*Deref::deref(&x)`.
|
||||
/// * Values of type `&T` are coerced to values of type `&U`
|
||||
/// * `T` implicitly implements all the (immutable) methods of the type `U`.
|
||||
///
|
||||
/// For more details, visit [the chapter in *The Rust Programming Language*]
|
||||
/// [book] as well as the reference sections on [the dereference operator]
|
||||
/// [ref-deref-op], [the `Deref` trait][ref-deref-trait], and [type coercions].
|
||||
///
|
||||
/// [book]: ../../book/second-edition/ch15-02-deref.html
|
||||
/// [`DerefMut`]: trait.DerefMut.html
|
||||
/// [more]: #more-on-deref-coercion
|
||||
/// [ref-deref-op]: ../../reference/expressions.html#the-dereference-operator
|
||||
/// [ref-deref-trait]: ../../reference/the-deref-trait.html
|
||||
/// [type coercions]: ../../reference/type-coercions.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// A struct with a single field which is accessible via dereferencing the
|
||||
/// A struct with a single field which is accessible by dereferencing the
|
||||
/// struct.
|
||||
///
|
||||
/// ```
|
||||
|
@ -35,19 +63,17 @@
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let x = DerefExample { value: 'a' };
|
||||
/// assert_eq!('a', *x);
|
||||
/// }
|
||||
/// 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
|
||||
/// The resulting type after dereferencing.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
type Target: ?Sized;
|
||||
|
||||
/// The method called to dereference a value
|
||||
/// Dereferences the value.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn deref(&self) -> &Self::Target;
|
||||
}
|
||||
|
@ -66,16 +92,46 @@ impl<'a, T: ?Sized> Deref for &'a mut T {
|
|||
fn deref(&self) -> &T { *self }
|
||||
}
|
||||
|
||||
/// The `DerefMut` trait is used to specify the functionality of dereferencing
|
||||
/// mutably like `*v = 1;`
|
||||
/// Used for mutable dereferencing operations, like in `*v = 1;`.
|
||||
///
|
||||
/// `DerefMut` also enables ['`Deref` coercions'][coercions].
|
||||
/// In addition to being used for explicit dereferencing operations with the
|
||||
/// (unary) `*` operator in mutable contexts, `DerefMut` is also used implicitly
|
||||
/// by the compiler in many circumstances. This mechanism is called
|
||||
/// ['`Deref` coercion'][more]. In immutable contexts, [`Deref`] is used.
|
||||
///
|
||||
/// [coercions]: ../../book/first-edition/deref-coercions.html
|
||||
/// Implementing `DerefMut` for smart pointers makes mutating the data behind
|
||||
/// them convenient, which is why they implement `DerefMut`. On the other hand,
|
||||
/// the rules regarding [`Deref`] and `DerefMut` were designed specifically to
|
||||
/// accomodate smart pointers. Because of this, **`DerefMut` should only be
|
||||
/// implemented for smart pointers** to avoid confusion.
|
||||
///
|
||||
/// For similar reasons, **this trait should never fail**. Failure during
|
||||
/// dereferencing can be extremely confusing when `DerefMut` is invoked
|
||||
/// implicitly.
|
||||
///
|
||||
/// # More on `Deref` coercion
|
||||
///
|
||||
/// If `T` implements `DerefMut<Target = U>`, and `x` is a value of type `T`,
|
||||
/// then:
|
||||
/// * In mutable contexts, `*x` on non-pointer types is equivalent to
|
||||
/// `*Deref::deref(&x)`.
|
||||
/// * Values of type `&mut T` are coerced to values of type `&mut U`
|
||||
/// * `T` implicitly implements all the (mutable) methods of the type `U`.
|
||||
///
|
||||
/// For more details, visit [the chapter in *The Rust Programming Language*]
|
||||
/// [book] as well as the reference sections on [the dereference operator]
|
||||
/// [ref-deref-op], [the `Deref` trait][ref-deref-trait], and [type coercions].
|
||||
///
|
||||
/// [book]: ../../book/second-edition/ch15-02-deref.html
|
||||
/// [`Deref`]: trait.Deref.html
|
||||
/// [more]: #more-on-deref-coercion
|
||||
/// [ref-deref-op]: ../../reference/expressions.html#the-dereference-operator
|
||||
/// [ref-deref-trait]: ../../reference/the-deref-trait.html
|
||||
/// [type coercions]: ../../reference/type-coercions.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// A struct with a single field which is modifiable via dereferencing the
|
||||
/// A struct with a single field which is modifiable by dereferencing the
|
||||
/// struct.
|
||||
///
|
||||
/// ```
|
||||
|
@ -99,16 +155,14 @@ impl<'a, T: ?Sized> Deref for &'a mut T {
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let mut x = DerefMutExample { value: 'a' };
|
||||
/// *x = 'b';
|
||||
/// assert_eq!('b', *x);
|
||||
/// }
|
||||
/// 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
|
||||
/// Mutably dereferences the value.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn deref_mut(&mut self) -> &mut Self::Target;
|
||||
}
|
||||
|
|
|
@ -8,20 +8,27 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/// The `Drop` trait is used to run some code when a value goes out of scope.
|
||||
/// Used to run some code when a value goes out of scope.
|
||||
/// This is sometimes called a 'destructor'.
|
||||
///
|
||||
/// When a value goes out of scope, if it implements this trait, it will have
|
||||
/// its `drop` method called. Then any fields the value contains will also
|
||||
/// When a value goes out of scope, it will have its `drop` method called if
|
||||
/// its type implements `Drop`. Then, any fields the value contains will also
|
||||
/// be dropped recursively.
|
||||
///
|
||||
/// Because of the recursive dropping, you do not need to implement this trait
|
||||
/// Because of this recursive dropping, you do not need to implement this trait
|
||||
/// unless your type needs its own destructor logic.
|
||||
///
|
||||
/// Refer to [the chapter on `Drop` in *The Rust Programming Language*][book]
|
||||
/// for some more elaboration.
|
||||
///
|
||||
/// [book]: ../../book/second-edition/ch15-03-drop.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// A trivial implementation of `Drop`. The `drop` method is called when `_x`
|
||||
/// goes out of scope, and therefore `main` prints `Dropping!`.
|
||||
/// ## Implementing `Drop`
|
||||
///
|
||||
/// The `drop` method is called when `_x` goes out of scope, and therefore
|
||||
/// `main` prints `Dropping!`.
|
||||
///
|
||||
/// ```
|
||||
/// struct HasDrop;
|
||||
|
@ -37,9 +44,11 @@
|
|||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Showing the recursive nature of `Drop`. When `outer` goes out of scope, the
|
||||
/// `drop` method will be called first for `Outer`, then for `Inner`. Therefore
|
||||
/// `main` prints `Dropping Outer!` and then `Dropping Inner!`.
|
||||
/// ## Dropping is done recursively
|
||||
///
|
||||
/// When `outer` goes out of scope, the `drop` method will be called first for
|
||||
/// `Outer`, then for `Inner`. Therefore, `main` prints `Dropping Outer!` and
|
||||
/// then `Dropping Inner!`.
|
||||
///
|
||||
/// ```
|
||||
/// struct Inner;
|
||||
|
@ -62,12 +71,20 @@
|
|||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Because variables are dropped in the reverse order they are declared,
|
||||
/// `main` will print `Declared second!` and then `Declared first!`.
|
||||
/// ## Variables are dropped in reverse order of declaration
|
||||
///
|
||||
/// `_first` is declared first and `_second` is declared second, so `main` will
|
||||
/// print `Declared second!` and then `Declared first!`.
|
||||
///
|
||||
/// ```
|
||||
/// struct PrintOnDrop(&'static str);
|
||||
///
|
||||
/// impl Drop for PrintOnDrop {
|
||||
/// fn drop(&mut self) {
|
||||
/// println!("{}", self.0);
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let _first = PrintOnDrop("Declared first!");
|
||||
/// let _second = PrintOnDrop("Declared second!");
|
||||
|
@ -76,24 +93,25 @@
|
|||
#[lang = "drop"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait Drop {
|
||||
/// A method called when the value goes out of scope.
|
||||
/// Executes the destructor for this type.
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
/// This function cannot be called explicitly. This is compiler error
|
||||
/// [E0040]. However, the [`std::mem::drop`] function in the prelude can be
|
||||
/// This method is called implilcitly when the value goes out of scope,
|
||||
/// and cannot be called explicitly (this is compiler error [E0040]).
|
||||
/// However, the [`std::mem::drop`] function in the prelude can be
|
||||
/// used to call the argument's `Drop` implementation.
|
||||
///
|
||||
/// [E0040]: ../../error-index.html#E0040
|
||||
/// [`std::mem::drop`]: ../../std/mem/fn.drop.html
|
||||
/// When this method has been called, `self` has not yet been deallocated.
|
||||
/// That only happens after the method is over.
|
||||
/// If this wasn't the case, `self` would be a dangling reference.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Given that a `panic!` will call `drop()` as it unwinds, any `panic!` in
|
||||
/// a `drop()` implementation will likely abort.
|
||||
/// Given that a [`panic!`] will call `drop` as it unwinds, any [`panic!`]
|
||||
/// in a `drop` implementation will likely abort.
|
||||
///
|
||||
/// [E0040]: ../../error-index.html#E0040
|
||||
/// [`panic!`]: ../macro.panic.html
|
||||
/// [`std::mem::drop`]: ../../std/mem/fn.drop.html
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn drop(&mut self);
|
||||
}
|
||||
|
|
|
@ -8,26 +8,51 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/// A version of the call operator that takes an immutable receiver.
|
||||
/// The version of the call operator that takes an immutable receiver.
|
||||
///
|
||||
/// Instances of `Fn` can be called repeatedly without mutating state.
|
||||
///
|
||||
/// *This trait (`Fn`) is not to be confused with [function pointers][]
|
||||
/// (`fn`).*
|
||||
///
|
||||
/// `Fn` is implemented automatically by closures which only take immutable
|
||||
/// references to captured variables or don't capture anything at all, as well
|
||||
/// as (safe) [function pointers][] (with some caveats, see their documentation
|
||||
/// for more details). Additionally, for any type `F` that implements `Fn`, `&F`
|
||||
/// implements `Fn`, too.
|
||||
///
|
||||
/// Since both [`FnMut`] and [`FnOnce`] are supertraits of `Fn`, any
|
||||
/// instance of `Fn` can be used as a parameter where a [`FnMut`] or [`FnOnce`]
|
||||
/// is expected.
|
||||
///
|
||||
/// Use `Fn` as a bound when you want to accept a parameter of function-like
|
||||
/// type and need to call it repeatedly and without mutating state (e.g. when
|
||||
/// calling it concurrently). If you do not need such strict requirements, use
|
||||
/// [`FnMut`] or [`FnOnce`] as bounds.
|
||||
///
|
||||
/// See the [chapter on closures in *The Rust Programming Language*][book] for
|
||||
/// some more information on this topic.
|
||||
///
|
||||
/// Also of note is the special syntax for `Fn` traits (e.g.
|
||||
/// `Fn(usize, bool) -> usize`). Those interested in the technical details of
|
||||
/// this can refer to [the relevant section in the *Rustonomicon*][nomicon].
|
||||
///
|
||||
/// [book]: ../../book/second-edition/ch13-01-closures.html
|
||||
/// [`FnMut`]: trait.FnMut.html
|
||||
/// [`FnOnce`]: trait.FnOnce.html
|
||||
/// [function pointers]: ../../std/primitive.fn.html
|
||||
/// [nomicon]: ../../nomicon/hrtb.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Closures automatically implement this trait, which allows them to be
|
||||
/// invoked. Note, however, that `Fn` takes an immutable reference to any
|
||||
/// captured variables. To take a mutable capture, implement [`FnMut`], and to
|
||||
/// consume the capture, implement [`FnOnce`].
|
||||
///
|
||||
/// [`FnMut`]: trait.FnMut.html
|
||||
/// [`FnOnce`]: trait.FnOnce.html
|
||||
/// ## Calling a closure
|
||||
///
|
||||
/// ```
|
||||
/// let square = |x| x * x;
|
||||
/// assert_eq!(square(5), 25);
|
||||
/// ```
|
||||
///
|
||||
/// Closures can also be passed to higher-level functions through a `Fn`
|
||||
/// parameter (or a `FnMut` or `FnOnce` parameter, which are supertraits of
|
||||
/// `Fn`).
|
||||
/// ## Using a `Fn` parameter
|
||||
///
|
||||
/// ```
|
||||
/// fn call_with_one<F>(func: F) -> usize
|
||||
|
@ -43,17 +68,46 @@
|
|||
#[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.
|
||||
/// Performs the call operation.
|
||||
#[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.
|
||||
/// The version of the call operator that takes a mutable receiver.
|
||||
///
|
||||
/// Instances of `FnMut` can be called repeatedly and may mutate state.
|
||||
///
|
||||
/// `FnMut` is implemented automatically by closures which take mutable
|
||||
/// references to captured variables, as well as all types that implement
|
||||
/// [`Fn`], e.g. (safe) [function pointers][] (since `FnMut` is a supertrait of
|
||||
/// [`Fn`]). Additionally, for any type `F` that implements `FnMut`, `&mut F`
|
||||
/// implements `FnMut`, too.
|
||||
///
|
||||
/// Since [`FnOnce`] is a supertrait of `FnMut`, any instance of `FnMut` can be
|
||||
/// used where a [`FnOnce`] is expected, and since [`Fn`] is a subtrait of
|
||||
/// `FnMut`, any instance of [`Fn`] can be used where `FnMut` is expected.
|
||||
///
|
||||
/// Use `FnMut` as a bound when you want to accept a parameter of function-like
|
||||
/// type and need to call it repeatedly, while allowing it to mutate state.
|
||||
/// If you don't want the parameter to mutate state, use [`Fn`] as a
|
||||
/// bound; if you don't need to call it repeatedly, use [`FnOnce`].
|
||||
///
|
||||
/// See the [chapter on closures in *The Rust Programming Language*][book] for
|
||||
/// some more information on this topic.
|
||||
///
|
||||
/// Also of note is the special syntax for `Fn` traits (e.g.
|
||||
/// `Fn(usize, bool) -> usize`). Those interested in the technical details of
|
||||
/// this can refer to [the relevant section in the *Rustonomicon*][nomicon].
|
||||
///
|
||||
/// [book]: ../../book/second-edition/ch13-01-closures.html
|
||||
/// [`Fn`]: trait.Fn.html
|
||||
/// [`FnOnce`]: trait.FnOnce.html
|
||||
/// [function pointers]: ../../std/primitive.fn.html
|
||||
/// [nomicon]: ../../nomicon/hrtb.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Closures that mutably capture variables automatically implement this trait,
|
||||
/// which allows them to be invoked.
|
||||
/// ## Calling a mutably capturing closure
|
||||
///
|
||||
/// ```
|
||||
/// let mut x = 5;
|
||||
|
@ -64,8 +118,7 @@ pub trait Fn<Args> : FnMut<Args> {
|
|||
/// assert_eq!(x, 25);
|
||||
/// ```
|
||||
///
|
||||
/// Closures can also be passed to higher-level functions through a `FnMut`
|
||||
/// parameter (or a `FnOnce` parameter, which is a supertrait of `FnMut`).
|
||||
/// ## Using a `FnMut` parameter
|
||||
///
|
||||
/// ```
|
||||
/// fn do_twice<F>(mut func: F)
|
||||
|
@ -88,17 +141,45 @@ pub trait Fn<Args> : FnMut<Args> {
|
|||
#[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.
|
||||
/// Performs the call operation.
|
||||
#[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.
|
||||
/// The version of the call operator that takes a by-value receiver.
|
||||
///
|
||||
/// Instances of `FnOnce` can be called, but might not be callable multiple
|
||||
/// times. Because of this, if the only thing known about a type is that it
|
||||
/// implements `FnOnce`, it can only be called once.
|
||||
///
|
||||
/// `FnOnce` is implemented automatically by closure that might consume captured
|
||||
/// variables, as well as all types that implement [`FnMut`], e.g. (safe)
|
||||
/// [function pointers][] (since `FnOnce` is a supertrait of [`FnMut`]).
|
||||
///
|
||||
/// Since both [`Fn`] and [`FnMut`] are subtraits of `FnOnce`, any instance of
|
||||
/// [`Fn`] or [`FnMut`] can be used where a `FnOnce` is expected.
|
||||
///
|
||||
/// Use `FnOnce` as a bound when you want to accept a parameter of function-like
|
||||
/// type and only need to call it once. If you need to call the parameter
|
||||
/// repeatedly, use [`FnMut`] as a bound; if you also need it to not mutate
|
||||
/// state, use [`Fn`].
|
||||
///
|
||||
/// See the [chapter on closures in *The Rust Programming Language*][book] for
|
||||
/// some more information on this topic.
|
||||
///
|
||||
/// Also of note is the special syntax for `Fn` traits (e.g.
|
||||
/// `Fn(usize, bool) -> usize`). Those interested in the technical details of
|
||||
/// this can refer to [the relevant section in the *Rustonomicon*][nomicon].
|
||||
///
|
||||
/// [book]: ../../book/second-edition/ch13-01-closures.html
|
||||
/// [`Fn`]: trait.Fn.html
|
||||
/// [`FnMut`]: trait.FnMut.html
|
||||
/// [function pointers]: ../../std/primitive.fn.html
|
||||
/// [nomicon]: ../../nomicon/hrtb.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// By-value closures automatically implement this trait, which allows them to
|
||||
/// be invoked.
|
||||
/// ## Calling a by-value closure
|
||||
///
|
||||
/// ```
|
||||
/// let x = 5;
|
||||
|
@ -106,21 +187,20 @@ pub trait FnMut<Args> : FnOnce<Args> {
|
|||
/// assert_eq!(square_x(), 25);
|
||||
/// ```
|
||||
///
|
||||
/// By-value Closures can also be passed to higher-level functions through a
|
||||
/// `FnOnce` parameter.
|
||||
/// ## Using a `FnOnce` parameter
|
||||
///
|
||||
/// ```
|
||||
/// fn consume_with_relish<F>(func: F)
|
||||
/// where F: FnOnce() -> String
|
||||
/// {
|
||||
/// // `func` consumes its captured variables, so it cannot be run more
|
||||
/// // than once
|
||||
/// // than once.
|
||||
/// println!("Consumed: {}", func());
|
||||
///
|
||||
/// println!("Delicious!");
|
||||
///
|
||||
/// // Attempting to invoke `func()` again will throw a `use of moved
|
||||
/// // value` error for `func`
|
||||
/// // value` error for `func`.
|
||||
/// }
|
||||
///
|
||||
/// let x = String::from("x");
|
||||
|
@ -138,7 +218,7 @@ pub trait FnOnce<Args> {
|
|||
#[stable(feature = "fn_once_output", since = "1.12.0")]
|
||||
type Output;
|
||||
|
||||
/// This is called when the call operator is used.
|
||||
/// Performs the call operation.
|
||||
#[unstable(feature = "fn_traits", issue = "29625")]
|
||||
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
|
||||
}
|
||||
|
|
|
@ -8,13 +8,12 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/// The `Index` trait is used to specify the functionality of indexing operations
|
||||
/// like `container[index]` when used in an immutable context.
|
||||
/// Used for indexing operations (`container[index]`) in immutable contexts.
|
||||
///
|
||||
/// `container[index]` is actually syntactic sugar for `*container.index(index)`,
|
||||
/// but only when used as an immutable value. If a mutable value is requested,
|
||||
/// [`IndexMut`] is used instead. This allows nice things such as
|
||||
/// `let value = v[index]` if `value` implements [`Copy`].
|
||||
/// `let value = v[index]` if the type of `value` implements [`Copy`].
|
||||
///
|
||||
/// [`IndexMut`]: ../../std/ops/trait.IndexMut.html
|
||||
/// [`Copy`]: ../../std/marker/trait.Copy.html
|
||||
|
@ -64,25 +63,23 @@
|
|||
#[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
|
||||
/// The returned type after indexing.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
type Output: ?Sized;
|
||||
|
||||
/// The method for the indexing (`container[index]`) operation
|
||||
/// Performs the indexing (`container[index]`) 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 `container[index]` when used in a mutable context.
|
||||
/// Used for indexing operations (`container[index]`) in mutable contexts.
|
||||
///
|
||||
/// `container[index]` is actually syntactic sugar for
|
||||
/// `*container.index_mut(index)`, but only when used as a mutable value. If
|
||||
/// an immutable value is requested, the [`Index`] trait is used instead. This
|
||||
/// allows nice things such as `v[index] = value` if `value` implements [`Copy`].
|
||||
/// allows nice things such as `v[index] = value`.
|
||||
///
|
||||
/// [`Index`]: ../../std/ops/trait.Index.html
|
||||
/// [`Copy`]: ../../std/marker/trait.Copy.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -106,7 +103,7 @@ pub trait Index<Idx: ?Sized> {
|
|||
///
|
||||
/// struct Balance {
|
||||
/// pub left: Weight,
|
||||
/// pub right:Weight,
|
||||
/// pub right: Weight,
|
||||
/// }
|
||||
///
|
||||
/// impl Index<Side> for Balance {
|
||||
|
@ -131,28 +128,26 @@ pub trait Index<Idx: ?Sized> {
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let mut balance = Balance {
|
||||
/// right: Weight::Kilogram(2.5),
|
||||
/// left: Weight::Pound(1.5),
|
||||
/// };
|
||||
/// let mut balance = Balance {
|
||||
/// right: Weight::Kilogram(2.5),
|
||||
/// left: Weight::Pound(1.5),
|
||||
/// };
|
||||
///
|
||||
/// // In this case balance[Side::Right] is sugar for
|
||||
/// // *balance.index(Side::Right), since we are only reading
|
||||
/// // balance[Side::Right], not writing it.
|
||||
/// assert_eq!(balance[Side::Right],Weight::Kilogram(2.5));
|
||||
/// // In this case, `balance[Side::Right]` is sugar for
|
||||
/// // `*balance.index(Side::Right)`, since we are only *reading*
|
||||
/// // `balance[Side::Right]`, not writing it.
|
||||
/// assert_eq!(balance[Side::Right], Weight::Kilogram(2.5));
|
||||
///
|
||||
/// // However in this case balance[Side::Left] is sugar for
|
||||
/// // *balance.index_mut(Side::Left), since we are writing
|
||||
/// // balance[Side::Left].
|
||||
/// balance[Side::Left] = Weight::Kilogram(3.0);
|
||||
/// }
|
||||
/// // However, in this case `balance[Side::Left]` is sugar for
|
||||
/// // `*balance.index_mut(Side::Left)`, since we are writing
|
||||
/// // `balance[Side::Left]`.
|
||||
/// balance[Side::Left] = Weight::Kilogram(3.0);
|
||||
/// ```
|
||||
#[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 mutable indexing (`container[index]`) operation
|
||||
/// Performs the mutable indexing (`container[index]`) operation.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,12 @@
|
|||
//! custom operators are required, you should look toward macros or compiler
|
||||
//! plugins to extend Rust's syntax.
|
||||
//!
|
||||
//! Implementations of operator traits should be unsurprising in their
|
||||
//! respective contexts, keeping in mind their usual meanings and
|
||||
//! [operator precedence]. For example, when implementing [`Mul`], the operation
|
||||
//! should have some resemblance to multiplication (and share expected
|
||||
//! properties like associativity).
|
||||
//!
|
||||
//! Note that the `&&` and `||` operators short-circuit, i.e. they only
|
||||
//! evaluate their second operand if it contributes to the result. Since this
|
||||
//! behavior is not enforceable by traits, `&&` and `||` are not supported as
|
||||
|
@ -46,7 +52,7 @@
|
|||
//! ```rust
|
||||
//! use std::ops::{Add, Sub};
|
||||
//!
|
||||
//! #[derive(Debug)]
|
||||
//! #[derive(Debug, PartialEq)]
|
||||
//! struct Point {
|
||||
//! x: i32,
|
||||
//! y: i32,
|
||||
|
@ -67,10 +73,9 @@
|
|||
//! 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});
|
||||
//! }
|
||||
//!
|
||||
//! assert_eq!(Point {x: 3, y: 3}, Point {x: 1, y: 0} + Point {x: 2, y: 3});
|
||||
//! assert_eq!(Point {x: -1, y: -3}, Point {x: 1, y: 0} - Point {x: 2, y: 3});
|
||||
//! ```
|
||||
//!
|
||||
//! See the documentation for each trait for an example implementation.
|
||||
|
@ -143,7 +148,9 @@
|
|||
//! [`FnOnce`]: trait.FnOnce.html
|
||||
//! [`Add`]: trait.Add.html
|
||||
//! [`Sub`]: trait.Sub.html
|
||||
//! [`Mul`]: trait.Mul.html
|
||||
//! [`clone`]: ../clone/trait.Clone.html#tymethod.clone
|
||||
//! [operator precedence]: ../../reference/expressions.html#operator-precedence
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
|
|
|
@ -10,10 +10,10 @@
|
|||
|
||||
use fmt;
|
||||
|
||||
/// An unbounded range. Use `..` (two dots) for its shorthand.
|
||||
/// An unbounded range (`..`).
|
||||
///
|
||||
/// Its primary use case is slicing index. It cannot serve as an iterator
|
||||
/// because it doesn't have a starting point.
|
||||
/// `RangeFull` is primarily used as a [slicing index], its shorthand is `..`.
|
||||
/// It cannot serve as an [`Iterator`] because it doesn't have a starting point.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -23,8 +23,8 @@ use fmt;
|
|||
/// 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:
|
||||
/// It does not have an [`IntoIterator`] implementation, so you can't use it in
|
||||
/// a `for` loop directly. This won't compile:
|
||||
///
|
||||
/// ```compile_fail,E0277
|
||||
/// for i in .. {
|
||||
|
@ -32,7 +32,7 @@ use fmt;
|
|||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Used as a slicing index, `RangeFull` produces the full array as a slice.
|
||||
/// Used as a [slicing index], `RangeFull` produces the full array as a slice.
|
||||
///
|
||||
/// ```
|
||||
/// let arr = [0, 1, 2, 3];
|
||||
|
@ -41,6 +41,10 @@ use fmt;
|
|||
/// assert_eq!(arr[1.. ], [ 1,2,3]);
|
||||
/// assert_eq!(arr[1..3], [ 1,2 ]);
|
||||
/// ```
|
||||
///
|
||||
/// [`IntoIterator`]: ../iter/trait.Iterator.html
|
||||
/// [`Iterator`]: ../iter/trait.IntoIterator.html
|
||||
/// [slicing index]: ../slice/trait.SliceIndex.html
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct RangeFull;
|
||||
|
@ -52,24 +56,23 @@ impl fmt::Debug for RangeFull {
|
|||
}
|
||||
}
|
||||
|
||||
/// A (half-open) range which is bounded at both ends: { x | start <= x < end }.
|
||||
/// Use `start..end` (two dots) for its shorthand.
|
||||
/// A (half-open) range bounded inclusively below and exclusively above
|
||||
/// (`start..end`).
|
||||
///
|
||||
/// See the [`contains`](#method.contains) method for its characterization.
|
||||
/// The `Range` `start..end` contains all values with `x >= start` and
|
||||
/// `x < end`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// fn main() {
|
||||
/// assert_eq!((3..5), std::ops::Range{ start: 3, end: 5 });
|
||||
/// assert_eq!(3+4+5, (3..6).sum());
|
||||
/// 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
|
||||
/// }
|
||||
/// 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")]
|
||||
|
@ -91,49 +94,49 @@ impl<Idx: fmt::Debug> fmt::Debug for Range<Idx> {
|
|||
|
||||
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
|
||||
impl<Idx: PartialOrd<Idx>> Range<Idx> {
|
||||
/// Returns `true` if `item` is contained in the 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));
|
||||
/// }
|
||||
/// 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.
|
||||
/// A range only bounded inclusively below (`start..`).
|
||||
///
|
||||
/// See the [`contains`](#method.contains) method for its characterization.
|
||||
/// The `RangeFrom` `start..` contains all values with `x >= start`.
|
||||
///
|
||||
/// Note: Currently, no overflow checking is done for the iterator
|
||||
/// *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.
|
||||
/// 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());
|
||||
/// 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 ]);
|
||||
/// }
|
||||
/// 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 ]);
|
||||
/// ```
|
||||
///
|
||||
/// [`Iterator`]: ../iter/trait.IntoIterator.html
|
||||
#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct RangeFrom<Idx> {
|
||||
|
@ -151,46 +154,47 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeFrom<Idx> {
|
|||
|
||||
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
|
||||
impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
|
||||
/// Returns `true` if `item` is contained in the range.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(range_contains)]
|
||||
/// fn main() {
|
||||
/// assert!( ! (3..).contains(2));
|
||||
/// assert!( (3..).contains(3));
|
||||
/// assert!( (3..).contains(1_000_000_000));
|
||||
/// }
|
||||
///
|
||||
/// 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.
|
||||
/// A range only bounded exclusively above (`..end`).
|
||||
///
|
||||
/// See the [`contains`](#method.contains) method for its characterization.
|
||||
///
|
||||
/// It cannot serve as an iterator because it doesn't have a starting point.
|
||||
/// The `RangeTo` `..end` contains all values with `x < end`.
|
||||
/// It cannot serve as an [`Iterator`] because it doesn't have a starting point.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// The `..{integer}` syntax is a `RangeTo`:
|
||||
/// The `..end` syntax is a `RangeTo`:
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!((..5), std::ops::RangeTo{ end: 5 });
|
||||
/// assert_eq!((..5), std::ops::RangeTo { end: 5 });
|
||||
/// ```
|
||||
///
|
||||
/// It does not have an `IntoIterator` implementation, so you can't use it in a
|
||||
/// `for` loop directly. This won't compile:
|
||||
/// It does not have an [`IntoIterator`] implementation, so you can't use it in
|
||||
/// a `for` loop directly. This won't compile:
|
||||
///
|
||||
/// ```compile_fail,E0277
|
||||
/// // error[E0277]: the trait bound `std::ops::RangeTo<{integer}>:
|
||||
/// // std::iter::Iterator` is not satisfied
|
||||
/// for i in ..5 {
|
||||
/// // ...
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// When used as a slicing index, `RangeTo` produces a slice of all array
|
||||
/// When used as a [slicing index], `RangeTo` produces a slice of all array
|
||||
/// elements before the index indicated by `end`.
|
||||
///
|
||||
/// ```
|
||||
|
@ -200,6 +204,10 @@ impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
|
|||
/// assert_eq!(arr[1.. ], [ 1,2,3]);
|
||||
/// assert_eq!(arr[1..3], [ 1,2 ]);
|
||||
/// ```
|
||||
///
|
||||
/// [`IntoIterator`]: ../iter/trait.Iterator.html
|
||||
/// [`Iterator`]: ../iter/trait.IntoIterator.html
|
||||
/// [slicing index]: ../slice/trait.SliceIndex.html
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct RangeTo<Idx> {
|
||||
|
@ -217,38 +225,38 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeTo<Idx> {
|
|||
|
||||
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
|
||||
impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
|
||||
/// Returns `true` if `item` is contained in the range.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(range_contains)]
|
||||
/// fn main() {
|
||||
/// assert!( (..5).contains(-1_000_000_000));
|
||||
/// assert!( (..5).contains(4));
|
||||
/// assert!( ! (..5).contains(5));
|
||||
/// }
|
||||
///
|
||||
/// 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.
|
||||
/// An range bounded inclusively below and above (`start...end`).
|
||||
///
|
||||
/// See the [`contains`](#method.contains) method for its characterization.
|
||||
/// The `RangeInclusive` `start...end` contains all values with `x >= start`
|
||||
/// and `x <= end`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(inclusive_range,inclusive_range_syntax)]
|
||||
/// fn main() {
|
||||
/// assert_eq!((3...5), std::ops::RangeInclusive{ 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
|
||||
/// }
|
||||
/// assert_eq!((3...5), std::ops::RangeInclusive { 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")]
|
||||
|
@ -274,61 +282,68 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> {
|
|||
|
||||
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
|
||||
impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
|
||||
/// Returns `true` if `item` is contained in the range.
|
||||
///
|
||||
/// # 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));
|
||||
/// }
|
||||
/// 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 {
|
||||
self.start <= item && item <= self.end
|
||||
}
|
||||
}
|
||||
|
||||
/// An inclusive range which is only bounded above: { x | x <= end }.
|
||||
/// Use `...end` (three dots) for its shorthand.
|
||||
/// A range only bounded inclusively above (`...end`).
|
||||
///
|
||||
/// See the [`contains`](#method.contains) method for its characterization.
|
||||
///
|
||||
/// It cannot serve as an iterator because it doesn't have a starting point.
|
||||
/// The `RangeToInclusive` `...end` contains all values with `x <= end`.
|
||||
/// It cannot serve as an [`Iterator`] because it doesn't have a starting point.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// The `...{integer}` syntax is a `RangeToInclusive`:
|
||||
/// The `...end` syntax is a `RangeToInclusive`:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(inclusive_range,inclusive_range_syntax)]
|
||||
/// assert_eq!((...5), std::ops::RangeToInclusive{ end: 5 });
|
||||
/// ```
|
||||
///
|
||||
/// It does not have an `IntoIterator` implementation, so you can't use it in a
|
||||
/// It does not have an [`IntoIterator`] implementation, so you can't use it in a
|
||||
/// `for` loop directly. This won't compile:
|
||||
///
|
||||
/// ```compile_fail,E0277
|
||||
/// #![feature(inclusive_range_syntax)]
|
||||
///
|
||||
/// // error[E0277]: the trait bound `std::ops::RangeToInclusive<{integer}>:
|
||||
/// // std::iter::Iterator` is not satisfied
|
||||
/// for i in ...5 {
|
||||
/// // ...
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// When used as a slicing index, `RangeToInclusive` produces a slice of all
|
||||
/// When used as a [slicing index], `RangeToInclusive` produces a slice of all
|
||||
/// array elements up to and including the index indicated by `end`.
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(inclusive_range_syntax)]
|
||||
///
|
||||
/// let arr = [0, 1, 2, 3];
|
||||
/// assert_eq!(arr[ ...2], [0,1,2 ]); // RangeToInclusive
|
||||
/// assert_eq!(arr[1...2], [ 1,2 ]);
|
||||
/// ```
|
||||
///
|
||||
/// [`IntoIterator`]: ../iter/trait.Iterator.html
|
||||
/// [`Iterator`]: ../iter/trait.IntoIterator.html
|
||||
/// [slicing index]: ../slice/trait.SliceIndex.html
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
|
||||
pub struct RangeToInclusive<Idx> {
|
||||
|
@ -348,15 +363,16 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeToInclusive<Idx> {
|
|||
|
||||
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
|
||||
impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
|
||||
/// Returns `true` if `item` is contained in the range.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(range_contains,inclusive_range_syntax)]
|
||||
/// fn main() {
|
||||
/// assert!( (...5).contains(-1_000_000_000));
|
||||
/// assert!( (...5).contains(5));
|
||||
/// assert!( ! (...5).contains(6));
|
||||
/// }
|
||||
///
|
||||
/// 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)
|
||||
|
|
Loading…
Reference in a new issue