1 //! Utilities for comparing and ordering values.
3 //! This module contains various tools for comparing and ordering values. In
6 //! * [`Eq`] and [`PartialEq`] are traits that allow you to define total and
7 //! partial equality between values, respectively. Implementing them overloads
8 //! the `==` and `!=` operators.
9 //! * [`Ord`] and [`PartialOrd`] are traits that allow you to define total and
10 //! partial orderings between values, respectively. Implementing them overloads
11 //! the `<`, `<=`, `>`, and `>=` operators.
12 //! * [`Ordering`] is an enum returned by the main functions of [`Ord`] and
13 //! [`PartialOrd`], and describes an ordering.
14 //! * [`Reverse`] is a struct that allows you to easily reverse an ordering.
15 //! * [`max`] and [`min`] are functions that build off of [`Ord`] and allow you
16 //! to find the maximum or minimum of two values.
18 //! For more details, see the respective documentation of each item in the list.
23 #![stable(feature = "rust1", since = "1.0.0")]
25 use crate::marker::Destruct;
27 use self::Ordering::*;
29 /// Trait for equality comparisons which are [partial equivalence
30 /// relations](https://en.wikipedia.org/wiki/Partial_equivalence_relation).
32 /// `x.eq(y)` can also be written `x == y`, and `x.ne(y)` can be written `x != y`.
33 /// We use the easier-to-read infix notation in the remainder of this documentation.
35 /// This trait allows for partial equality, for types that do not have a full
36 /// equivalence relation. For example, in floating point numbers `NaN != NaN`,
37 /// so floating point types implement `PartialEq` but not [`trait@Eq`].
39 /// Implementations must ensure that `eq` and `ne` are consistent with each other:
41 /// - `a != b` if and only if `!(a == b)`.
43 /// The default implementation of `ne` provides this consistency and is almost
44 /// always sufficient. It should not be overridden without very good reason.
46 /// If [`PartialOrd`] or [`Ord`] are also implemented for `Self` and `Rhs`, their methods must also
47 /// be consistent with `PartialEq` (see the documentation of those traits for the exact
48 /// requirements). It's easy to accidentally make them disagree by deriving some of the traits and
49 /// manually implementing others.
51 /// The equality relation `==` must satisfy the following conditions
52 /// (for all `a`, `b`, `c` of type `A`, `B`, `C`):
54 /// - **Symmetric**: if `A: PartialEq<B>` and `B: PartialEq<A>`, then **`a == b`
55 /// implies `b == a`**; and
57 /// - **Transitive**: if `A: PartialEq<B>` and `B: PartialEq<C>` and `A:
58 /// PartialEq<C>`, then **`a == b` and `b == c` implies `a == c`**.
60 /// Note that the `B: PartialEq<A>` (symmetric) and `A: PartialEq<C>`
61 /// (transitive) impls are not forced to exist, but these requirements apply
62 /// whenever they do exist.
66 /// This trait can be used with `#[derive]`. When `derive`d on structs, two
67 /// instances are equal if all fields are equal, and not equal if any fields
68 /// are not equal. When `derive`d on enums, two instances are equal if they
69 /// are the same variant and all fields are equal.
71 /// ## How can I implement `PartialEq`?
73 /// An example implementation for a domain in which two books are considered
74 /// the same book if their ISBN matches, even if the formats differ:
85 /// format: BookFormat,
88 /// impl PartialEq for Book {
89 /// fn eq(&self, other: &Self) -> bool {
90 /// self.isbn == other.isbn
94 /// let b1 = Book { isbn: 3, format: BookFormat::Paperback };
95 /// let b2 = Book { isbn: 3, format: BookFormat::Ebook };
96 /// let b3 = Book { isbn: 10, format: BookFormat::Paperback };
98 /// assert!(b1 == b2);
99 /// assert!(b1 != b3);
102 /// ## How can I compare two different types?
104 /// The type you can compare with is controlled by `PartialEq`'s type parameter.
105 /// For example, let's tweak our previous code a bit:
108 /// // The derive implements <BookFormat> == <BookFormat> comparisons
109 /// #[derive(PartialEq)]
110 /// enum BookFormat {
118 /// format: BookFormat,
121 /// // Implement <Book> == <BookFormat> comparisons
122 /// impl PartialEq<BookFormat> for Book {
123 /// fn eq(&self, other: &BookFormat) -> bool {
124 /// self.format == *other
128 /// // Implement <BookFormat> == <Book> comparisons
129 /// impl PartialEq<Book> for BookFormat {
130 /// fn eq(&self, other: &Book) -> bool {
131 /// *self == other.format
135 /// let b1 = Book { isbn: 3, format: BookFormat::Paperback };
137 /// assert!(b1 == BookFormat::Paperback);
138 /// assert!(BookFormat::Ebook != b1);
141 /// By changing `impl PartialEq for Book` to `impl PartialEq<BookFormat> for Book`,
142 /// we allow `BookFormat`s to be compared with `Book`s.
144 /// A comparison like the one above, which ignores some fields of the struct,
145 /// can be dangerous. It can easily lead to an unintended violation of the
146 /// requirements for a partial equivalence relation. For example, if we kept
147 /// the above implementation of `PartialEq<Book>` for `BookFormat` and added an
148 /// implementation of `PartialEq<Book>` for `Book` (either via a `#[derive]` or
149 /// via the manual implementation from the first example) then the result would
150 /// violate transitivity:
153 /// #[derive(PartialEq)]
154 /// enum BookFormat {
160 /// #[derive(PartialEq)]
163 /// format: BookFormat,
166 /// impl PartialEq<BookFormat> for Book {
167 /// fn eq(&self, other: &BookFormat) -> bool {
168 /// self.format == *other
172 /// impl PartialEq<Book> for BookFormat {
173 /// fn eq(&self, other: &Book) -> bool {
174 /// *self == other.format
179 /// let b1 = Book { isbn: 1, format: BookFormat::Paperback };
180 /// let b2 = Book { isbn: 2, format: BookFormat::Paperback };
182 /// assert!(b1 == BookFormat::Paperback);
183 /// assert!(BookFormat::Paperback == b2);
185 /// // The following should hold by transitivity but doesn't.
186 /// assert!(b1 == b2); // <-- PANICS
196 /// assert_eq!(x == y, false);
197 /// assert_eq!(x.eq(&y), false);
200 /// [`eq`]: PartialEq::eq
201 /// [`ne`]: PartialEq::ne
203 #[stable(feature = "rust1", since = "1.0.0")]
208 rustc_on_unimplemented(
209 message = "can't compare `{Self}` with `{Rhs}`",
210 label = "no implementation for `{Self} == {Rhs}`"
215 rustc_on_unimplemented(
216 message = "can't compare `{Self}` with `{Rhs}`",
217 label = "no implementation for `{Self} == {Rhs}`",
222 #[rustc_diagnostic_item = "PartialEq"]
223 pub trait PartialEq<Rhs: ?Sized = Self> {
224 /// This method tests for `self` and `other` values to be equal, and is used
227 #[stable(feature = "rust1", since = "1.0.0")]
228 fn eq(&self, other: &Rhs) -> bool;
230 /// This method tests for `!=`. The default implementation is almost always
231 /// sufficient, and should not be overridden without very good reason.
234 #[stable(feature = "rust1", since = "1.0.0")]
235 fn ne(&self, other: &Rhs) -> bool {
240 /// Derive macro generating an impl of the trait `PartialEq`.
241 #[rustc_builtin_macro]
242 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
243 #[allow_internal_unstable(core_intrinsics, structural_match)]
244 pub macro PartialEq($item:item) {
245 /* compiler built-in */
248 /// Trait for equality comparisons which are [equivalence relations](
249 /// https://en.wikipedia.org/wiki/Equivalence_relation).
251 /// This means, that in addition to `a == b` and `a != b` being strict inverses, the equality must
252 /// be (for all `a`, `b` and `c`):
254 /// - reflexive: `a == a`;
255 /// - symmetric: `a == b` implies `b == a`; and
256 /// - transitive: `a == b` and `b == c` implies `a == c`.
258 /// This property cannot be checked by the compiler, and therefore `Eq` implies
259 /// [`PartialEq`], and has no extra methods.
263 /// This trait can be used with `#[derive]`. When `derive`d, because `Eq` has
264 /// no extra methods, it is only informing the compiler that this is an
265 /// equivalence relation rather than a partial equivalence relation. Note that
266 /// the `derive` strategy requires all fields are `Eq`, which isn't
269 /// ## How can I implement `Eq`?
271 /// If you cannot use the `derive` strategy, specify that your type implements
272 /// `Eq`, which has no methods:
275 /// enum BookFormat { Paperback, Hardback, Ebook }
278 /// format: BookFormat,
280 /// impl PartialEq for Book {
281 /// fn eq(&self, other: &Self) -> bool {
282 /// self.isbn == other.isbn
285 /// impl Eq for Book {}
289 #[stable(feature = "rust1", since = "1.0.0")]
290 #[rustc_diagnostic_item = "Eq"]
291 pub trait Eq: PartialEq<Self> {
292 // this method is used solely by #[deriving] to assert
293 // that every component of a type implements #[deriving]
294 // itself, the current deriving infrastructure means doing this
295 // assertion without using a method on this trait is nearly
298 // This should never be implemented by hand.
300 #[no_coverage] // rust-lang/rust#84605
302 #[stable(feature = "rust1", since = "1.0.0")]
303 fn assert_receiver_is_total_eq(&self) {}
306 /// Derive macro generating an impl of the trait `Eq`.
307 #[rustc_builtin_macro]
308 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
309 #[allow_internal_unstable(core_intrinsics, derive_eq, structural_match, no_coverage)]
310 pub macro Eq($item:item) {
311 /* compiler built-in */
314 // FIXME: this struct is used solely by #[derive] to
315 // assert that every component of a type implements Eq.
317 // This struct should never appear in user code.
319 #[allow(missing_debug_implementations)]
320 #[unstable(feature = "derive_eq", reason = "deriving hack, should not be public", issue = "none")]
321 pub struct AssertParamIsEq<T: Eq + ?Sized> {
322 _field: crate::marker::PhantomData<T>,
325 /// An `Ordering` is the result of a comparison between two values.
330 /// use std::cmp::Ordering;
332 /// let result = 1.cmp(&2);
333 /// assert_eq!(Ordering::Less, result);
335 /// let result = 1.cmp(&1);
336 /// assert_eq!(Ordering::Equal, result);
338 /// let result = 2.cmp(&1);
339 /// assert_eq!(Ordering::Greater, result);
341 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
342 #[stable(feature = "rust1", since = "1.0.0")]
345 /// An ordering where a compared value is less than another.
346 #[stable(feature = "rust1", since = "1.0.0")]
348 /// An ordering where a compared value is equal to another.
349 #[stable(feature = "rust1", since = "1.0.0")]
351 /// An ordering where a compared value is greater than another.
352 #[stable(feature = "rust1", since = "1.0.0")]
357 /// Returns `true` if the ordering is the `Equal` variant.
362 /// use std::cmp::Ordering;
364 /// assert_eq!(Ordering::Less.is_eq(), false);
365 /// assert_eq!(Ordering::Equal.is_eq(), true);
366 /// assert_eq!(Ordering::Greater.is_eq(), false);
370 #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
371 #[stable(feature = "ordering_helpers", since = "1.53.0")]
372 pub const fn is_eq(self) -> bool {
373 matches!(self, Equal)
376 /// Returns `true` if the ordering is not the `Equal` variant.
381 /// use std::cmp::Ordering;
383 /// assert_eq!(Ordering::Less.is_ne(), true);
384 /// assert_eq!(Ordering::Equal.is_ne(), false);
385 /// assert_eq!(Ordering::Greater.is_ne(), true);
389 #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
390 #[stable(feature = "ordering_helpers", since = "1.53.0")]
391 pub const fn is_ne(self) -> bool {
392 !matches!(self, Equal)
395 /// Returns `true` if the ordering is the `Less` variant.
400 /// use std::cmp::Ordering;
402 /// assert_eq!(Ordering::Less.is_lt(), true);
403 /// assert_eq!(Ordering::Equal.is_lt(), false);
404 /// assert_eq!(Ordering::Greater.is_lt(), false);
408 #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
409 #[stable(feature = "ordering_helpers", since = "1.53.0")]
410 pub const fn is_lt(self) -> bool {
414 /// Returns `true` if the ordering is the `Greater` variant.
419 /// use std::cmp::Ordering;
421 /// assert_eq!(Ordering::Less.is_gt(), false);
422 /// assert_eq!(Ordering::Equal.is_gt(), false);
423 /// assert_eq!(Ordering::Greater.is_gt(), true);
427 #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
428 #[stable(feature = "ordering_helpers", since = "1.53.0")]
429 pub const fn is_gt(self) -> bool {
430 matches!(self, Greater)
433 /// Returns `true` if the ordering is either the `Less` or `Equal` variant.
438 /// use std::cmp::Ordering;
440 /// assert_eq!(Ordering::Less.is_le(), true);
441 /// assert_eq!(Ordering::Equal.is_le(), true);
442 /// assert_eq!(Ordering::Greater.is_le(), false);
446 #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
447 #[stable(feature = "ordering_helpers", since = "1.53.0")]
448 pub const fn is_le(self) -> bool {
449 !matches!(self, Greater)
452 /// Returns `true` if the ordering is either the `Greater` or `Equal` variant.
457 /// use std::cmp::Ordering;
459 /// assert_eq!(Ordering::Less.is_ge(), false);
460 /// assert_eq!(Ordering::Equal.is_ge(), true);
461 /// assert_eq!(Ordering::Greater.is_ge(), true);
465 #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
466 #[stable(feature = "ordering_helpers", since = "1.53.0")]
467 pub const fn is_ge(self) -> bool {
468 !matches!(self, Less)
471 /// Reverses the `Ordering`.
473 /// * `Less` becomes `Greater`.
474 /// * `Greater` becomes `Less`.
475 /// * `Equal` becomes `Equal`.
482 /// use std::cmp::Ordering;
484 /// assert_eq!(Ordering::Less.reverse(), Ordering::Greater);
485 /// assert_eq!(Ordering::Equal.reverse(), Ordering::Equal);
486 /// assert_eq!(Ordering::Greater.reverse(), Ordering::Less);
489 /// This method can be used to reverse a comparison:
492 /// let data: &mut [_] = &mut [2, 10, 5, 8];
494 /// // sort the array from largest to smallest.
495 /// data.sort_by(|a, b| a.cmp(b).reverse());
497 /// let b: &mut [_] = &mut [10, 8, 5, 2];
498 /// assert!(data == b);
502 #[rustc_const_stable(feature = "const_ordering", since = "1.48.0")]
503 #[stable(feature = "rust1", since = "1.0.0")]
504 pub const fn reverse(self) -> Ordering {
512 /// Chains two orderings.
514 /// Returns `self` when it's not `Equal`. Otherwise returns `other`.
519 /// use std::cmp::Ordering;
521 /// let result = Ordering::Equal.then(Ordering::Less);
522 /// assert_eq!(result, Ordering::Less);
524 /// let result = Ordering::Less.then(Ordering::Equal);
525 /// assert_eq!(result, Ordering::Less);
527 /// let result = Ordering::Less.then(Ordering::Greater);
528 /// assert_eq!(result, Ordering::Less);
530 /// let result = Ordering::Equal.then(Ordering::Equal);
531 /// assert_eq!(result, Ordering::Equal);
533 /// let x: (i64, i64, i64) = (1, 2, 7);
534 /// let y: (i64, i64, i64) = (1, 5, 3);
535 /// let result = x.0.cmp(&y.0).then(x.1.cmp(&y.1)).then(x.2.cmp(&y.2));
537 /// assert_eq!(result, Ordering::Less);
541 #[rustc_const_stable(feature = "const_ordering", since = "1.48.0")]
542 #[stable(feature = "ordering_chaining", since = "1.17.0")]
543 pub const fn then(self, other: Ordering) -> Ordering {
550 /// Chains the ordering with the given function.
552 /// Returns `self` when it's not `Equal`. Otherwise calls `f` and returns
558 /// use std::cmp::Ordering;
560 /// let result = Ordering::Equal.then_with(|| Ordering::Less);
561 /// assert_eq!(result, Ordering::Less);
563 /// let result = Ordering::Less.then_with(|| Ordering::Equal);
564 /// assert_eq!(result, Ordering::Less);
566 /// let result = Ordering::Less.then_with(|| Ordering::Greater);
567 /// assert_eq!(result, Ordering::Less);
569 /// let result = Ordering::Equal.then_with(|| Ordering::Equal);
570 /// assert_eq!(result, Ordering::Equal);
572 /// let x: (i64, i64, i64) = (1, 2, 7);
573 /// let y: (i64, i64, i64) = (1, 5, 3);
574 /// let result = x.0.cmp(&y.0).then_with(|| x.1.cmp(&y.1)).then_with(|| x.2.cmp(&y.2));
576 /// assert_eq!(result, Ordering::Less);
580 #[stable(feature = "ordering_chaining", since = "1.17.0")]
581 pub fn then_with<F: FnOnce() -> Ordering>(self, f: F) -> Ordering {
589 /// A helper struct for reverse ordering.
591 /// This struct is a helper to be used with functions like [`Vec::sort_by_key`] and
592 /// can be used to reverse order a part of a key.
594 /// [`Vec::sort_by_key`]: ../../std/vec/struct.Vec.html#method.sort_by_key
599 /// use std::cmp::Reverse;
601 /// let mut v = vec![1, 2, 3, 4, 5, 6];
602 /// v.sort_by_key(|&num| (num > 3, Reverse(num)));
603 /// assert_eq!(v, vec![3, 2, 1, 6, 5, 4]);
605 #[derive(PartialEq, Eq, Debug, Copy, Default, Hash)]
606 #[stable(feature = "reverse_cmp_key", since = "1.19.0")]
608 pub struct Reverse<T>(#[stable(feature = "reverse_cmp_key", since = "1.19.0")] pub T);
610 #[stable(feature = "reverse_cmp_key", since = "1.19.0")]
611 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
612 impl<T: ~const PartialOrd> const PartialOrd for Reverse<T> {
614 fn partial_cmp(&self, other: &Reverse<T>) -> Option<Ordering> {
615 other.0.partial_cmp(&self.0)
619 fn lt(&self, other: &Self) -> bool {
623 fn le(&self, other: &Self) -> bool {
627 fn gt(&self, other: &Self) -> bool {
631 fn ge(&self, other: &Self) -> bool {
636 #[stable(feature = "reverse_cmp_key", since = "1.19.0")]
637 impl<T: Ord> Ord for Reverse<T> {
639 fn cmp(&self, other: &Reverse<T>) -> Ordering {
644 #[stable(feature = "reverse_cmp_key", since = "1.19.0")]
645 impl<T: Clone> Clone for Reverse<T> {
647 fn clone(&self) -> Reverse<T> {
648 Reverse(self.0.clone())
652 fn clone_from(&mut self, other: &Self) {
653 self.0.clone_from(&other.0)
657 /// Trait for types that form a [total order](https://en.wikipedia.org/wiki/Total_order).
659 /// Implementations must be consistent with the [`PartialOrd`] implementation, and ensure
660 /// `max`, `min`, and `clamp` are consistent with `cmp`:
662 /// - `partial_cmp(a, b) == Some(cmp(a, b))`.
663 /// - `max(a, b) == max_by(a, b, cmp)` (ensured by the default implementation).
664 /// - `min(a, b) == min_by(a, b, cmp)` (ensured by the default implementation).
665 /// - For `a.clamp(min, max)`, see the [method docs](#method.clamp)
666 /// (ensured by the default implementation).
668 /// It's easy to accidentally make `cmp` and `partial_cmp` disagree by
669 /// deriving some of the traits and manually implementing others.
673 /// From the above and the requirements of `PartialOrd`, it follows that `<` defines a strict total order.
674 /// This means that for all `a`, `b` and `c`:
676 /// - exactly one of `a < b`, `a == b` or `a > b` is true; and
677 /// - `<` is transitive: `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
681 /// This trait can be used with `#[derive]`.
683 /// When `derive`d on structs, it will produce a
684 /// [lexicographic](https://en.wikipedia.org/wiki/Lexicographic_order) ordering
685 /// based on the top-to-bottom declaration order of the struct's members.
687 /// When `derive`d on enums, variants are ordered by their discriminants.
688 /// By default, the discriminant is smallest for variants at the top, and
689 /// largest for variants at the bottom. Here's an example:
692 /// #[derive(PartialEq, Eq, PartialOrd, Ord)]
698 /// assert!(E::Top < E::Bottom);
701 /// However, manually setting the discriminants can override this default
705 /// #[derive(PartialEq, Eq, PartialOrd, Ord)]
711 /// assert!(E::Bottom < E::Top);
714 /// ## Lexicographical comparison
716 /// Lexicographical comparison is an operation with the following properties:
717 /// - Two sequences are compared element by element.
718 /// - The first mismatching element defines which sequence is lexicographically less or greater than the other.
719 /// - If one sequence is a prefix of another, the shorter sequence is lexicographically less than the other.
720 /// - If two sequence have equivalent elements and are of the same length, then the sequences are lexicographically equal.
721 /// - An empty sequence is lexicographically less than any non-empty sequence.
722 /// - Two empty sequences are lexicographically equal.
724 /// ## How can I implement `Ord`?
726 /// `Ord` requires that the type also be [`PartialOrd`] and [`Eq`] (which requires [`PartialEq`]).
728 /// Then you must define an implementation for [`cmp`]. You may find it useful to use
729 /// [`cmp`] on your type's fields.
731 /// Here's an example where you want to sort people by height only, disregarding `id`
735 /// use std::cmp::Ordering;
744 /// impl Ord for Person {
745 /// fn cmp(&self, other: &Self) -> Ordering {
746 /// self.height.cmp(&other.height)
750 /// impl PartialOrd for Person {
751 /// fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
752 /// Some(self.cmp(other))
756 /// impl PartialEq for Person {
757 /// fn eq(&self, other: &Self) -> bool {
758 /// self.height == other.height
763 /// [`cmp`]: Ord::cmp
768 #[stable(feature = "rust1", since = "1.0.0")]
769 #[rustc_diagnostic_item = "Ord"]
771 pub trait Ord: Eq + PartialOrd<Self> {
772 /// This method returns an [`Ordering`] between `self` and `other`.
774 /// By convention, `self.cmp(&other)` returns the ordering matching the expression
775 /// `self <operator> other` if true.
780 /// use std::cmp::Ordering;
782 /// assert_eq!(5.cmp(&10), Ordering::Less);
783 /// assert_eq!(10.cmp(&5), Ordering::Greater);
784 /// assert_eq!(5.cmp(&5), Ordering::Equal);
787 #[stable(feature = "rust1", since = "1.0.0")]
788 fn cmp(&self, other: &Self) -> Ordering;
790 /// Compares and returns the maximum of two values.
792 /// Returns the second argument if the comparison determines them to be equal.
797 /// assert_eq!(2, 1.max(2));
798 /// assert_eq!(2, 2.max(2));
800 #[stable(feature = "ord_max_min", since = "1.21.0")]
803 fn max(self, other: Self) -> Self
806 Self: ~const Destruct,
808 // HACK(fee1-dead): go back to using `self.max_by(other, Ord::cmp)`
809 // when trait methods are allowed to be used when a const closure is
811 match self.cmp(&other) {
812 Ordering::Less | Ordering::Equal => other,
813 Ordering::Greater => self,
817 /// Compares and returns the minimum of two values.
819 /// Returns the first argument if the comparison determines them to be equal.
824 /// assert_eq!(1, 1.min(2));
825 /// assert_eq!(2, 2.min(2));
827 #[stable(feature = "ord_max_min", since = "1.21.0")]
830 fn min(self, other: Self) -> Self
833 Self: ~const Destruct,
835 // HACK(fee1-dead): go back to using `self.min_by(other, Ord::cmp)`
836 // when trait methods are allowed to be used when a const closure is
838 match self.cmp(&other) {
839 Ordering::Less | Ordering::Equal => self,
840 Ordering::Greater => other,
844 /// Restrict a value to a certain interval.
846 /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
847 /// less than `min`. Otherwise this returns `self`.
851 /// Panics if `min > max`.
856 /// assert!((-3).clamp(-2, 1) == -2);
857 /// assert!(0.clamp(-2, 1) == 0);
858 /// assert!(2.clamp(-2, 1) == 1);
861 #[stable(feature = "clamp", since = "1.50.0")]
862 fn clamp(self, min: Self, max: Self) -> Self
865 Self: ~const Destruct,
866 Self: ~const PartialOrd,
871 } else if self > max {
879 /// Derive macro generating an impl of the trait `Ord`.
880 #[rustc_builtin_macro]
881 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
882 #[allow_internal_unstable(core_intrinsics)]
883 pub macro Ord($item:item) {
884 /* compiler built-in */
887 #[stable(feature = "rust1", since = "1.0.0")]
888 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
889 impl const Ord for Ordering {
891 fn cmp(&self, other: &Ordering) -> Ordering {
892 (*self as i32).cmp(&(*other as i32))
896 #[stable(feature = "rust1", since = "1.0.0")]
897 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
898 impl const PartialOrd for Ordering {
900 fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
901 (*self as i32).partial_cmp(&(*other as i32))
905 /// Trait for types that form a [partial order](https://en.wikipedia.org/wiki/Partial_order).
907 /// The `lt`, `le`, `gt`, and `ge` methods of this trait can be called using
908 /// the `<`, `<=`, `>`, and `>=` operators, respectively.
910 /// The methods of this trait must be consistent with each other and with those of [`PartialEq`].
911 /// The following conditions must hold:
913 /// 1. `a == b` if and only if `partial_cmp(a, b) == Some(Equal)`.
914 /// 2. `a < b` if and only if `partial_cmp(a, b) == Some(Less)`
915 /// 3. `a > b` if and only if `partial_cmp(a, b) == Some(Greater)`
916 /// 4. `a <= b` if and only if `a < b || a == b`
917 /// 5. `a >= b` if and only if `a > b || a == b`
918 /// 6. `a != b` if and only if `!(a == b)`.
920 /// Conditions 2–5 above are ensured by the default implementation.
921 /// Condition 6 is already ensured by [`PartialEq`].
923 /// If [`Ord`] is also implemented for `Self` and `Rhs`, it must also be consistent with
924 /// `partial_cmp` (see the documentation of that trait for the exact requirements). It's
925 /// easy to accidentally make them disagree by deriving some of the traits and manually
926 /// implementing others.
928 /// The comparison must satisfy, for all `a`, `b` and `c`:
930 /// - transitivity: `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
931 /// - duality: `a < b` if and only if `b > a`.
933 /// Note that these requirements mean that the trait itself must be implemented symmetrically and
934 /// transitively: if `T: PartialOrd<U>` and `U: PartialOrd<V>` then `U: PartialOrd<T>` and `T:
939 /// The following corollaries follow from the above requirements:
941 /// - irreflexivity of `<` and `>`: `!(a < a)`, `!(a > a)`
942 /// - transitivity of `>`: if `a > b` and `b > c` then `a > c`
943 /// - duality of `partial_cmp`: `partial_cmp(a, b) == partial_cmp(b, a).map(Ordering::reverse)`
947 /// This trait can be used with `#[derive]`.
949 /// When `derive`d on structs, it will produce a
950 /// [lexicographic](https://en.wikipedia.org/wiki/Lexicographic_order) ordering
951 /// based on the top-to-bottom declaration order of the struct's members.
953 /// When `derive`d on enums, variants are ordered by their discriminants.
954 /// By default, the discriminant is smallest for variants at the top, and
955 /// largest for variants at the bottom. Here's an example:
958 /// #[derive(PartialEq, PartialOrd)]
964 /// assert!(E::Top < E::Bottom);
967 /// However, manually setting the discriminants can override this default
971 /// #[derive(PartialEq, PartialOrd)]
977 /// assert!(E::Bottom < E::Top);
980 /// ## How can I implement `PartialOrd`?
982 /// `PartialOrd` only requires implementation of the [`partial_cmp`] method, with the others
983 /// generated from default implementations.
985 /// However it remains possible to implement the others separately for types which do not have a
986 /// total order. For example, for floating point numbers, `NaN < 0 == false` and `NaN >= 0 ==
987 /// false` (cf. IEEE 754-2008 section 5.11).
989 /// `PartialOrd` requires your type to be [`PartialEq`].
991 /// If your type is [`Ord`], you can implement [`partial_cmp`] by using [`cmp`]:
994 /// use std::cmp::Ordering;
1003 /// impl PartialOrd for Person {
1004 /// fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1005 /// Some(self.cmp(other))
1009 /// impl Ord for Person {
1010 /// fn cmp(&self, other: &Self) -> Ordering {
1011 /// self.height.cmp(&other.height)
1015 /// impl PartialEq for Person {
1016 /// fn eq(&self, other: &Self) -> bool {
1017 /// self.height == other.height
1022 /// You may also find it useful to use [`partial_cmp`] on your type's fields. Here
1023 /// is an example of `Person` types who have a floating-point `height` field that
1024 /// is the only field to be used for sorting:
1027 /// use std::cmp::Ordering;
1035 /// impl PartialOrd for Person {
1036 /// fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1037 /// self.height.partial_cmp(&other.height)
1041 /// impl PartialEq for Person {
1042 /// fn eq(&self, other: &Self) -> bool {
1043 /// self.height == other.height
1054 /// assert_eq!(x < y, true);
1055 /// assert_eq!(x.lt(&y), true);
1058 /// [`partial_cmp`]: PartialOrd::partial_cmp
1059 /// [`cmp`]: Ord::cmp
1060 #[lang = "partial_ord"]
1061 #[stable(feature = "rust1", since = "1.0.0")]
1064 #[doc(alias = "<=")]
1065 #[doc(alias = ">=")]
1068 rustc_on_unimplemented(
1069 message = "can't compare `{Self}` with `{Rhs}`",
1070 label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`",
1075 rustc_on_unimplemented(
1076 message = "can't compare `{Self}` with `{Rhs}`",
1077 label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`",
1082 #[rustc_diagnostic_item = "PartialOrd"]
1083 pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
1084 /// This method returns an ordering between `self` and `other` values if one exists.
1089 /// use std::cmp::Ordering;
1091 /// let result = 1.0.partial_cmp(&2.0);
1092 /// assert_eq!(result, Some(Ordering::Less));
1094 /// let result = 1.0.partial_cmp(&1.0);
1095 /// assert_eq!(result, Some(Ordering::Equal));
1097 /// let result = 2.0.partial_cmp(&1.0);
1098 /// assert_eq!(result, Some(Ordering::Greater));
1101 /// When comparison is impossible:
1104 /// let result = f64::NAN.partial_cmp(&1.0);
1105 /// assert_eq!(result, None);
1108 #[stable(feature = "rust1", since = "1.0.0")]
1109 fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
1111 /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
1116 /// let result = 1.0 < 2.0;
1117 /// assert_eq!(result, true);
1119 /// let result = 2.0 < 1.0;
1120 /// assert_eq!(result, false);
1124 #[stable(feature = "rust1", since = "1.0.0")]
1125 fn lt(&self, other: &Rhs) -> bool {
1126 matches!(self.partial_cmp(other), Some(Less))
1129 /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
1135 /// let result = 1.0 <= 2.0;
1136 /// assert_eq!(result, true);
1138 /// let result = 2.0 <= 2.0;
1139 /// assert_eq!(result, true);
1143 #[stable(feature = "rust1", since = "1.0.0")]
1144 fn le(&self, other: &Rhs) -> bool {
1145 matches!(self.partial_cmp(other), Some(Less | Equal))
1148 /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
1153 /// let result = 1.0 > 2.0;
1154 /// assert_eq!(result, false);
1156 /// let result = 2.0 > 2.0;
1157 /// assert_eq!(result, false);
1161 #[stable(feature = "rust1", since = "1.0.0")]
1162 fn gt(&self, other: &Rhs) -> bool {
1163 matches!(self.partial_cmp(other), Some(Greater))
1166 /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
1172 /// let result = 2.0 >= 1.0;
1173 /// assert_eq!(result, true);
1175 /// let result = 2.0 >= 2.0;
1176 /// assert_eq!(result, true);
1180 #[stable(feature = "rust1", since = "1.0.0")]
1181 fn ge(&self, other: &Rhs) -> bool {
1182 matches!(self.partial_cmp(other), Some(Greater | Equal))
1186 /// Derive macro generating an impl of the trait `PartialOrd`.
1187 #[rustc_builtin_macro]
1188 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
1189 #[allow_internal_unstable(core_intrinsics)]
1190 pub macro PartialOrd($item:item) {
1191 /* compiler built-in */
1194 /// Compares and returns the minimum of two values.
1196 /// Returns the first argument if the comparison determines them to be equal.
1198 /// Internally uses an alias to [`Ord::min`].
1205 /// assert_eq!(1, cmp::min(1, 2));
1206 /// assert_eq!(2, cmp::min(2, 2));
1210 #[stable(feature = "rust1", since = "1.0.0")]
1211 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1212 #[cfg_attr(not(test), rustc_diagnostic_item = "cmp_min")]
1213 pub const fn min<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T {
1217 /// Returns the minimum of two values with respect to the specified comparison function.
1219 /// Returns the first argument if the comparison determines them to be equal.
1226 /// assert_eq!(cmp::min_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), 1);
1227 /// assert_eq!(cmp::min_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), -2);
1231 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
1232 pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
1233 match compare(&v1, &v2) {
1234 Ordering::Less | Ordering::Equal => v1,
1235 Ordering::Greater => v2,
1239 /// Returns the element that gives the minimum value from the specified function.
1241 /// Returns the first argument if the comparison determines them to be equal.
1248 /// assert_eq!(cmp::min_by_key(-2, 1, |x: &i32| x.abs()), 1);
1249 /// assert_eq!(cmp::min_by_key(-2, 2, |x: &i32| x.abs()), -2);
1253 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
1254 pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
1255 min_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2)))
1258 /// Compares and returns the maximum of two values.
1260 /// Returns the second argument if the comparison determines them to be equal.
1262 /// Internally uses an alias to [`Ord::max`].
1269 /// assert_eq!(2, cmp::max(1, 2));
1270 /// assert_eq!(2, cmp::max(2, 2));
1274 #[stable(feature = "rust1", since = "1.0.0")]
1275 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1276 #[cfg_attr(not(test), rustc_diagnostic_item = "cmp_max")]
1277 pub const fn max<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T {
1281 /// Returns the maximum of two values with respect to the specified comparison function.
1283 /// Returns the second argument if the comparison determines them to be equal.
1290 /// assert_eq!(cmp::max_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), -2);
1291 /// assert_eq!(cmp::max_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), 2);
1295 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
1296 pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
1297 match compare(&v1, &v2) {
1298 Ordering::Less | Ordering::Equal => v2,
1299 Ordering::Greater => v1,
1303 /// Returns the element that gives the maximum value from the specified function.
1305 /// Returns the second argument if the comparison determines them to be equal.
1312 /// assert_eq!(cmp::max_by_key(-2, 1, |x: &i32| x.abs()), -2);
1313 /// assert_eq!(cmp::max_by_key(-2, 2, |x: &i32| x.abs()), 2);
1317 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
1318 pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
1319 max_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2)))
1322 // Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
1324 use crate::cmp::Ordering::{self, Equal, Greater, Less};
1325 use crate::hint::unreachable_unchecked;
1327 macro_rules! partial_eq_impl {
1329 #[stable(feature = "rust1", since = "1.0.0")]
1330 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1331 impl const PartialEq for $t {
1333 fn eq(&self, other: &$t) -> bool { (*self) == (*other) }
1335 fn ne(&self, other: &$t) -> bool { (*self) != (*other) }
1340 #[stable(feature = "rust1", since = "1.0.0")]
1341 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1342 impl const PartialEq for () {
1344 fn eq(&self, _other: &()) -> bool {
1348 fn ne(&self, _other: &()) -> bool {
1354 bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64
1357 macro_rules! eq_impl {
1359 #[stable(feature = "rust1", since = "1.0.0")]
1364 eq_impl! { () bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
1366 macro_rules! partial_ord_impl {
1368 #[stable(feature = "rust1", since = "1.0.0")]
1369 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1370 impl const PartialOrd for $t {
1372 fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
1373 match (*self <= *other, *self >= *other) {
1374 (false, false) => None,
1375 (false, true) => Some(Greater),
1376 (true, false) => Some(Less),
1377 (true, true) => Some(Equal),
1381 fn lt(&self, other: &$t) -> bool { (*self) < (*other) }
1383 fn le(&self, other: &$t) -> bool { (*self) <= (*other) }
1385 fn ge(&self, other: &$t) -> bool { (*self) >= (*other) }
1387 fn gt(&self, other: &$t) -> bool { (*self) > (*other) }
1392 #[stable(feature = "rust1", since = "1.0.0")]
1393 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1394 impl const PartialOrd for () {
1396 fn partial_cmp(&self, _: &()) -> Option<Ordering> {
1401 #[stable(feature = "rust1", since = "1.0.0")]
1402 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1403 impl const PartialOrd for bool {
1405 fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
1406 Some(self.cmp(other))
1410 partial_ord_impl! { f32 f64 }
1412 macro_rules! ord_impl {
1414 #[stable(feature = "rust1", since = "1.0.0")]
1415 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1416 impl const PartialOrd for $t {
1418 fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
1419 Some(self.cmp(other))
1422 fn lt(&self, other: &$t) -> bool { (*self) < (*other) }
1424 fn le(&self, other: &$t) -> bool { (*self) <= (*other) }
1426 fn ge(&self, other: &$t) -> bool { (*self) >= (*other) }
1428 fn gt(&self, other: &$t) -> bool { (*self) > (*other) }
1431 #[stable(feature = "rust1", since = "1.0.0")]
1432 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1433 impl const Ord for $t {
1435 fn cmp(&self, other: &$t) -> Ordering {
1436 // The order here is important to generate more optimal assembly.
1437 // See <https://github.com/rust-lang/rust/issues/63758> for more info.
1438 if *self < *other { Less }
1439 else if *self == *other { Equal }
1446 #[stable(feature = "rust1", since = "1.0.0")]
1447 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1448 impl const Ord for () {
1450 fn cmp(&self, _other: &()) -> Ordering {
1455 #[stable(feature = "rust1", since = "1.0.0")]
1456 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1457 impl const Ord for bool {
1459 fn cmp(&self, other: &bool) -> Ordering {
1460 // Casting to i8's and converting the difference to an Ordering generates
1461 // more optimal assembly.
1462 // See <https://github.com/rust-lang/rust/issues/66780> for more info.
1463 match (*self as i8) - (*other as i8) {
1467 // SAFETY: bool as i8 returns 0 or 1, so the difference can't be anything else
1468 _ => unsafe { unreachable_unchecked() },
1473 ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
1475 #[unstable(feature = "never_type", issue = "35121")]
1476 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1477 impl const PartialEq for ! {
1478 fn eq(&self, _: &!) -> bool {
1483 #[unstable(feature = "never_type", issue = "35121")]
1486 #[unstable(feature = "never_type", issue = "35121")]
1487 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1488 impl const PartialOrd for ! {
1489 fn partial_cmp(&self, _: &!) -> Option<Ordering> {
1494 #[unstable(feature = "never_type", issue = "35121")]
1495 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1496 impl const Ord for ! {
1497 fn cmp(&self, _: &!) -> Ordering {
1504 #[stable(feature = "rust1", since = "1.0.0")]
1505 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1506 impl<A: ?Sized, B: ?Sized> const PartialEq<&B> for &A
1508 A: ~const PartialEq<B>,
1511 fn eq(&self, other: &&B) -> bool {
1512 PartialEq::eq(*self, *other)
1515 fn ne(&self, other: &&B) -> bool {
1516 PartialEq::ne(*self, *other)
1519 #[stable(feature = "rust1", since = "1.0.0")]
1520 impl<A: ?Sized, B: ?Sized> PartialOrd<&B> for &A
1525 fn partial_cmp(&self, other: &&B) -> Option<Ordering> {
1526 PartialOrd::partial_cmp(*self, *other)
1529 fn lt(&self, other: &&B) -> bool {
1530 PartialOrd::lt(*self, *other)
1533 fn le(&self, other: &&B) -> bool {
1534 PartialOrd::le(*self, *other)
1537 fn gt(&self, other: &&B) -> bool {
1538 PartialOrd::gt(*self, *other)
1541 fn ge(&self, other: &&B) -> bool {
1542 PartialOrd::ge(*self, *other)
1545 #[stable(feature = "rust1", since = "1.0.0")]
1546 impl<A: ?Sized> Ord for &A
1551 fn cmp(&self, other: &Self) -> Ordering {
1552 Ord::cmp(*self, *other)
1555 #[stable(feature = "rust1", since = "1.0.0")]
1556 impl<A: ?Sized> Eq for &A where A: Eq {}
1560 #[stable(feature = "rust1", since = "1.0.0")]
1561 impl<A: ?Sized, B: ?Sized> PartialEq<&mut B> for &mut A
1566 fn eq(&self, other: &&mut B) -> bool {
1567 PartialEq::eq(*self, *other)
1570 fn ne(&self, other: &&mut B) -> bool {
1571 PartialEq::ne(*self, *other)
1574 #[stable(feature = "rust1", since = "1.0.0")]
1575 impl<A: ?Sized, B: ?Sized> PartialOrd<&mut B> for &mut A
1580 fn partial_cmp(&self, other: &&mut B) -> Option<Ordering> {
1581 PartialOrd::partial_cmp(*self, *other)
1584 fn lt(&self, other: &&mut B) -> bool {
1585 PartialOrd::lt(*self, *other)
1588 fn le(&self, other: &&mut B) -> bool {
1589 PartialOrd::le(*self, *other)
1592 fn gt(&self, other: &&mut B) -> bool {
1593 PartialOrd::gt(*self, *other)
1596 fn ge(&self, other: &&mut B) -> bool {
1597 PartialOrd::ge(*self, *other)
1600 #[stable(feature = "rust1", since = "1.0.0")]
1601 impl<A: ?Sized> Ord for &mut A
1606 fn cmp(&self, other: &Self) -> Ordering {
1607 Ord::cmp(*self, *other)
1610 #[stable(feature = "rust1", since = "1.0.0")]
1611 impl<A: ?Sized> Eq for &mut A where A: Eq {}
1613 #[stable(feature = "rust1", since = "1.0.0")]
1614 impl<A: ?Sized, B: ?Sized> PartialEq<&mut B> for &A
1619 fn eq(&self, other: &&mut B) -> bool {
1620 PartialEq::eq(*self, *other)
1623 fn ne(&self, other: &&mut B) -> bool {
1624 PartialEq::ne(*self, *other)
1628 #[stable(feature = "rust1", since = "1.0.0")]
1629 impl<A: ?Sized, B: ?Sized> PartialEq<&B> for &mut A
1634 fn eq(&self, other: &&B) -> bool {
1635 PartialEq::eq(*self, *other)
1638 fn ne(&self, other: &&B) -> bool {
1639 PartialEq::ne(*self, *other)