rust/library/core/src/cmp.rs

1470 lines
43 KiB
Rust
Raw Normal View History

2015-02-06 02:57:55 +00:00
//! Functionality for ordering and comparison.
//!
2019-01-10 20:21:01 +00:00
//! This module contains various tools for ordering and comparing values. In
//! summary:
2016-09-26 18:43:54 +00:00
//!
2019-01-10 20:21:01 +00:00
//! * [`Eq`] and [`PartialEq`] are traits that allow you to define total and
//! partial equality between values, respectively. Implementing them overloads
//! the `==` and `!=` operators.
//! * [`Ord`] and [`PartialOrd`] are traits that allow you to define total and
//! partial orderings between values, respectively. Implementing them overloads
//! the `<`, `<=`, `>`, and `>=` operators.
//! * [`Ordering`] is an enum returned by the main functions of [`Ord`] and
//! [`PartialOrd`], and describes an ordering.
//! * [`Reverse`] is a struct that allows you to easily reverse an ordering.
//! * [`max`] and [`min`] are functions that build off of [`Ord`] and allow you
//! to find the maximum or minimum of two values.
2016-03-14 15:43:55 +00:00
//!
2019-01-10 20:21:01 +00:00
//! For more details, see the respective documentation of each item in the list.
//!
2020-08-10 21:16:01 +00:00
//! [`max`]: Ord::max
//! [`min`]: Ord::min
2015-01-24 05:48:20 +00:00
#![stable(feature = "rust1", since = "1.0.0")]
use self::Ordering::*;
/// Trait for equality comparisons which are [partial equivalence
2020-08-23 10:02:42 +00:00
/// relations](https://en.wikipedia.org/wiki/Partial_equivalence_relation).
///
/// This trait allows for partial equality, for types that do not have a full
2019-02-09 21:23:30 +00:00
/// equivalence relation. For example, in floating point numbers `NaN != NaN`,
/// so floating point types implement `PartialEq` but not [`trait@Eq`].
///
/// Formally, the equality must be (for all `a`, `b`, `c` of type `A`, `B`,
/// `C`):
///
/// - **Symmetric**: if `A: PartialEq<B>` and `B: PartialEq<A>`, then **`a == b`
/// implies `b == a`**; and
///
/// - **Transitive**: if `A: PartialEq<B>` and `B: PartialEq<C>` and `A:
/// PartialEq<C>`, then **`a == b` and `b == c` implies `a == c`**.
///
/// Note that the `B: PartialEq<A>` (symmetric) and `A: PartialEq<C>`
/// (transitive) impls are not forced to exist, but these requirements apply
/// whenever they do exist.
///
/// ## 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.
2016-03-14 15:43:55 +00:00
///
/// ## How can I implement `PartialEq`?
///
2020-01-29 12:32:37 +00:00
/// `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`.
///
2020-01-29 12:32:37 +00:00
/// Implementations of `PartialEq`, [`PartialOrd`], and [`Ord`] *must* agree with
/// each other. It's easy to accidentally make them disagree by deriving some
/// of the traits and manually implementing others.
///
/// An example implementation for a domain in which two books are considered
/// the same book if their ISBN matches, even if the formats differ:
///
/// ```
2018-08-21 21:24:23 +00:00
/// enum BookFormat {
/// Paperback,
/// Hardback,
/// Ebook,
/// }
///
/// struct Book {
/// isbn: i32,
/// format: BookFormat,
/// }
///
/// impl PartialEq for Book {
/// fn eq(&self, other: &Self) -> 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);
/// ```
///
2018-08-21 21:24:23 +00:00
/// ## How can I compare two different types?
///
/// The type you can compare with is controlled by `PartialEq`'s type parameter.
/// For example, let's tweak our previous code a bit:
///
/// ```
/// // The derive implements <BookFormat> == <BookFormat> comparisons
2019-01-06 20:18:22 +00:00
/// #[derive(PartialEq)]
2018-08-21 21:24:23 +00:00
/// enum BookFormat {
/// Paperback,
/// Hardback,
/// Ebook,
/// }
///
/// struct Book {
/// isbn: i32,
/// format: BookFormat,
/// }
///
/// // Implement <Book> == <BookFormat> comparisons
2018-08-21 21:24:23 +00:00
/// impl PartialEq<BookFormat> for Book {
/// fn eq(&self, other: &BookFormat) -> bool {
/// self.format == *other
2018-08-21 21:24:23 +00:00
/// }
/// }
///
/// // Implement <BookFormat> == <Book> comparisons
/// impl PartialEq<Book> for BookFormat {
2018-08-21 21:24:23 +00:00
/// fn eq(&self, other: &Book) -> bool {
2019-01-06 03:52:13 +00:00
/// *self == other.format
2018-08-21 21:24:23 +00:00
/// }
/// }
///
/// let b1 = Book { isbn: 3, format: BookFormat::Paperback };
///
/// assert!(b1 == BookFormat::Paperback);
/// assert!(BookFormat::Ebook != b1);
2018-08-21 21:24:23 +00:00
/// ```
///
/// By changing `impl PartialEq for Book` to `impl PartialEq<BookFormat> for Book`,
/// we allow `BookFormat`s to be compared with `Book`s.
2018-08-21 21:24:23 +00:00
///
/// A comparison like the one above, which ignores some fields of the struct,
/// can be dangerous. It can easily lead to an unintended violation of the
/// requirements for a partial equivalence relation. For example, if we kept
/// the above implementation of `PartialEq<Book>` for `BookFormat` and added an
/// implementation of `PartialEq<Book>` for `Book` (either via a `#[derive]` or
/// via the manual implementation from the first example) then the result would
/// violate transitivity:
///
/// ```should_panic
/// #[derive(PartialEq)]
2018-08-21 21:24:23 +00:00
/// enum BookFormat {
/// Paperback,
/// Hardback,
/// Ebook,
/// }
///
/// #[derive(PartialEq)]
2018-08-21 21:24:23 +00:00
/// struct Book {
/// isbn: i32,
/// format: BookFormat,
/// }
///
/// impl PartialEq<BookFormat> for Book {
/// fn eq(&self, other: &BookFormat) -> bool {
/// self.format == *other
/// }
/// }
2019-01-12 16:19:02 +00:00
///
/// impl PartialEq<Book> for BookFormat {
/// fn eq(&self, other: &Book) -> bool {
/// *self == other.format
2018-08-21 21:24:23 +00:00
/// }
/// }
///
/// fn main() {
/// let b1 = Book { isbn: 1, format: BookFormat::Paperback };
/// let b2 = Book { isbn: 2, format: BookFormat::Paperback };
2018-08-21 21:24:23 +00:00
///
/// assert!(b1 == BookFormat::Paperback);
/// assert!(BookFormat::Paperback == b2);
2018-08-21 21:24:23 +00:00
///
/// // The following should hold by transitivity but doesn't.
/// assert!(b1 == b2); // <-- PANICS
/// }
2018-08-21 21:24:23 +00:00
/// ```
///
2016-03-14 15:43:55 +00:00
/// # Examples
///
/// ```
/// let x: u32 = 0;
/// let y: u32 = 1;
///
/// assert_eq!(x == y, false);
/// assert_eq!(x.eq(&y), false);
/// ```
2020-01-29 12:32:37 +00:00
///
/// [`eq`]: PartialEq::eq
/// [`ne`]: PartialEq::ne
#[lang = "eq"]
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
2018-04-25 18:10:58 +00:00
#[doc(alias = "==")]
#[doc(alias = "!=")]
#[rustc_on_unimplemented(
2019-12-22 22:42:04 +00:00
message = "can't compare `{Self}` with `{Rhs}`",
label = "no implementation for `{Self} == {Rhs}`"
)]
pub trait PartialEq<Rhs: ?Sized = Self> {
/// This method tests for `self` and `other` values to be equal, and is used
/// by `==`.
#[must_use]
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
fn eq(&self, other: &Rhs) -> bool;
2014-10-30 01:11:16 +00:00
/// This method tests for `!=`.
#[inline]
#[must_use]
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
2019-12-22 22:42:04 +00:00
fn ne(&self, other: &Rhs) -> bool {
!self.eq(other)
}
2014-10-30 01:11:16 +00:00
}
/// Derive macro generating an impl of the trait `PartialEq`.
#[rustc_builtin_macro]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
Migrate from `#[structural_match]` attribute a lang-item trait. (Or more precisely, a pair of such traits: one for `derive(PartialEq)` and one for `derive(Eq)`.) ((The addition of the second marker trait, `StructuralEq`, is largely a hack to work-around `fn (&T)` not implementing `PartialEq` and `Eq`; see also issue rust-lang/rust#46989; otherwise I would just check if `Eq` is implemented.)) Note: this does not use trait fulfillment error-reporting machinery; it just uses the trait system to determine if the ADT was tagged or not. (Nonetheless, I have kept an `on_unimplemented` message on the new trait for structural_match check, even though it is currently not used.) Note also: this does *not* resolve the ICE from rust-lang/rust#65466, as noted in a comment added in this commit. Further work is necessary to resolve that and other problems with the structural match checking, especially to do so without breaking stable code (adapted from test fn-ptr-is-structurally-matchable.rs): ```rust fn r_sm_to(_: &SM) {} fn main() { const CFN6: Wrap<fn(&SM)> = Wrap(r_sm_to); let input: Wrap<fn(&SM)> = Wrap(r_sm_to); match Wrap(input) { Wrap(CFN6) => {} Wrap(_) => {} }; } ``` where we would hit a problem with the strategy of unconditionally checking for `PartialEq` because the type `for <'a> fn(&'a SM)` does not currently even *implement* `PartialEq`. ---- added review feedback: * use an or-pattern * eschew `return` when tail position will do. * don't need fresh_expansion; just add `structural_match` to appropriate `allow_internal_unstable` attributes. also fixed example in doc comment so that it actually compiles.
2019-10-17 08:54:37 +00:00
#[allow_internal_unstable(core_intrinsics, structural_match)]
2019-12-22 22:42:04 +00:00
pub macro PartialEq($item:item) {
/* compiler built-in */
}
/// Trait for equality comparisons which are [equivalence relations](
/// https://en.wikipedia.org/wiki/Equivalence_relation).
///
2015-02-06 02:57:55 +00:00
/// 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`.
2015-02-06 02:57:55 +00:00
///
2015-02-17 23:24:34 +00:00
/// This property cannot be checked by the compiler, and therefore `Eq` implies
2020-01-29 12:32:37 +00:00
/// [`PartialEq`], and has no extra methods.
///
/// ## 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
2016-08-26 16:23:42 +00:00
/// the `derive` strategy requires all fields are `Eq`, 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: &Self) -> bool {
/// self.isbn == other.isbn
/// }
/// }
/// impl Eq for Book {}
/// ```
2018-04-25 18:10:58 +00:00
#[doc(alias = "==")]
#[doc(alias = "!=")]
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-05 02:39:02 +00:00
pub trait Eq: PartialEq<Self> {
// this method is used solely by #[deriving] to assert
// that every component of a type implements #[deriving]
2014-10-30 01:11:16 +00:00
// itself, the current deriving infrastructure means doing this
// assertion without using a method on this trait is nearly
// impossible.
//
// This should never be implemented by hand.
#[doc(hidden)]
#[cfg_attr(not(bootstrap), no_coverage)] // rust-lang/rust#84605
#[inline]
2015-02-17 23:24:34 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
2014-10-30 01:11:16 +00:00
fn assert_receiver_is_total_eq(&self) {}
}
/// Derive macro generating an impl of the trait `Eq`.
#[rustc_builtin_macro]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow_internal_unstable(core_intrinsics, derive_eq, structural_match, no_coverage)]
2019-12-22 22:42:04 +00:00
pub macro Eq($item:item) {
/* compiler built-in */
}
2016-08-26 16:23:42 +00:00
// FIXME: this struct is used solely by #[derive] to
// assert that every component of a type implements Eq.
//
// This struct should never appear in user code.
#[doc(hidden)]
#[allow(missing_debug_implementations)]
2019-12-22 22:42:04 +00:00
#[unstable(feature = "derive_eq", reason = "deriving hack, should not be public", issue = "none")]
pub struct AssertParamIsEq<T: Eq + ?Sized> {
_field: crate::marker::PhantomData<T>,
}
2016-08-26 16:23:42 +00:00
2015-02-06 02:57:55 +00:00
/// 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, Hash)]
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
pub enum Ordering {
/// An ordering where a compared value is less than another.
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
Less = -1,
/// An ordering where a compared value is equal to another.
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
Equal = 0,
/// An ordering where a compared value is greater than another.
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
Greater = 1,
}
2013-03-02 03:07:12 +00:00
impl Ordering {
/// Returns `true` if the ordering is the `Equal` variant.
///
/// # Examples
///
/// ```
/// use std::cmp::Ordering;
///
/// assert_eq!(Ordering::Less.is_eq(), false);
/// assert_eq!(Ordering::Equal.is_eq(), true);
/// assert_eq!(Ordering::Greater.is_eq(), false);
/// ```
#[inline]
#[must_use]
2021-04-24 16:45:20 +00:00
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
#[stable(feature = "ordering_helpers", since = "1.53.0")]
pub const fn is_eq(self) -> bool {
matches!(self, Equal)
}
/// Returns `true` if the ordering is not the `Equal` variant.
///
/// # Examples
///
/// ```
/// use std::cmp::Ordering;
///
/// assert_eq!(Ordering::Less.is_ne(), true);
/// assert_eq!(Ordering::Equal.is_ne(), false);
/// assert_eq!(Ordering::Greater.is_ne(), true);
/// ```
#[inline]
#[must_use]
2021-04-24 16:45:20 +00:00
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
#[stable(feature = "ordering_helpers", since = "1.53.0")]
pub const fn is_ne(self) -> bool {
!matches!(self, Equal)
}
/// Returns `true` if the ordering is the `Less` variant.
///
/// # Examples
///
/// ```
/// use std::cmp::Ordering;
///
/// assert_eq!(Ordering::Less.is_lt(), true);
/// assert_eq!(Ordering::Equal.is_lt(), false);
/// assert_eq!(Ordering::Greater.is_lt(), false);
/// ```
#[inline]
#[must_use]
2021-04-24 16:45:20 +00:00
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
#[stable(feature = "ordering_helpers", since = "1.53.0")]
pub const fn is_lt(self) -> bool {
matches!(self, Less)
}
/// Returns `true` if the ordering is the `Greater` variant.
///
/// # Examples
///
/// ```
/// use std::cmp::Ordering;
///
/// assert_eq!(Ordering::Less.is_gt(), false);
/// assert_eq!(Ordering::Equal.is_gt(), false);
/// assert_eq!(Ordering::Greater.is_gt(), true);
/// ```
#[inline]
#[must_use]
2021-04-24 16:45:20 +00:00
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
#[stable(feature = "ordering_helpers", since = "1.53.0")]
pub const fn is_gt(self) -> bool {
matches!(self, Greater)
}
/// Returns `true` if the ordering is either the `Less` or `Equal` variant.
///
/// # Examples
///
/// ```
/// use std::cmp::Ordering;
///
/// assert_eq!(Ordering::Less.is_le(), true);
/// assert_eq!(Ordering::Equal.is_le(), true);
/// assert_eq!(Ordering::Greater.is_le(), false);
/// ```
#[inline]
#[must_use]
2021-04-24 16:45:20 +00:00
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
#[stable(feature = "ordering_helpers", since = "1.53.0")]
pub const fn is_le(self) -> bool {
!matches!(self, Greater)
}
/// Returns `true` if the ordering is either the `Greater` or `Equal` variant.
///
/// # Examples
///
/// ```
/// use std::cmp::Ordering;
///
/// assert_eq!(Ordering::Less.is_ge(), false);
/// assert_eq!(Ordering::Equal.is_ge(), true);
/// assert_eq!(Ordering::Greater.is_ge(), true);
/// ```
#[inline]
#[must_use]
2021-04-24 16:45:20 +00:00
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
#[stable(feature = "ordering_helpers", since = "1.53.0")]
pub const fn is_ge(self) -> bool {
!matches!(self, Less)
}
/// Reverses the `Ordering`.
///
2015-02-06 02:57:55 +00:00
/// * `Less` becomes `Greater`.
/// * `Greater` becomes `Less`.
/// * `Equal` becomes `Equal`.
///
2015-02-06 02:57:55 +00:00
/// # Examples
///
2015-02-06 02:57:55 +00:00
/// 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:
///
/// ```
/// let data: &mut [_] = &mut [2, 10, 5, 8];
///
/// // sort the array from largest to smallest.
/// data.sort_by(|a, b| a.cmp(b).reverse());
///
/// let b: &mut [_] = &mut [10, 8, 5, 2];
2014-08-06 09:59:40 +00:00
/// assert!(data == b);
/// ```
#[inline]
#[must_use]
#[rustc_const_stable(feature = "const_ordering", since = "1.48.0")]
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
pub const fn reverse(self) -> Ordering {
match self {
Less => Greater,
Equal => Equal,
Greater => Less,
}
}
2016-10-09 08:46:11 +00:00
2016-10-10 16:54:37 +00:00
/// Chains two orderings.
2016-10-09 12:10:56 +00:00
///
2016-10-09 08:46:11 +00:00
/// Returns `self` when it's not `Equal`. Otherwise returns `other`.
2020-01-29 12:32:37 +00:00
///
2016-10-09 08:46:11 +00:00
/// # Examples
///
/// ```
/// use std::cmp::Ordering;
///
2016-10-27 21:31:10 +00:00
/// let result = Ordering::Equal.then(Ordering::Less);
2016-10-09 08:46:11 +00:00
/// assert_eq!(result, Ordering::Less);
///
2016-10-27 21:31:10 +00:00
/// let result = Ordering::Less.then(Ordering::Equal);
2016-10-09 08:46:11 +00:00
/// assert_eq!(result, Ordering::Less);
///
2016-10-27 21:31:10 +00:00
/// let result = Ordering::Less.then(Ordering::Greater);
2016-10-09 08:46:11 +00:00
/// assert_eq!(result, Ordering::Less);
///
2016-10-27 21:31:10 +00:00
/// let result = Ordering::Equal.then(Ordering::Equal);
2016-10-09 08:46:11 +00:00
/// assert_eq!(result, Ordering::Equal);
///
2016-10-16 18:24:20 +00:00
/// let x: (i64, i64, i64) = (1, 2, 7);
/// let y: (i64, i64, i64) = (1, 5, 3);
2016-10-27 21:31:10 +00:00
/// let result = x.0.cmp(&y.0).then(x.1.cmp(&y.1)).then(x.2.cmp(&y.2));
2016-10-09 08:46:11 +00:00
///
/// assert_eq!(result, Ordering::Less);
/// ```
#[inline]
#[must_use]
#[rustc_const_stable(feature = "const_ordering", since = "1.48.0")]
#[stable(feature = "ordering_chaining", since = "1.17.0")]
pub const fn then(self, other: Ordering) -> Ordering {
2016-10-09 08:46:11 +00:00
match self {
Equal => other,
_ => self,
}
}
2016-10-10 16:54:37 +00:00
/// Chains the ordering with the given function.
2016-10-09 12:10:56 +00:00
///
2016-10-09 08:46:11 +00:00
/// Returns `self` when it's not `Equal`. Otherwise calls `f` and returns
/// the result.
2016-10-09 12:10:56 +00:00
///
2016-10-09 08:46:11 +00:00
/// # Examples
///
/// ```
/// use std::cmp::Ordering;
///
2016-10-27 21:31:10 +00:00
/// let result = Ordering::Equal.then_with(|| Ordering::Less);
2016-10-09 08:46:11 +00:00
/// assert_eq!(result, Ordering::Less);
///
2016-10-27 21:31:10 +00:00
/// let result = Ordering::Less.then_with(|| Ordering::Equal);
2016-10-09 08:46:11 +00:00
/// assert_eq!(result, Ordering::Less);
///
2016-10-27 21:31:10 +00:00
/// let result = Ordering::Less.then_with(|| Ordering::Greater);
2016-10-09 08:46:11 +00:00
/// assert_eq!(result, Ordering::Less);
///
2016-10-27 21:31:10 +00:00
/// let result = Ordering::Equal.then_with(|| Ordering::Equal);
2016-10-09 08:46:11 +00:00
/// assert_eq!(result, Ordering::Equal);
///
2016-10-16 18:24:20 +00:00
/// let x: (i64, i64, i64) = (1, 2, 7);
2021-01-17 15:11:48 +00:00
/// let y: (i64, i64, i64) = (1, 5, 3);
2016-10-27 21:31:10 +00:00
/// let result = x.0.cmp(&y.0).then_with(|| x.1.cmp(&y.1)).then_with(|| x.2.cmp(&y.2));
2016-10-09 08:46:11 +00:00
///
/// assert_eq!(result, Ordering::Less);
/// ```
#[inline]
#[must_use]
#[stable(feature = "ordering_chaining", since = "1.17.0")]
2016-10-27 21:31:10 +00:00
pub fn then_with<F: FnOnce() -> Ordering>(self, f: F) -> Ordering {
2016-10-09 08:46:11 +00:00
match self {
Equal => f(),
_ => self,
}
}
}
/// A helper struct for reverse ordering.
///
2020-01-29 12:32:37 +00:00
/// This struct is a helper to be used with functions like [`Vec::sort_by_key`] and
/// can be used to reverse order a part of a key.
///
2020-01-29 12:32:37 +00:00
/// [`Vec::sort_by_key`]: ../../std/vec/struct.Vec.html#method.sort_by_key
///
/// # Examples
///
/// ```
/// use std::cmp::Reverse;
///
/// let mut v = vec![1, 2, 3, 4, 5, 6];
2017-03-22 08:04:42 +00:00
/// v.sort_by_key(|&num| (num > 3, Reverse(num)));
/// assert_eq!(v, vec![3, 2, 1, 6, 5, 4]);
/// ```
#[derive(PartialEq, Eq, Debug, Copy, Clone, Default, Hash)]
2017-06-08 15:34:22 +00:00
#[stable(feature = "reverse_cmp_key", since = "1.19.0")]
#[repr(transparent)]
pub struct Reverse<T>(#[stable(feature = "reverse_cmp_key", since = "1.19.0")] pub T);
2017-06-08 15:34:22 +00:00
#[stable(feature = "reverse_cmp_key", since = "1.19.0")]
2017-03-22 13:16:41 +00:00
impl<T: PartialOrd> PartialOrd for Reverse<T> {
#[inline]
fn partial_cmp(&self, other: &Reverse<T>) -> Option<Ordering> {
other.0.partial_cmp(&self.0)
}
#[inline]
2019-12-22 22:42:04 +00:00
fn lt(&self, other: &Self) -> bool {
other.0 < self.0
}
#[inline]
2019-12-22 22:42:04 +00:00
fn le(&self, other: &Self) -> bool {
other.0 <= self.0
}
#[inline]
2019-12-22 22:42:04 +00:00
fn gt(&self, other: &Self) -> bool {
other.0 > self.0
}
#[inline]
2019-12-22 22:42:04 +00:00
fn ge(&self, other: &Self) -> bool {
other.0 >= self.0
}
}
2017-06-08 15:34:22 +00:00
#[stable(feature = "reverse_cmp_key", since = "1.19.0")]
2017-03-22 13:16:41 +00:00
impl<T: Ord> Ord for Reverse<T> {
#[inline]
fn cmp(&self, other: &Reverse<T>) -> Ordering {
other.0.cmp(&self.0)
}
}
2015-02-06 02:57:55 +00:00
/// 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 asymmetric: exactly one of `a < b`, `a == b` or `a > b` is true; and
2015-02-06 02:57:55 +00:00
/// - 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 on structs, it will produce a
/// [lexicographic](https://en.wikipedia.org/wiki/Lexicographic_order) ordering based on the top-to-bottom declaration order of the struct's members.
/// When `derive`d on enums, variants are ordered by their top-to-bottom discriminant order.
///
/// ## Lexicographical comparison
///
/// Lexicographical comparison is an operation with the following properties:
/// - Two sequences are compared element by element.
/// - The first mismatching element defines which sequence is lexicographically less or greater than the other.
/// - If one sequence is a prefix of another, the shorter sequence is lexicographically less than the other.
/// - If two sequence have equivalent elements and are of the same length, then the sequences are lexicographically equal.
/// - An empty sequence is lexicographically less than any non-empty sequence.
/// - Two empty sequences are lexicographically equal.
///
/// ## How can I implement `Ord`?
///
2020-01-29 12:32:37 +00:00
/// `Ord` requires that the type also be [`PartialOrd`] and [`Eq`] (which requires [`PartialEq`]).
///
2020-01-29 12:32:37 +00:00
/// Then you must define an implementation for [`cmp`]. You may find it useful to use
/// [`cmp`] on your type's fields.
///
2020-01-29 12:32:37 +00:00
/// Implementations of [`PartialEq`], [`PartialOrd`], and `Ord` *must*
/// agree with each other. That is, `a.cmp(b) == Ordering::Equal` if
2018-12-30 00:14:06 +00:00
/// and only if `a == b` and `Some(a.cmp(b)) == a.partial_cmp(b)` for
/// all `a` and `b`. It's easy to accidentally make them disagree by
/// deriving some of the traits and manually implementing others.
///
/// 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: &Self) -> Ordering {
/// self.height.cmp(&other.height)
/// }
/// }
///
/// impl PartialOrd for Person {
/// fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
/// Some(self.cmp(other))
/// }
/// }
///
/// impl PartialEq for Person {
/// fn eq(&self, other: &Self) -> bool {
/// self.height == other.height
/// }
/// }
/// ```
2020-01-29 12:32:37 +00:00
///
/// [`cmp`]: Ord::cmp
2018-04-25 18:10:58 +00:00
#[doc(alias = "<")]
#[doc(alias = ">")]
#[doc(alias = "<=")]
#[doc(alias = ">=")]
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-05 02:39:02 +00:00
pub trait Ord: Eq + PartialOrd<Self> {
2020-01-29 12:32:37 +00:00
/// This method returns an [`Ordering`] between `self` and `other`.
2015-02-06 02:57:55 +00:00
///
/// By convention, `self.cmp(&other)` returns the ordering matching the expression
/// `self <operator> other` if true.
2014-10-30 01:11:16 +00:00
///
2015-02-06 02:57:55 +00:00
/// # Examples
2014-10-30 01:11:16 +00:00
///
/// ```
2015-02-06 02:57:55 +00:00
/// use std::cmp::Ordering;
///
2015-02-06 02:57:55 +00:00
/// assert_eq!(5.cmp(&10), Ordering::Less);
/// assert_eq!(10.cmp(&5), Ordering::Greater);
/// assert_eq!(5.cmp(&5), Ordering::Equal);
2014-10-30 01:11:16 +00:00
/// ```
#[must_use]
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
fn cmp(&self, other: &Self) -> Ordering;
/// Compares and returns the maximum of two values.
///
/// Returns the second argument if the comparison determines them to be equal.
///
/// # Examples
///
/// ```
/// assert_eq!(2, 1.max(2));
/// assert_eq!(2, 2.max(2));
/// ```
#[stable(feature = "ord_max_min", since = "1.21.0")]
2018-08-09 09:27:48 +00:00
#[inline]
#[must_use]
fn max(self, other: Self) -> Self
2019-12-22 22:42:04 +00:00
where
Self: Sized,
{
max_by(self, other, Ord::cmp)
}
/// Compares and returns the minimum of two values.
///
/// Returns the first argument if the comparison determines them to be equal.
///
/// # Examples
///
/// ```
/// assert_eq!(1, 1.min(2));
/// assert_eq!(2, 2.min(2));
/// ```
#[stable(feature = "ord_max_min", since = "1.21.0")]
2018-08-09 09:27:48 +00:00
#[inline]
#[must_use]
fn min(self, other: Self) -> Self
2019-12-22 22:42:04 +00:00
where
Self: Sized,
{
min_by(self, other, Ord::cmp)
}
2019-03-09 18:16:54 +00:00
/// Restrict a value to a certain interval.
///
/// Returns `max` if `self` is greater than `max`, and `min` if `self` is
/// less than `min`. Otherwise this returns `self`.
///
/// # Panics
///
/// Panics if `min > max`.
2019-03-09 18:16:54 +00:00
///
/// # Examples
///
/// ```
/// assert!((-3).clamp(-2, 1) == -2);
/// assert!(0.clamp(-2, 1) == 0);
/// assert!(2.clamp(-2, 1) == 1);
/// ```
#[must_use]
#[stable(feature = "clamp", since = "1.50.0")]
2019-03-09 18:16:54 +00:00
fn clamp(self, min: Self, max: Self) -> Self
2019-12-22 22:42:04 +00:00
where
Self: Sized,
{
2019-03-09 18:16:54 +00:00
assert!(min <= max);
if self < min {
min
} else if self > max {
2019-03-09 18:16:54 +00:00
max
} else {
self
}
}
2014-10-30 01:11:16 +00:00
}
/// Derive macro generating an impl of the trait `Ord`.
#[rustc_builtin_macro]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow_internal_unstable(core_intrinsics)]
2019-12-22 22:42:04 +00:00
pub macro Ord($item:item) {
/* compiler built-in */
}
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl Eq for Ordering {}
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl Ord for Ordering {
#[inline]
fn cmp(&self, other: &Ordering) -> Ordering {
(*self as i32).cmp(&(*other as i32))
}
}
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd for Ordering {
#[inline]
fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
(*self as i32).partial_cmp(&(*other as i32))
}
}
/// Trait for values that can be compared for a sort-order.
///
/// The comparison must satisfy, for all `a`, `b` and `c`:
///
/// - asymmetry: if `a < b` then `!(a > b)`, as well as `a > b` implying `!(a < b)`; and
2015-02-06 02:57:55 +00:00
/// - transitivity: `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
///
2015-02-06 02:57:55 +00:00
/// Note that these requirements mean that the trait itself must be implemented symmetrically and
/// 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 on structs, it will produce a
/// lexicographic ordering based on the top-to-bottom declaration order of the struct's members.
/// When `derive`d on enums, variants are ordered by their top-to-bottom discriminant order.
///
2016-12-29 22:21:07 +00:00
/// ## How can I implement `PartialOrd`?
///
2020-01-29 12:32:37 +00:00
/// `PartialOrd` only requires implementation of the [`partial_cmp`] method, with the others
/// generated from default implementations.
///
2015-02-06 02:57:55 +00:00
/// 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).
///
2020-01-29 12:32:37 +00:00
/// `PartialOrd` requires your type to be [`PartialEq`].
///
2020-01-29 12:32:37 +00:00
/// Implementations of [`PartialEq`], `PartialOrd`, and [`Ord`] *must* agree with each other. It's
/// easy to accidentally make them disagree by deriving some of the traits and manually
/// implementing others.
///
2020-01-29 12:32:37 +00:00
/// 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 {
2020-09-22 21:36:08 +00:00
/// fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
/// Some(self.cmp(other))
/// }
/// }
///
/// impl Ord for Person {
2020-09-22 21:36:08 +00:00
/// fn cmp(&self, other: &Self) -> Ordering {
/// self.height.cmp(&other.height)
/// }
/// }
///
/// impl PartialEq for Person {
2020-09-22 21:36:08 +00:00
/// fn eq(&self, other: &Self) -> bool {
/// self.height == other.height
/// }
/// }
/// ```
///
2020-01-29 12:32:37 +00:00
/// 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: &Self) -> Option<Ordering> {
/// self.height.partial_cmp(&other.height)
/// }
/// }
///
/// impl PartialEq for Person {
/// fn eq(&self, other: &Self) -> bool {
/// self.height == other.height
/// }
/// }
/// ```
2016-03-14 15:43:55 +00:00
///
/// # Examples
///
/// ```
/// let x : u32 = 0;
/// let y : u32 = 1;
///
/// assert_eq!(x < y, true);
/// assert_eq!(x.lt(&y), true);
/// ```
2020-01-29 12:32:37 +00:00
///
/// [`partial_cmp`]: PartialOrd::partial_cmp
/// [`cmp`]: Ord::cmp
#[lang = "partial_ord"]
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
2018-04-25 18:10:58 +00:00
#[doc(alias = ">")]
#[doc(alias = "<")]
#[doc(alias = "<=")]
#[doc(alias = ">=")]
#[rustc_on_unimplemented(
2019-12-22 22:42:04 +00:00
message = "can't compare `{Self}` with `{Rhs}`",
label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`"
)]
pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
2015-02-06 02:57:55 +00:00
/// 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 = f64::NAN.partial_cmp(&1.0);
2015-02-06 02:57:55 +00:00
/// assert_eq!(result, None);
/// ```
#[must_use]
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
2014-10-30 01:11:16 +00:00
/// This method tests less than (for `self` and `other`) and is used by the `<` operator.
2015-02-06 02:57:55 +00:00
///
/// # Examples
///
/// ```
/// let result = 1.0 < 2.0;
/// assert_eq!(result, true);
///
/// let result = 2.0 < 1.0;
/// assert_eq!(result, false);
/// ```
2014-10-30 01:11:16 +00:00
#[inline]
#[must_use]
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
fn lt(&self, other: &Rhs) -> bool {
matches!(self.partial_cmp(other), Some(Less))
2014-10-30 01:11:16 +00:00
}
2015-02-06 02:57:55 +00:00
/// 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);
/// ```
2014-10-30 01:11:16 +00:00
#[inline]
#[must_use]
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
fn le(&self, other: &Rhs) -> bool {
// Pattern `Some(Less | Eq)` optimizes worse than negating `None | Some(Greater)`.
// FIXME: The root cause was fixed upstream in LLVM with:
// https://github.com/llvm/llvm-project/commit/9bad7de9a3fb844f1ca2965f35d0c2a3d1e11775
// Revert this workaround once support for LLVM 12 gets dropped.
!matches!(self.partial_cmp(other), None | Some(Greater))
2014-10-30 01:11:16 +00:00
}
2015-02-06 02:57:55 +00:00
/// 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);
/// ```
2014-10-30 01:11:16 +00:00
#[inline]
#[must_use]
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
fn gt(&self, other: &Rhs) -> bool {
matches!(self.partial_cmp(other), Some(Greater))
2014-10-30 01:11:16 +00:00
}
2015-02-06 02:57:55 +00:00
/// 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);
/// ```
2014-10-30 01:11:16 +00:00
#[inline]
#[must_use]
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
fn ge(&self, other: &Rhs) -> bool {
matches!(self.partial_cmp(other), Some(Greater | Equal))
2014-10-30 01:11:16 +00:00
}
}
/// Derive macro generating an impl of the trait `PartialOrd`.
#[rustc_builtin_macro]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow_internal_unstable(core_intrinsics)]
2019-12-22 22:42:04 +00:00
pub macro PartialOrd($item:item) {
/* compiler built-in */
}
/// Compares and returns the minimum of two values.
2015-02-06 02:57:55 +00:00
///
/// Returns the first argument if the comparison determines them to be equal.
///
2020-01-29 12:32:37 +00:00
/// Internally uses an alias to [`Ord::min`].
///
2015-02-06 02:57:55 +00:00
/// # Examples
///
/// ```
/// use std::cmp;
///
/// assert_eq!(1, cmp::min(1, 2));
/// assert_eq!(2, cmp::min(2, 2));
/// ```
#[inline]
#[must_use]
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn min<T: Ord>(v1: T, v2: T) -> T {
v1.min(v2)
}
/// Returns the minimum of two values with respect to the specified comparison function.
///
/// Returns the first argument if the comparison determines them to be equal.
///
/// # Examples
///
/// ```
/// use std::cmp;
///
/// assert_eq!(cmp::min_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), 1);
/// assert_eq!(cmp::min_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), -2);
/// ```
#[inline]
#[must_use]
#[stable(feature = "cmp_min_max_by", since = "1.53.0")]
pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
match compare(&v1, &v2) {
Ordering::Less | Ordering::Equal => v1,
Ordering::Greater => v2,
}
}
/// Returns the element that gives the minimum value from the specified function.
///
/// Returns the first argument if the comparison determines them to be equal.
///
/// # Examples
///
/// ```
/// use std::cmp;
///
/// assert_eq!(cmp::min_by_key(-2, 1, |x: &i32| x.abs()), 1);
/// assert_eq!(cmp::min_by_key(-2, 2, |x: &i32| x.abs()), -2);
/// ```
#[inline]
#[must_use]
#[stable(feature = "cmp_min_max_by", since = "1.53.0")]
pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
min_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2)))
}
/// Compares and returns the maximum of two values.
2015-02-06 02:57:55 +00:00
///
/// Returns the second argument if the comparison determines them to be equal.
///
2020-01-29 12:32:37 +00:00
/// Internally uses an alias to [`Ord::max`].
///
2015-02-06 02:57:55 +00:00
/// # Examples
///
/// ```
/// use std::cmp;
///
/// assert_eq!(2, cmp::max(1, 2));
/// assert_eq!(2, cmp::max(2, 2));
/// ```
#[inline]
#[must_use]
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn max<T: Ord>(v1: T, v2: T) -> T {
v1.max(v2)
}
2013-03-02 03:07:12 +00:00
/// Returns the maximum of two values with respect to the specified comparison function.
///
/// Returns the second argument if the comparison determines them to be equal.
///
/// # Examples
///
/// ```
/// use std::cmp;
///
/// assert_eq!(cmp::max_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), -2);
/// assert_eq!(cmp::max_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), 2);
/// ```
#[inline]
#[must_use]
#[stable(feature = "cmp_min_max_by", since = "1.53.0")]
pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
match compare(&v1, &v2) {
Ordering::Less | Ordering::Equal => v2,
Ordering::Greater => v1,
}
}
/// Returns the element that gives the maximum value from the specified function.
///
/// Returns the second argument if the comparison determines them to be equal.
///
/// # Examples
///
/// ```
/// use std::cmp;
///
/// assert_eq!(cmp::max_by_key(-2, 1, |x: &i32| x.abs()), -2);
/// assert_eq!(cmp::max_by_key(-2, 2, |x: &i32| x.abs()), 2);
/// ```
#[inline]
#[must_use]
#[stable(feature = "cmp_min_max_by", since = "1.53.0")]
pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
max_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2)))
}
// Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
mod impls {
2019-12-22 22:42:04 +00:00
use crate::cmp::Ordering::{self, Equal, Greater, Less};
use crate::hint::unreachable_unchecked;
macro_rules! partial_eq_impl {
($($t:ty)*) => ($(
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for $t {
#[inline]
fn eq(&self, other: &$t) -> bool { (*self) == (*other) }
#[inline]
fn ne(&self, other: &$t) -> bool { (*self) != (*other) }
}
)*)
}
2014-05-13 04:02:27 +00:00
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for () {
2014-05-13 04:02:27 +00:00
#[inline]
2019-12-22 22:42:04 +00:00
fn eq(&self, _other: &()) -> bool {
true
}
2014-05-13 04:02:27 +00:00
#[inline]
2019-12-22 22:42:04 +00:00
fn ne(&self, _other: &()) -> bool {
false
}
2014-05-13 04:02:27 +00:00
}
partial_eq_impl! {
bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64
}
macro_rules! eq_impl {
($($t:ty)*) => ($(
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl Eq for $t {}
)*)
}
eq_impl! { () bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
macro_rules! partial_ord_impl {
($($t:ty)*) => ($(
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd for $t {
#[inline]
fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
match (self <= other, self >= other) {
(false, false) => None,
(false, true) => Some(Greater),
(true, false) => Some(Less),
(true, true) => Some(Equal),
}
}
#[inline]
fn lt(&self, other: &$t) -> bool { (*self) < (*other) }
#[inline]
fn le(&self, other: &$t) -> bool { (*self) <= (*other) }
#[inline]
fn ge(&self, other: &$t) -> bool { (*self) >= (*other) }
#[inline]
fn gt(&self, other: &$t) -> bool { (*self) > (*other) }
}
)*)
}
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd for () {
2014-05-13 04:02:27 +00:00
#[inline]
fn partial_cmp(&self, _: &()) -> Option<Ordering> {
Some(Equal)
}
2014-05-13 04:02:27 +00:00
}
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd for bool {
#[inline]
fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
Some(self.cmp(other))
}
}
partial_ord_impl! { f32 f64 }
macro_rules! ord_impl {
($($t:ty)*) => ($(
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd for $t {
#[inline]
fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
Some(self.cmp(other))
}
#[inline]
fn lt(&self, other: &$t) -> bool { (*self) < (*other) }
#[inline]
fn le(&self, other: &$t) -> bool { (*self) <= (*other) }
#[inline]
fn ge(&self, other: &$t) -> bool { (*self) >= (*other) }
#[inline]
fn gt(&self, other: &$t) -> bool { (*self) > (*other) }
}
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl Ord for $t {
#[inline]
fn cmp(&self, other: &$t) -> Ordering {
// The order here is important to generate more optimal assembly.
// See <https://github.com/rust-lang/rust/issues/63758> for more info.
if *self < *other { Less }
else if *self == *other { Equal }
else { Greater }
}
}
)*)
}
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl Ord for () {
2014-05-13 04:02:27 +00:00
#[inline]
2019-12-22 22:42:04 +00:00
fn cmp(&self, _other: &()) -> Ordering {
Equal
}
2014-05-13 04:02:27 +00:00
}
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl Ord for bool {
#[inline]
fn cmp(&self, other: &bool) -> Ordering {
// Casting to i8's and converting the difference to an Ordering generates
// more optimal assembly.
// See <https://github.com/rust-lang/rust/issues/66780> for more info.
match (*self as i8) - (*other as i8) {
-1 => Less,
0 => Equal,
1 => Greater,
// SAFETY: bool as i8 returns 0 or 1, so the difference can't be anything else
_ => unsafe { unreachable_unchecked() },
}
}
}
ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
#[unstable(feature = "never_type", issue = "35121")]
2016-08-18 17:08:25 +00:00
impl PartialEq for ! {
fn eq(&self, _: &!) -> bool {
*self
}
}
2016-08-01 04:56:43 +00:00
#[unstable(feature = "never_type", issue = "35121")]
2016-08-18 17:08:25 +00:00
impl Eq for ! {}
2016-08-01 04:56:43 +00:00
#[unstable(feature = "never_type", issue = "35121")]
2016-08-18 17:08:25 +00:00
impl PartialOrd for ! {
fn partial_cmp(&self, _: &!) -> Option<Ordering> {
*self
2016-08-01 04:56:43 +00:00
}
}
#[unstable(feature = "never_type", issue = "35121")]
2016-08-18 17:08:25 +00:00
impl Ord for ! {
fn cmp(&self, _: &!) -> Ordering {
*self
}
}
2016-08-01 04:56:43 +00:00
// & pointers
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
2019-12-22 22:42:04 +00:00
impl<A: ?Sized, B: ?Sized> PartialEq<&B> for &A
where
A: PartialEq<B>,
{
2014-10-30 01:11:16 +00:00
#[inline]
2019-12-22 22:42:04 +00:00
fn eq(&self, other: &&B) -> bool {
PartialEq::eq(*self, *other)
}
2014-10-30 01:11:16 +00:00
#[inline]
2019-12-22 22:42:04 +00:00
fn ne(&self, other: &&B) -> bool {
PartialEq::ne(*self, *other)
}
2014-10-30 01:11:16 +00:00
}
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
2019-12-22 22:42:04 +00:00
impl<A: ?Sized, B: ?Sized> PartialOrd<&B> for &A
where
A: PartialOrd<B>,
{
2014-10-30 01:11:16 +00:00
#[inline]
fn partial_cmp(&self, other: &&B) -> Option<Ordering> {
2014-10-30 01:11:16 +00:00
PartialOrd::partial_cmp(*self, *other)
}
#[inline]
2019-12-22 22:42:04 +00:00
fn lt(&self, other: &&B) -> bool {
PartialOrd::lt(*self, *other)
}
2014-10-30 01:11:16 +00:00
#[inline]
2019-12-22 22:42:04 +00:00
fn le(&self, other: &&B) -> bool {
PartialOrd::le(*self, *other)
}
2014-10-30 01:11:16 +00:00
#[inline]
2019-12-22 22:42:04 +00:00
fn gt(&self, other: &&B) -> bool {
PartialOrd::gt(*self, *other)
}
#[inline]
2019-12-22 22:42:04 +00:00
fn ge(&self, other: &&B) -> bool {
PartialOrd::ge(*self, *other)
}
2014-10-30 01:11:16 +00:00
}
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
2019-12-22 22:42:04 +00:00
impl<A: ?Sized> Ord for &A
where
A: Ord,
{
2014-10-30 01:11:16 +00:00
#[inline]
2019-12-22 22:42:04 +00:00
fn cmp(&self, other: &Self) -> Ordering {
Ord::cmp(*self, *other)
}
2014-10-30 01:11:16 +00:00
}
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: ?Sized> Eq for &A where A: Eq {}
2014-10-30 01:11:16 +00:00
// &mut pointers
2014-10-30 01:11:16 +00:00
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
2019-12-22 22:42:04 +00:00
impl<A: ?Sized, B: ?Sized> PartialEq<&mut B> for &mut A
where
A: PartialEq<B>,
{
2014-10-30 01:11:16 +00:00
#[inline]
2019-12-22 22:42:04 +00:00
fn eq(&self, other: &&mut B) -> bool {
PartialEq::eq(*self, *other)
}
2014-10-30 01:11:16 +00:00
#[inline]
2019-12-22 22:42:04 +00:00
fn ne(&self, other: &&mut B) -> bool {
PartialEq::ne(*self, *other)
}
2014-10-30 01:11:16 +00:00
}
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
2019-12-22 22:42:04 +00:00
impl<A: ?Sized, B: ?Sized> PartialOrd<&mut B> for &mut A
where
A: PartialOrd<B>,
{
2014-10-30 01:11:16 +00:00
#[inline]
fn partial_cmp(&self, other: &&mut B) -> Option<Ordering> {
2014-10-30 01:11:16 +00:00
PartialOrd::partial_cmp(*self, *other)
}
#[inline]
2019-12-22 22:42:04 +00:00
fn lt(&self, other: &&mut B) -> bool {
PartialOrd::lt(*self, *other)
}
2014-10-30 01:11:16 +00:00
#[inline]
2019-12-22 22:42:04 +00:00
fn le(&self, other: &&mut B) -> bool {
PartialOrd::le(*self, *other)
}
2014-10-30 01:11:16 +00:00
#[inline]
2019-12-22 22:42:04 +00:00
fn gt(&self, other: &&mut B) -> bool {
PartialOrd::gt(*self, *other)
}
#[inline]
2019-12-22 22:42:04 +00:00
fn ge(&self, other: &&mut B) -> bool {
PartialOrd::ge(*self, *other)
}
2014-10-30 01:11:16 +00:00
}
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
2019-12-22 22:42:04 +00:00
impl<A: ?Sized> Ord for &mut A
where
A: Ord,
{
2014-10-30 01:11:16 +00:00
#[inline]
2019-12-22 22:42:04 +00:00
fn cmp(&self, other: &Self) -> Ordering {
Ord::cmp(*self, *other)
}
2014-10-30 01:11:16 +00:00
}
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: ?Sized> Eq for &mut A where A: Eq {}
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
2019-12-22 22:42:04 +00:00
impl<A: ?Sized, B: ?Sized> PartialEq<&mut B> for &A
where
A: PartialEq<B>,
{
#[inline]
2019-12-22 22:42:04 +00:00
fn eq(&self, other: &&mut B) -> bool {
PartialEq::eq(*self, *other)
}
#[inline]
2019-12-22 22:42:04 +00:00
fn ne(&self, other: &&mut B) -> bool {
PartialEq::ne(*self, *other)
}
}
2015-01-24 05:48:20 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
2019-12-22 22:42:04 +00:00
impl<A: ?Sized, B: ?Sized> PartialEq<&B> for &mut A
where
A: PartialEq<B>,
{
#[inline]
2019-12-22 22:42:04 +00:00
fn eq(&self, other: &&B) -> bool {
PartialEq::eq(*self, *other)
}
#[inline]
2019-12-22 22:42:04 +00:00
fn ne(&self, other: &&B) -> bool {
PartialEq::ne(*self, *other)
}
}
}