diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 1ebd2df5814..5bc634936cf 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -8,35 +8,33 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Defines the `PartialOrd` and `PartialEq` comparison traits. +//! Functionality for ordering and comparison. //! -//! This module defines both `PartialOrd` and `PartialEq` traits which are used by the -//! compiler to implement comparison operators. Rust programs may implement -//!`PartialOrd` to overload the `<`, `<=`, `>`, and `>=` operators, and may implement -//! `PartialEq` to overload the `==` and `!=` operators. +//! This module defines both `PartialOrd` and `PartialEq` traits which are used by the compiler to +//! implement comparison operators. Rust programs may implement `PartialOrd` to overload the `<`, +//! `<=`, `>`, and `>=` operators, and may implement `PartialEq` to overload the `==` and `!=` +//! operators. //! -//! For example, to define a type with a customized definition for the PartialEq -//! operators, you could do the following: +//! For example, to define a type with a customized definition for the PartialEq operators, you +//! could do the following: //! -//! ```rust +//! ``` //! use core::num::SignedInt; //! -//! // Our type. -//! struct SketchyNum { -//! num : int +//! struct FuzzyNum { +//! num: i32, //! } //! -//! // Our implementation of `PartialEq` to support `==` and `!=`. -//! impl PartialEq for SketchyNum { +//! impl PartialEq for FuzzyNum { //! // Our custom eq allows numbers which are near each other to be equal! :D -//! fn eq(&self, other: &SketchyNum) -> bool { +//! fn eq(&self, other: &FuzzyNum) -> bool { //! (self.num - other.num).abs() < 5 //! } //! } //! //! // Now these binary operators will work when applied! -//! assert!(SketchyNum {num: 37} == SketchyNum {num: 34}); -//! assert!(SketchyNum {num: 25} != SketchyNum {num: 57}); +//! assert!(FuzzyNum { num: 37 } == FuzzyNum { num: 34 }); +//! assert!(FuzzyNum { num: 25 } != FuzzyNum { num: 57 }); //! ``` #![stable(feature = "rust1", since = "1.0.0")] @@ -49,24 +47,22 @@ use option::Option::{self, Some, None}; /// Trait for equality comparisons which are [partial equivalence relations]( /// http://en.wikipedia.org/wiki/Partial_equivalence_relation). /// -/// This trait allows for partial equality, for types that do not have a full -/// equivalence relation. For example, in floating point numbers `NaN != NaN`, -/// so floating point types implement `PartialEq` but not `Eq`. +/// This trait allows for partial equality, for types that do not have a full equivalence relation. +/// For example, in floating point numbers `NaN != NaN`, so floating point types implement +/// `PartialEq` but not `Eq`. /// /// Formally, the equality must be (for all `a`, `b` and `c`): /// /// - symmetric: `a == b` implies `b == a`; and /// - transitive: `a == b` and `b == c` implies `a == c`. /// -/// Note that these requirements mean that the trait itself must be -/// implemented symmetrically and transitively: if `T: PartialEq` -/// and `U: PartialEq` then `U: PartialEq` and `T: +/// Note that these requirements mean that the trait itself must be implemented symmetrically and +/// transitively: if `T: PartialEq` and `U: PartialEq` then `U: PartialEq` and `T: /// PartialEq`. /// -/// PartialEq only requires the `eq` method to be implemented; `ne` is defined -/// in terms of it by default. Any manual implementation of `ne` *must* respect -/// the rule that `eq` is a strict inverse of `ne`; that is, `!(a == b)` if and -/// only if `a != b`. +/// PartialEq only requires the `eq` method to be implemented; `ne` is defined in terms of it by +/// default. Any manual implementation of `ne` *must* respect the rule that `eq` is a strict +/// inverse of `ne`; that is, `!(a == b)` if and only if `a != b`. #[lang="eq"] #[stable(feature = "rust1", since = "1.0.0")] #[old_orphan_check] @@ -84,12 +80,15 @@ pub trait PartialEq { /// Trait for equality comparisons which are [equivalence relations]( /// https://en.wikipedia.org/wiki/Equivalence_relation). /// -/// This means, that in addition to `a == b` and `a != b` being strict -/// inverses, the equality must be (for all `a`, `b` and `c`): +/// This means, that in addition to `a == b` and `a != b` being strict inverses, the equality must +/// be (for all `a`, `b` and `c`): /// /// - reflexive: `a == a`; /// - symmetric: `a == b` implies `b == a`; and /// - transitive: `a == b` and `b == c` implies `a == c`. +/// +/// This property cannot be checked by the compiler, and therefore `Eq` implies `PartialEq`, and +/// has no extra methods. #[stable(feature = "rust1", since = "1.0.0")] pub trait Eq: PartialEq { // FIXME #13101: this method is used solely by #[deriving] to @@ -104,7 +103,22 @@ pub trait Eq: PartialEq { fn assert_receiver_is_total_eq(&self) {} } -/// An ordering is, e.g, a result of a comparison between two values. +/// An `Ordering` is the result of a comparison between two values. +/// +/// # Examples +/// +/// ``` +/// use std::cmp::Ordering; +/// +/// let result = 1.cmp(&2); +/// assert_eq!(Ordering::Less, result); +/// +/// let result = 1.cmp(&1); +/// assert_eq!(Ordering::Equal, result); +/// +/// let result = 2.cmp(&1); +/// assert_eq!(Ordering::Greater, result); +/// ``` #[derive(Clone, Copy, PartialEq, Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub enum Ordering { @@ -120,17 +134,28 @@ pub enum Ordering { } impl Ordering { - /// Reverse the `Ordering`, so that `Less` becomes `Greater` and - /// vice versa. + /// Reverse the `Ordering`. /// - /// # Example + /// * `Less` becomes `Greater`. + /// * `Greater` becomes `Less`. + /// * `Equal` becomes `Equal`. /// - /// ```rust - /// use std::cmp::Ordering::{Less, Equal, Greater}; + /// # Examples /// - /// assert_eq!(Less.reverse(), Greater); - /// assert_eq!(Equal.reverse(), Equal); - /// assert_eq!(Greater.reverse(), Less); + /// Basic behavior: + /// + /// ``` + /// use std::cmp::Ordering; + /// + /// assert_eq!(Ordering::Less.reverse(), Ordering::Greater); + /// assert_eq!(Ordering::Equal.reverse(), Ordering::Equal); + /// assert_eq!(Ordering::Greater.reverse(), Ordering::Less); + /// ``` + /// + /// This method can be used to reverse a comparison: + /// + /// ``` + /// use std::cmp::Ordering; /// /// let mut data: &mut [_] = &mut [2, 10, 5, 8]; /// @@ -155,28 +180,27 @@ impl Ordering { } } -/// Trait for types that form a [total order]( -/// https://en.wikipedia.org/wiki/Total_order). +/// Trait for types that form a [total order](https://en.wikipedia.org/wiki/Total_order). /// /// An order is a total order if it is (for all `a`, `b` and `c`): /// -/// - total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is -/// true; and -/// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for -/// both `==` and `>`. +/// - total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true; and +/// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`. #[stable(feature = "rust1", since = "1.0.0")] pub trait Ord: Eq + PartialOrd { - /// This method returns an ordering between `self` and `other` values. + /// This method returns an `Ordering` between `self` and `other`. /// - /// By convention, `self.cmp(&other)` returns the ordering matching - /// the expression `self other` if true. For example: + /// By convention, `self.cmp(&other)` returns the ordering matching the expression + /// `self other` if true. + /// + /// # Examples /// /// ``` - /// use std::cmp::Ordering::{Less, Equal, Greater}; + /// use std::cmp::Ordering; /// - /// assert_eq!( 5.cmp(&10), Less); // because 5 < 10 - /// assert_eq!(10.cmp(&5), Greater); // because 10 > 5 - /// assert_eq!( 5.cmp(&5), Equal); // because 5 == 5 + /// assert_eq!(5.cmp(&10), Ordering::Less); + /// assert_eq!(10.cmp(&5), Ordering::Greater); + /// assert_eq!(5.cmp(&5), Ordering::Equal); /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn cmp(&self, other: &Self) -> Ordering; @@ -208,30 +232,60 @@ impl PartialOrd for Ordering { /// The comparison must satisfy, for all `a`, `b` and `c`: /// /// - antisymmetry: if `a < b` then `!(a > b)` and vice versa; and -/// - transitivity: `a < b` and `b < c` implies `a < c`. The same must hold for -/// both `==` and `>`. +/// - transitivity: `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`. /// -/// Note that these requirements mean that the trait itself must be -/// implemented symmetrically and transitively: if `T: PartialOrd` -/// and `U: PartialOrd` then `U: PartialOrd` and `T: +/// Note that these requirements mean that the trait itself must be implemented symmetrically and +/// transitively: if `T: PartialOrd` and `U: PartialOrd` then `U: PartialOrd` and `T: /// PartialOrd`. /// -/// PartialOrd only requires implementation of the `partial_cmp` method, -/// with the others generated from default implementations. +/// PartialOrd only requires implementation of the `partial_cmp` method, with the others generated +/// from default implementations. /// -/// However it remains possible to implement the others separately for types -/// which do not have a total order. For example, for floating point numbers, -/// `NaN < 0 == false` and `NaN >= 0 == false` (cf. IEEE 754-2008 section -/// 5.11). +/// However it remains possible to implement the others separately for types which do not have a +/// total order. For example, for floating point numbers, `NaN < 0 == false` and `NaN >= 0 == +/// false` (cf. IEEE 754-2008 section 5.11). #[lang="ord"] #[stable(feature = "rust1", since = "1.0.0")] pub trait PartialOrd: PartialEq { - /// This method returns an ordering between `self` and `other` values - /// if one exists. + /// This method returns an ordering between `self` and `other` values if one exists. + /// + /// # Examples + /// + /// ``` + /// use std::cmp::Ordering; + /// + /// let result = 1.0.partial_cmp(&2.0); + /// assert_eq!(result, Some(Ordering::Less)); + /// + /// let result = 1.0.partial_cmp(&1.0); + /// assert_eq!(result, Some(Ordering::Equal)); + /// + /// let result = 2.0.partial_cmp(&1.0); + /// assert_eq!(result, Some(Ordering::Greater)); + /// ``` + /// + /// When comparison is impossible: + /// + /// ``` + /// let result = std::f64::NAN.partial_cmp(&1.0); + /// assert_eq!(result, None); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn partial_cmp(&self, other: &Rhs) -> Option; /// This method tests less than (for `self` and `other`) and is used by the `<` operator. + /// + /// # Examples + /// + /// ``` + /// use std::cmp::Ordering; + /// + /// let result = 1.0 < 2.0; + /// assert_eq!(result, true); + /// + /// let result = 2.0 < 1.0; + /// assert_eq!(result, false); + /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn lt(&self, other: &Rhs) -> bool { @@ -241,7 +295,18 @@ pub trait PartialOrd: PartialEq { } } - /// This method tests less than or equal to (`<=`). + /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=` + /// operator. + /// + /// # Examples + /// + /// ``` + /// let result = 1.0 <= 2.0; + /// assert_eq!(result, true); + /// + /// let result = 2.0 <= 2.0; + /// assert_eq!(result, true); + /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn le(&self, other: &Rhs) -> bool { @@ -251,7 +316,17 @@ pub trait PartialOrd: PartialEq { } } - /// This method tests greater than (`>`). + /// This method tests greater than (for `self` and `other`) and is used by the `>` operator. + /// + /// # Examples + /// + /// ``` + /// let result = 1.0 > 2.0; + /// assert_eq!(result, false); + /// + /// let result = 2.0 > 2.0; + /// assert_eq!(result, false); + /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn gt(&self, other: &Rhs) -> bool { @@ -261,7 +336,18 @@ pub trait PartialOrd: PartialEq { } } - /// This method tests greater than or equal to (`>=`). + /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=` + /// operator. + /// + /// # Examples + /// + /// ``` + /// let result = 2.0 >= 1.0; + /// assert_eq!(result, true); + /// + /// let result = 2.0 >= 2.0; + /// assert_eq!(result, true); + /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn ge(&self, other: &Rhs) -> bool { @@ -273,6 +359,15 @@ pub trait PartialOrd: PartialEq { } /// Compare and return the minimum of two values. +/// +/// # Examples +/// +/// ``` +/// use std::cmp; +/// +/// assert_eq!(1, cmp::min(1, 2)); +/// assert_eq!(2, cmp::min(2, 2)); +/// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn min(v1: T, v2: T) -> T { @@ -280,6 +375,15 @@ pub fn min(v1: T, v2: T) -> T { } /// Compare and return the maximum of two values. +/// +/// # Examples +/// +/// ``` +/// use std::cmp; +/// +/// assert_eq!(2, cmp::max(1, 2)); +/// assert_eq!(2, cmp::max(2, 2)); +/// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn max(v1: T, v2: T) -> T { @@ -289,6 +393,24 @@ pub fn max(v1: T, v2: T) -> T { /// Compare and return the minimum of two values if there is one. /// /// Returns the first argument if the comparison determines them to be equal. +/// +/// # Examples +/// +/// ``` +/// use std::cmp; +/// +/// assert_eq!(Some(1), cmp::partial_min(1, 2)); +/// assert_eq!(Some(2), cmp::partial_min(2, 2)); +/// ``` +/// +/// When comparison is impossible: +/// +/// ``` +/// use std::cmp; +/// +/// let result = cmp::partial_min(std::f64::NAN, &1.0); +/// assert_eq!(result, None); +/// ``` #[inline] #[unstable(feature = "core")] pub fn partial_min(v1: T, v2: T) -> Option { @@ -302,6 +424,24 @@ pub fn partial_min(v1: T, v2: T) -> Option { /// Compare and return the maximum of two values if there is one. /// /// Returns the first argument if the comparison determines them to be equal. +/// +/// # Examples +/// +/// ``` +/// use std::cmp; +/// +/// assert_eq!(Some(2), cmp::partial_max(1, 2)); +/// assert_eq!(Some(2), cmp::partial_max(2, 2)); +/// ``` +/// +/// When comparison is impossible: +/// +/// ``` +/// use std::cmp; +/// +/// let result = cmp::partial_max(std::f64::NAN, &1.0); +/// assert_eq!(result, None); +/// ``` #[inline] #[unstable(feature = "core")] pub fn partial_max(v1: T, v2: T) -> Option {