aboutsummaryrefslogtreecommitdiff
path: root/libcore/cmp.rs
diff options
context:
space:
mode:
authorpravic <[email protected]>2016-06-06 23:07:53 +0300
committerpravic <[email protected]>2016-06-06 23:07:53 +0300
commitf2db0929feeb53567655dbdebba7e6b1c3f2f69e (patch)
treec2cf041f838782f9ddd8994146f52e8f498bfe07 /libcore/cmp.rs
parentadd 'netio' native import library (diff)
parentMerge branch 'nofp_patch' into libcore_nofp (diff)
downloadkmd-env-rs-master.tar.xz
kmd-env-rs-master.zip
Merge branch 'libcore_nofp'HEADmaster
Diffstat (limited to 'libcore/cmp.rs')
-rw-r--r--libcore/cmp.rs168
1 files changed, 164 insertions, 4 deletions
diff --git a/libcore/cmp.rs b/libcore/cmp.rs
index d3481ba..8764766 100644
--- a/libcore/cmp.rs
+++ b/libcore/cmp.rs
@@ -53,12 +53,43 @@ use option::Option::{self, Some};
/// symmetrically and transitively: if `T: PartialEq<U>` and `U: PartialEq<V>`
/// then `U: PartialEq<T>` and `T: PartialEq<V>`.
///
+/// ## Derivable
+///
+/// This trait can be used with `#[derive]`. When `derive`d on structs, two
+/// instances are equal if all fields are equal, and not equal if any fields
+/// are not equal. When `derive`d on enums, each variant is equal to itself
+/// and not equal to the other variants.
+///
+/// ## How can I implement `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`.
///
-/// This trait can be used with `#[derive]`.
+/// An example implementation for a domain in which two books are considered
+/// the same book if their ISBN matches, even if the formats differ:
+///
+/// ```
+/// enum BookFormat { Paperback, Hardback, Ebook }
+/// struct Book {
+/// isbn: i32,
+/// format: BookFormat,
+/// }
+///
+/// impl PartialEq for Book {
+/// fn eq(&self, other: &Book) -> bool {
+/// self.isbn == other.isbn
+/// }
+/// }
+///
+/// let b1 = Book { isbn: 3, format: BookFormat::Paperback };
+/// let b2 = Book { isbn: 3, format: BookFormat::Ebook };
+/// let b3 = Book { isbn: 10, format: BookFormat::Paperback };
+///
+/// assert!(b1 == b2);
+/// assert!(b1 != b3);
+/// ```
///
/// # Examples
///
@@ -96,7 +127,32 @@ pub trait PartialEq<Rhs: ?Sized = Self> {
/// This property cannot be checked by the compiler, and therefore `Eq` implies
/// `PartialEq`, and has no extra methods.
///
-/// This trait can be used with `#[derive]`.
+/// ## Derivable
+///
+/// This trait can be used with `#[derive]`. When `derive`d, because `Eq` has
+/// no extra methods, it is only informing the compiler that this is an
+/// equivalence relation rather than a partial equivalence relation. Note that
+/// the `derive` strategy requires all fields are `PartialEq`, which isn't
+/// always desired.
+///
+/// ## How can I implement `Eq`?
+///
+/// If you cannot use the `derive` strategy, specify that your type implements
+/// `Eq`, which has no methods:
+///
+/// ```
+/// enum BookFormat { Paperback, Hardback, Ebook }
+/// struct Book {
+/// isbn: i32,
+/// format: BookFormat,
+/// }
+/// impl PartialEq for Book {
+/// fn eq(&self, other: &Book) -> bool {
+/// self.isbn == other.isbn
+/// }
+/// }
+/// impl Eq for Book {}
+/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Eq: PartialEq<Self> {
// FIXME #13101: this method is used solely by #[deriving] to
@@ -190,8 +246,49 @@ impl Ordering {
/// - 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 `>`.
///
+/// ## Derivable
+///
/// This trait can be used with `#[derive]`. When `derive`d, it will produce a lexicographic
/// ordering based on the top-to-bottom declaration order of the struct's members.
+///
+/// ## How can I implement `Ord`?
+///
+/// `Ord` requires that the type also be `PartialOrd` and `Eq` (which requires `PartialEq`).
+///
+/// Then you must define an implementation for `cmp()`. You may find it useful to use
+/// `cmp()` on your type's fields.
+///
+/// Here's an example where you want to sort people by height only, disregarding `id`
+/// and `name`:
+///
+/// ```
+/// use std::cmp::Ordering;
+///
+/// #[derive(Eq)]
+/// struct Person {
+/// id: u32,
+/// name: String,
+/// height: u32,
+/// }
+///
+/// impl Ord for Person {
+/// fn cmp(&self, other: &Person) -> Ordering {
+/// self.height.cmp(&other.height)
+/// }
+/// }
+///
+/// impl PartialOrd for Person {
+/// fn partial_cmp(&self, other: &Person) -> Option<Ordering> {
+/// Some(self.cmp(other))
+/// }
+/// }
+///
+/// impl PartialEq for Person {
+/// fn eq(&self, other: &Person) -> bool {
+/// self.height == other.height
+/// }
+/// }
+/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Ord: Eq + PartialOrd<Self> {
/// This method returns an `Ordering` between `self` and `other`.
@@ -242,6 +339,13 @@ impl PartialOrd for Ordering {
/// transitively: if `T: PartialOrd<U>` and `U: PartialOrd<V>` then `U: PartialOrd<T>` and `T:
/// PartialOrd<V>`.
///
+/// ## Derivable
+///
+/// This trait can be used with `#[derive]`. When `derive`d, it will produce a lexicographic
+/// ordering based on the top-to-bottom declaration order of the struct's members.
+///
+/// ## How can I implement `Ord`?
+///
/// PartialOrd only requires implementation of the `partial_cmp` method, with the others generated
/// from default implementations.
///
@@ -249,8 +353,64 @@ impl PartialOrd for Ordering {
/// total order. For example, for floating point numbers, `NaN < 0 == false` and `NaN >= 0 ==
/// false` (cf. IEEE 754-2008 section 5.11).
///
-/// This trait can be used with `#[derive]`. When `derive`d, it will produce an ordering
-/// based on the top-to-bottom declaration order of the struct's members.
+/// `PartialOrd` requires your type to be `PartialEq`.
+///
+/// If your type is `Ord`, you can implement `partial_cmp()` by using `cmp()`:
+///
+/// ```
+/// use std::cmp::Ordering;
+///
+/// #[derive(Eq)]
+/// struct Person {
+/// id: u32,
+/// name: String,
+/// height: u32,
+/// }
+///
+/// impl PartialOrd for Person {
+/// fn partial_cmp(&self, other: &Person) -> Option<Ordering> {
+/// Some(self.cmp(other))
+/// }
+/// }
+///
+/// impl Ord for Person {
+/// fn cmp(&self, other: &Person) -> Ordering {
+/// self.height.cmp(&other.height)
+/// }
+/// }
+///
+/// impl PartialEq for Person {
+/// fn eq(&self, other: &Person) -> bool {
+/// self.height == other.height
+/// }
+/// }
+/// ```
+///
+/// You may also find it useful to use `partial_cmp()` on your type`s fields. Here
+/// is an example of `Person` types who have a floating-point `height` field that
+/// is the only field to be used for sorting:
+///
+/// ```
+/// use std::cmp::Ordering;
+///
+/// struct Person {
+/// id: u32,
+/// name: String,
+/// height: f64,
+/// }
+///
+/// impl PartialOrd for Person {
+/// fn partial_cmp(&self, other: &Person) -> Option<Ordering> {
+/// self.height.partial_cmp(&other.height)
+/// }
+/// }
+///
+/// impl PartialEq for Person {
+/// fn eq(&self, other: &Person) -> bool {
+/// self.height == other.height
+/// }
+/// }
+/// ```
///
/// # Examples
///