]> git.lizzy.rs Git - rust.git/blob - src/libcore/cmp.rs
Rollup merge of #58595 - stjepang:make-duration-consts-associated, r=oli-obk
[rust.git] / src / libcore / cmp.rs
1 //! Functionality for ordering and comparison.
2 //!
3 //! This module contains various tools for ordering and comparing values. In
4 //! summary:
5 //!
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`][cmp::Ordering] is an enum returned by the
13 //!   main functions of [`Ord`] and [`PartialOrd`], and describes an ordering.
14 //! * [`Reverse`][cmp::Reverse] is a struct that allows you to easily reverse
15 //!   an ordering.
16 //! * [`max`][cmp::max] and [`min`][cmp::min] are functions that build off of
17 //!   [`Ord`] and allow you to find the maximum or minimum of two values.
18 //!
19 //! For more details, see the respective documentation of each item in the list.
20
21 #![stable(feature = "rust1", since = "1.0.0")]
22
23 use self::Ordering::*;
24
25 /// Trait for equality comparisons which are [partial equivalence
26 /// relations](http://en.wikipedia.org/wiki/Partial_equivalence_relation).
27 ///
28 /// This trait allows for partial equality, for types that do not have a full
29 /// equivalence relation. For example, in floating point numbers `NaN != NaN`,
30 /// so floating point types implement `PartialEq` but not `Eq`.
31 ///
32 /// Formally, the equality must be (for all `a`, `b` and `c`):
33 ///
34 /// - symmetric: `a == b` implies `b == a`; and
35 /// - transitive: `a == b` and `b == c` implies `a == c`.
36 ///
37 /// Note that these requirements mean that the trait itself must be implemented
38 /// symmetrically and transitively: if `T: PartialEq<U>` and `U: PartialEq<V>`
39 /// then `U: PartialEq<T>` and `T: PartialEq<V>`.
40 ///
41 /// ## Derivable
42 ///
43 /// This trait can be used with `#[derive]`. When `derive`d on structs, two
44 /// instances are equal if all fields are equal, and not equal if any fields
45 /// are not equal. When `derive`d on enums, each variant is equal to itself
46 /// and not equal to the other variants.
47 ///
48 /// ## How can I implement `PartialEq`?
49 ///
50 /// PartialEq only requires the `eq` method to be implemented; `ne` is defined
51 /// in terms of it by default. Any manual implementation of `ne` *must* respect
52 /// the rule that `eq` is a strict inverse of `ne`; that is, `!(a == b)` if and
53 /// only if `a != b`.
54 ///
55 /// Implementations of `PartialEq`, `PartialOrd`, and `Ord` *must* agree with
56 /// each other. It's easy to accidentally make them disagree by deriving some
57 /// of the traits and manually implementing others.
58 ///
59 /// An example implementation for a domain in which two books are considered
60 /// the same book if their ISBN matches, even if the formats differ:
61 ///
62 /// ```
63 /// enum BookFormat {
64 ///     Paperback,
65 ///     Hardback,
66 ///     Ebook,
67 /// }
68 ///
69 /// struct Book {
70 ///     isbn: i32,
71 ///     format: BookFormat,
72 /// }
73 ///
74 /// impl PartialEq for Book {
75 ///     fn eq(&self, other: &Book) -> bool {
76 ///         self.isbn == other.isbn
77 ///     }
78 /// }
79 ///
80 /// let b1 = Book { isbn: 3, format: BookFormat::Paperback };
81 /// let b2 = Book { isbn: 3, format: BookFormat::Ebook };
82 /// let b3 = Book { isbn: 10, format: BookFormat::Paperback };
83 ///
84 /// assert!(b1 == b2);
85 /// assert!(b1 != b3);
86 /// ```
87 ///
88 /// ## How can I compare two different types?
89 ///
90 /// The type you can compare with is controlled by `PartialEq`'s type parameter.
91 /// For example, let's tweak our previous code a bit:
92 ///
93 /// ```
94 /// // The derive implements <BookFormat> == <BookFormat> comparisons
95 /// #[derive(PartialEq)]
96 /// enum BookFormat {
97 ///     Paperback,
98 ///     Hardback,
99 ///     Ebook,
100 /// }
101 ///
102 /// struct Book {
103 ///     isbn: i32,
104 ///     format: BookFormat,
105 /// }
106 ///
107 /// // Implement <Book> == <BookFormat> comparisons
108 /// impl PartialEq<BookFormat> for Book {
109 ///     fn eq(&self, other: &BookFormat) -> bool {
110 ///         self.format == *other
111 ///     }
112 /// }
113 ///
114 /// // Implement <BookFormat> == <Book> comparisons
115 /// impl PartialEq<Book> for BookFormat {
116 ///     fn eq(&self, other: &Book) -> bool {
117 ///         *self == other.format
118 ///     }
119 /// }
120 ///
121 /// let b1 = Book { isbn: 3, format: BookFormat::Paperback };
122 ///
123 /// assert!(b1 == BookFormat::Paperback);
124 /// assert!(BookFormat::Ebook != b1);
125 /// ```
126 ///
127 /// By changing `impl PartialEq for Book` to `impl PartialEq<BookFormat> for Book`,
128 /// we allow `BookFormat`s to be compared with `Book`s.
129 ///
130 /// You can also combine these implementations to let the `==` operator work with
131 /// two different types:
132 ///
133 /// ```
134 /// #[derive(PartialEq)]
135 /// enum BookFormat {
136 ///     Paperback,
137 ///     Hardback,
138 ///     Ebook,
139 /// }
140 ///
141 /// struct Book {
142 ///     isbn: i32,
143 ///     format: BookFormat,
144 /// }
145 ///
146 /// impl PartialEq<BookFormat> for Book {
147 ///     fn eq(&self, other: &BookFormat) -> bool {
148 ///         self.format == *other
149 ///     }
150 /// }
151 ///
152 /// impl PartialEq<Book> for BookFormat {
153 ///     fn eq(&self, other: &Book) -> bool {
154 ///         *self == other.format
155 ///     }
156 /// }
157 ///
158 /// impl PartialEq for Book {
159 ///     fn eq(&self, other: &Book) -> bool {
160 ///         self.isbn == other.isbn
161 ///     }
162 /// }
163 ///
164 /// let b1 = Book { isbn: 3, format: BookFormat::Paperback };
165 /// let b2 = Book { isbn: 3, format: BookFormat::Ebook };
166 ///
167 /// assert!(b1 == BookFormat::Paperback);
168 /// assert!(BookFormat::Ebook != b1);
169 /// assert!(b1 == b2);
170 /// ```
171 ///
172 /// # Examples
173 ///
174 /// ```
175 /// let x: u32 = 0;
176 /// let y: u32 = 1;
177 ///
178 /// assert_eq!(x == y, false);
179 /// assert_eq!(x.eq(&y), false);
180 /// ```
181 #[lang = "eq"]
182 #[stable(feature = "rust1", since = "1.0.0")]
183 #[doc(alias = "==")]
184 #[doc(alias = "!=")]
185 #[rustc_on_unimplemented(
186     message="can't compare `{Self}` with `{Rhs}`",
187     label="no implementation for `{Self} == {Rhs}`",
188 )]
189 pub trait PartialEq<Rhs: ?Sized = Self> {
190     /// This method tests for `self` and `other` values to be equal, and is used
191     /// by `==`.
192     #[must_use]
193     #[stable(feature = "rust1", since = "1.0.0")]
194     fn eq(&self, other: &Rhs) -> bool;
195
196     /// This method tests for `!=`.
197     #[inline]
198     #[must_use]
199     #[stable(feature = "rust1", since = "1.0.0")]
200     fn ne(&self, other: &Rhs) -> bool { !self.eq(other) }
201 }
202
203 /// Trait for equality comparisons which are [equivalence relations](
204 /// https://en.wikipedia.org/wiki/Equivalence_relation).
205 ///
206 /// This means, that in addition to `a == b` and `a != b` being strict inverses, the equality must
207 /// be (for all `a`, `b` and `c`):
208 ///
209 /// - reflexive: `a == a`;
210 /// - symmetric: `a == b` implies `b == a`; and
211 /// - transitive: `a == b` and `b == c` implies `a == c`.
212 ///
213 /// This property cannot be checked by the compiler, and therefore `Eq` implies
214 /// `PartialEq`, and has no extra methods.
215 ///
216 /// ## Derivable
217 ///
218 /// This trait can be used with `#[derive]`. When `derive`d, because `Eq` has
219 /// no extra methods, it is only informing the compiler that this is an
220 /// equivalence relation rather than a partial equivalence relation. Note that
221 /// the `derive` strategy requires all fields are `Eq`, which isn't
222 /// always desired.
223 ///
224 /// ## How can I implement `Eq`?
225 ///
226 /// If you cannot use the `derive` strategy, specify that your type implements
227 /// `Eq`, which has no methods:
228 ///
229 /// ```
230 /// enum BookFormat { Paperback, Hardback, Ebook }
231 /// struct Book {
232 ///     isbn: i32,
233 ///     format: BookFormat,
234 /// }
235 /// impl PartialEq for Book {
236 ///     fn eq(&self, other: &Book) -> bool {
237 ///         self.isbn == other.isbn
238 ///     }
239 /// }
240 /// impl Eq for Book {}
241 /// ```
242 #[doc(alias = "==")]
243 #[doc(alias = "!=")]
244 #[stable(feature = "rust1", since = "1.0.0")]
245 pub trait Eq: PartialEq<Self> {
246     // this method is used solely by #[deriving] to assert
247     // that every component of a type implements #[deriving]
248     // itself, the current deriving infrastructure means doing this
249     // assertion without using a method on this trait is nearly
250     // impossible.
251     //
252     // This should never be implemented by hand.
253     #[doc(hidden)]
254     #[inline]
255     #[stable(feature = "rust1", since = "1.0.0")]
256     fn assert_receiver_is_total_eq(&self) {}
257 }
258
259 // FIXME: this struct is used solely by #[derive] to
260 // assert that every component of a type implements Eq.
261 //
262 // This struct should never appear in user code.
263 #[doc(hidden)]
264 #[allow(missing_debug_implementations)]
265 #[unstable(feature = "derive_eq",
266            reason = "deriving hack, should not be public",
267            issue = "0")]
268 pub struct AssertParamIsEq<T: Eq + ?Sized> { _field: ::marker::PhantomData<T> }
269
270 /// An `Ordering` is the result of a comparison between two values.
271 ///
272 /// # Examples
273 ///
274 /// ```
275 /// use std::cmp::Ordering;
276 ///
277 /// let result = 1.cmp(&2);
278 /// assert_eq!(Ordering::Less, result);
279 ///
280 /// let result = 1.cmp(&1);
281 /// assert_eq!(Ordering::Equal, result);
282 ///
283 /// let result = 2.cmp(&1);
284 /// assert_eq!(Ordering::Greater, result);
285 /// ```
286 #[derive(Clone, Copy, PartialEq, Debug, Hash)]
287 #[stable(feature = "rust1", since = "1.0.0")]
288 pub enum Ordering {
289     /// An ordering where a compared value is less [than another].
290     #[stable(feature = "rust1", since = "1.0.0")]
291     Less = -1,
292     /// An ordering where a compared value is equal [to another].
293     #[stable(feature = "rust1", since = "1.0.0")]
294     Equal = 0,
295     /// An ordering where a compared value is greater [than another].
296     #[stable(feature = "rust1", since = "1.0.0")]
297     Greater = 1,
298 }
299
300 impl Ordering {
301     /// Reverses the `Ordering`.
302     ///
303     /// * `Less` becomes `Greater`.
304     /// * `Greater` becomes `Less`.
305     /// * `Equal` becomes `Equal`.
306     ///
307     /// # Examples
308     ///
309     /// Basic behavior:
310     ///
311     /// ```
312     /// use std::cmp::Ordering;
313     ///
314     /// assert_eq!(Ordering::Less.reverse(), Ordering::Greater);
315     /// assert_eq!(Ordering::Equal.reverse(), Ordering::Equal);
316     /// assert_eq!(Ordering::Greater.reverse(), Ordering::Less);
317     /// ```
318     ///
319     /// This method can be used to reverse a comparison:
320     ///
321     /// ```
322     /// let mut data: &mut [_] = &mut [2, 10, 5, 8];
323     ///
324     /// // sort the array from largest to smallest.
325     /// data.sort_by(|a, b| a.cmp(b).reverse());
326     ///
327     /// let b: &mut [_] = &mut [10, 8, 5, 2];
328     /// assert!(data == b);
329     /// ```
330     #[inline]
331     #[stable(feature = "rust1", since = "1.0.0")]
332     pub fn reverse(self) -> Ordering {
333         match self {
334             Less => Greater,
335             Equal => Equal,
336             Greater => Less,
337         }
338     }
339
340     /// Chains two orderings.
341     ///
342     /// Returns `self` when it's not `Equal`. Otherwise returns `other`.
343     /// # Examples
344     ///
345     /// ```
346     /// use std::cmp::Ordering;
347     ///
348     /// let result = Ordering::Equal.then(Ordering::Less);
349     /// assert_eq!(result, Ordering::Less);
350     ///
351     /// let result = Ordering::Less.then(Ordering::Equal);
352     /// assert_eq!(result, Ordering::Less);
353     ///
354     /// let result = Ordering::Less.then(Ordering::Greater);
355     /// assert_eq!(result, Ordering::Less);
356     ///
357     /// let result = Ordering::Equal.then(Ordering::Equal);
358     /// assert_eq!(result, Ordering::Equal);
359     ///
360     /// let x: (i64, i64, i64) = (1, 2, 7);
361     /// let y: (i64, i64, i64) = (1, 5, 3);
362     /// let result = x.0.cmp(&y.0).then(x.1.cmp(&y.1)).then(x.2.cmp(&y.2));
363     ///
364     /// assert_eq!(result, Ordering::Less);
365     /// ```
366     #[inline]
367     #[stable(feature = "ordering_chaining", since = "1.17.0")]
368     pub fn then(self, other: Ordering) -> Ordering {
369         match self {
370             Equal => other,
371             _ => self,
372         }
373     }
374
375     /// Chains the ordering with the given function.
376     ///
377     /// Returns `self` when it's not `Equal`. Otherwise calls `f` and returns
378     /// the result.
379     ///
380     /// # Examples
381     ///
382     /// ```
383     /// use std::cmp::Ordering;
384     ///
385     /// let result = Ordering::Equal.then_with(|| Ordering::Less);
386     /// assert_eq!(result, Ordering::Less);
387     ///
388     /// let result = Ordering::Less.then_with(|| Ordering::Equal);
389     /// assert_eq!(result, Ordering::Less);
390     ///
391     /// let result = Ordering::Less.then_with(|| Ordering::Greater);
392     /// assert_eq!(result, Ordering::Less);
393     ///
394     /// let result = Ordering::Equal.then_with(|| Ordering::Equal);
395     /// assert_eq!(result, Ordering::Equal);
396     ///
397     /// let x: (i64, i64, i64) = (1, 2, 7);
398     /// let y: (i64, i64, i64)  = (1, 5, 3);
399     /// let result = x.0.cmp(&y.0).then_with(|| x.1.cmp(&y.1)).then_with(|| x.2.cmp(&y.2));
400     ///
401     /// assert_eq!(result, Ordering::Less);
402     /// ```
403     #[inline]
404     #[stable(feature = "ordering_chaining", since = "1.17.0")]
405     pub fn then_with<F: FnOnce() -> Ordering>(self, f: F) -> Ordering {
406         match self {
407             Equal => f(),
408             _ => self,
409         }
410     }
411 }
412
413 /// A helper struct for reverse ordering.
414 ///
415 /// This struct is a helper to be used with functions like `Vec::sort_by_key` and
416 /// can be used to reverse order a part of a key.
417 ///
418 /// Example usage:
419 ///
420 /// ```
421 /// use std::cmp::Reverse;
422 ///
423 /// let mut v = vec![1, 2, 3, 4, 5, 6];
424 /// v.sort_by_key(|&num| (num > 3, Reverse(num)));
425 /// assert_eq!(v, vec![3, 2, 1, 6, 5, 4]);
426 /// ```
427 #[derive(PartialEq, Eq, Debug, Copy, Clone, Default, Hash)]
428 #[stable(feature = "reverse_cmp_key", since = "1.19.0")]
429 pub struct Reverse<T>(#[stable(feature = "reverse_cmp_key", since = "1.19.0")] pub T);
430
431 #[stable(feature = "reverse_cmp_key", since = "1.19.0")]
432 impl<T: PartialOrd> PartialOrd for Reverse<T> {
433     #[inline]
434     fn partial_cmp(&self, other: &Reverse<T>) -> Option<Ordering> {
435         other.0.partial_cmp(&self.0)
436     }
437
438     #[inline]
439     fn lt(&self, other: &Self) -> bool { other.0 < self.0 }
440     #[inline]
441     fn le(&self, other: &Self) -> bool { other.0 <= self.0 }
442     #[inline]
443     fn ge(&self, other: &Self) -> bool { other.0 >= self.0 }
444     #[inline]
445     fn gt(&self, other: &Self) -> bool { other.0 > self.0 }
446 }
447
448 #[stable(feature = "reverse_cmp_key", since = "1.19.0")]
449 impl<T: Ord> Ord for Reverse<T> {
450     #[inline]
451     fn cmp(&self, other: &Reverse<T>) -> Ordering {
452         other.0.cmp(&self.0)
453     }
454 }
455
456 /// Trait for types that form a [total order](https://en.wikipedia.org/wiki/Total_order).
457 ///
458 /// An order is a total order if it is (for all `a`, `b` and `c`):
459 ///
460 /// - total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true; and
461 /// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
462 ///
463 /// ## Derivable
464 ///
465 /// This trait can be used with `#[derive]`. When `derive`d on structs, it will produce a
466 /// lexicographic ordering based on the top-to-bottom declaration order of the struct's members.
467 /// When `derive`d on enums, variants are ordered by their top-to-bottom declaration order.
468 ///
469 /// ## How can I implement `Ord`?
470 ///
471 /// `Ord` requires that the type also be `PartialOrd` and `Eq` (which requires `PartialEq`).
472 ///
473 /// Then you must define an implementation for `cmp()`. You may find it useful to use
474 /// `cmp()` on your type's fields.
475 ///
476 /// Implementations of `PartialEq`, `PartialOrd`, and `Ord` *must*
477 /// agree with each other. That is, `a.cmp(b) == Ordering::Equal` if
478 /// and only if `a == b` and `Some(a.cmp(b)) == a.partial_cmp(b)` for
479 /// all `a` and `b`. It's easy to accidentally make them disagree by
480 /// deriving some of the traits and manually implementing others.
481 ///
482 /// Here's an example where you want to sort people by height only, disregarding `id`
483 /// and `name`:
484 ///
485 /// ```
486 /// use std::cmp::Ordering;
487 ///
488 /// #[derive(Eq)]
489 /// struct Person {
490 ///     id: u32,
491 ///     name: String,
492 ///     height: u32,
493 /// }
494 ///
495 /// impl Ord for Person {
496 ///     fn cmp(&self, other: &Person) -> Ordering {
497 ///         self.height.cmp(&other.height)
498 ///     }
499 /// }
500 ///
501 /// impl PartialOrd for Person {
502 ///     fn partial_cmp(&self, other: &Person) -> Option<Ordering> {
503 ///         Some(self.cmp(other))
504 ///     }
505 /// }
506 ///
507 /// impl PartialEq for Person {
508 ///     fn eq(&self, other: &Person) -> bool {
509 ///         self.height == other.height
510 ///     }
511 /// }
512 /// ```
513 #[lang = "ord"]
514 #[doc(alias = "<")]
515 #[doc(alias = ">")]
516 #[doc(alias = "<=")]
517 #[doc(alias = ">=")]
518 #[stable(feature = "rust1", since = "1.0.0")]
519 pub trait Ord: Eq + PartialOrd<Self> {
520     /// This method returns an `Ordering` between `self` and `other`.
521     ///
522     /// By convention, `self.cmp(&other)` returns the ordering matching the expression
523     /// `self <operator> other` if true.
524     ///
525     /// # Examples
526     ///
527     /// ```
528     /// use std::cmp::Ordering;
529     ///
530     /// assert_eq!(5.cmp(&10), Ordering::Less);
531     /// assert_eq!(10.cmp(&5), Ordering::Greater);
532     /// assert_eq!(5.cmp(&5), Ordering::Equal);
533     /// ```
534     #[stable(feature = "rust1", since = "1.0.0")]
535     fn cmp(&self, other: &Self) -> Ordering;
536
537     /// Compares and returns the maximum of two values.
538     ///
539     /// Returns the second argument if the comparison determines them to be equal.
540     ///
541     /// # Examples
542     ///
543     /// ```
544     /// assert_eq!(2, 1.max(2));
545     /// assert_eq!(2, 2.max(2));
546     /// ```
547     #[stable(feature = "ord_max_min", since = "1.21.0")]
548     #[inline]
549     fn max(self, other: Self) -> Self
550     where Self: Sized {
551         if other >= self { other } else { self }
552     }
553
554     /// Compares and returns the minimum of two values.
555     ///
556     /// Returns the first argument if the comparison determines them to be equal.
557     ///
558     /// # Examples
559     ///
560     /// ```
561     /// assert_eq!(1, 1.min(2));
562     /// assert_eq!(2, 2.min(2));
563     /// ```
564     #[stable(feature = "ord_max_min", since = "1.21.0")]
565     #[inline]
566     fn min(self, other: Self) -> Self
567     where Self: Sized {
568         if self <= other { self } else { other }
569     }
570 }
571
572 #[stable(feature = "rust1", since = "1.0.0")]
573 impl Eq for Ordering {}
574
575 #[stable(feature = "rust1", since = "1.0.0")]
576 impl Ord for Ordering {
577     #[inline]
578     fn cmp(&self, other: &Ordering) -> Ordering {
579         (*self as i32).cmp(&(*other as i32))
580     }
581 }
582
583 #[stable(feature = "rust1", since = "1.0.0")]
584 impl PartialOrd for Ordering {
585     #[inline]
586     fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
587         (*self as i32).partial_cmp(&(*other as i32))
588     }
589 }
590
591 /// Trait for values that can be compared for a sort-order.
592 ///
593 /// The comparison must satisfy, for all `a`, `b` and `c`:
594 ///
595 /// - antisymmetry: if `a < b` then `!(a > b)`, as well as `a > b` implying `!(a < b)`; and
596 /// - transitivity: `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
597 ///
598 /// Note that these requirements mean that the trait itself must be implemented symmetrically and
599 /// transitively: if `T: PartialOrd<U>` and `U: PartialOrd<V>` then `U: PartialOrd<T>` and `T:
600 /// PartialOrd<V>`.
601 ///
602 /// ## Derivable
603 ///
604 /// This trait can be used with `#[derive]`. When `derive`d on structs, it will produce a
605 /// lexicographic ordering based on the top-to-bottom declaration order of the struct's members.
606 /// When `derive`d on enums, variants are ordered by their top-to-bottom declaration order.
607 ///
608 /// ## How can I implement `PartialOrd`?
609 ///
610 /// `PartialOrd` only requires implementation of the `partial_cmp` method, with the others
611 /// generated from default implementations.
612 ///
613 /// However it remains possible to implement the others separately for types which do not have a
614 /// total order. For example, for floating point numbers, `NaN < 0 == false` and `NaN >= 0 ==
615 /// false` (cf. IEEE 754-2008 section 5.11).
616 ///
617 /// `PartialOrd` requires your type to be `PartialEq`.
618 ///
619 /// Implementations of `PartialEq`, `PartialOrd`, and `Ord` *must* agree with each other. It's
620 /// easy to accidentally make them disagree by deriving some of the traits and manually
621 /// implementing others.
622 ///
623 /// If your type is `Ord`, you can implement `partial_cmp()` by using `cmp()`:
624 ///
625 /// ```
626 /// use std::cmp::Ordering;
627 ///
628 /// #[derive(Eq)]
629 /// struct Person {
630 ///     id: u32,
631 ///     name: String,
632 ///     height: u32,
633 /// }
634 ///
635 /// impl PartialOrd for Person {
636 ///     fn partial_cmp(&self, other: &Person) -> Option<Ordering> {
637 ///         Some(self.cmp(other))
638 ///     }
639 /// }
640 ///
641 /// impl Ord for Person {
642 ///     fn cmp(&self, other: &Person) -> Ordering {
643 ///         self.height.cmp(&other.height)
644 ///     }
645 /// }
646 ///
647 /// impl PartialEq for Person {
648 ///     fn eq(&self, other: &Person) -> bool {
649 ///         self.height == other.height
650 ///     }
651 /// }
652 /// ```
653 ///
654 /// You may also find it useful to use `partial_cmp()` on your type's fields. Here
655 /// is an example of `Person` types who have a floating-point `height` field that
656 /// is the only field to be used for sorting:
657 ///
658 /// ```
659 /// use std::cmp::Ordering;
660 ///
661 /// struct Person {
662 ///     id: u32,
663 ///     name: String,
664 ///     height: f64,
665 /// }
666 ///
667 /// impl PartialOrd for Person {
668 ///     fn partial_cmp(&self, other: &Person) -> Option<Ordering> {
669 ///         self.height.partial_cmp(&other.height)
670 ///     }
671 /// }
672 ///
673 /// impl PartialEq for Person {
674 ///     fn eq(&self, other: &Person) -> bool {
675 ///         self.height == other.height
676 ///     }
677 /// }
678 /// ```
679 ///
680 /// # Examples
681 ///
682 /// ```
683 /// let x : u32 = 0;
684 /// let y : u32 = 1;
685 ///
686 /// assert_eq!(x < y, true);
687 /// assert_eq!(x.lt(&y), true);
688 /// ```
689 #[lang = "partial_ord"]
690 #[stable(feature = "rust1", since = "1.0.0")]
691 #[doc(alias = ">")]
692 #[doc(alias = "<")]
693 #[doc(alias = "<=")]
694 #[doc(alias = ">=")]
695 #[rustc_on_unimplemented(
696     message="can't compare `{Self}` with `{Rhs}`",
697     label="no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`",
698 )]
699 pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
700     /// This method returns an ordering between `self` and `other` values if one exists.
701     ///
702     /// # Examples
703     ///
704     /// ```
705     /// use std::cmp::Ordering;
706     ///
707     /// let result = 1.0.partial_cmp(&2.0);
708     /// assert_eq!(result, Some(Ordering::Less));
709     ///
710     /// let result = 1.0.partial_cmp(&1.0);
711     /// assert_eq!(result, Some(Ordering::Equal));
712     ///
713     /// let result = 2.0.partial_cmp(&1.0);
714     /// assert_eq!(result, Some(Ordering::Greater));
715     /// ```
716     ///
717     /// When comparison is impossible:
718     ///
719     /// ```
720     /// let result = std::f64::NAN.partial_cmp(&1.0);
721     /// assert_eq!(result, None);
722     /// ```
723     #[must_use]
724     #[stable(feature = "rust1", since = "1.0.0")]
725     fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
726
727     /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
728     ///
729     /// # Examples
730     ///
731     /// ```
732     /// let result = 1.0 < 2.0;
733     /// assert_eq!(result, true);
734     ///
735     /// let result = 2.0 < 1.0;
736     /// assert_eq!(result, false);
737     /// ```
738     #[inline]
739     #[must_use]
740     #[stable(feature = "rust1", since = "1.0.0")]
741     fn lt(&self, other: &Rhs) -> bool {
742         match self.partial_cmp(other) {
743             Some(Less) => true,
744             _ => false,
745         }
746     }
747
748     /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
749     /// operator.
750     ///
751     /// # Examples
752     ///
753     /// ```
754     /// let result = 1.0 <= 2.0;
755     /// assert_eq!(result, true);
756     ///
757     /// let result = 2.0 <= 2.0;
758     /// assert_eq!(result, true);
759     /// ```
760     #[inline]
761     #[must_use]
762     #[stable(feature = "rust1", since = "1.0.0")]
763     fn le(&self, other: &Rhs) -> bool {
764         match self.partial_cmp(other) {
765             Some(Less) | Some(Equal) => true,
766             _ => false,
767         }
768     }
769
770     /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
771     ///
772     /// # Examples
773     ///
774     /// ```
775     /// let result = 1.0 > 2.0;
776     /// assert_eq!(result, false);
777     ///
778     /// let result = 2.0 > 2.0;
779     /// assert_eq!(result, false);
780     /// ```
781     #[inline]
782     #[must_use]
783     #[stable(feature = "rust1", since = "1.0.0")]
784     fn gt(&self, other: &Rhs) -> bool {
785         match self.partial_cmp(other) {
786             Some(Greater) => true,
787             _ => false,
788         }
789     }
790
791     /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
792     /// operator.
793     ///
794     /// # Examples
795     ///
796     /// ```
797     /// let result = 2.0 >= 1.0;
798     /// assert_eq!(result, true);
799     ///
800     /// let result = 2.0 >= 2.0;
801     /// assert_eq!(result, true);
802     /// ```
803     #[inline]
804     #[must_use]
805     #[stable(feature = "rust1", since = "1.0.0")]
806     fn ge(&self, other: &Rhs) -> bool {
807         match self.partial_cmp(other) {
808             Some(Greater) | Some(Equal) => true,
809             _ => false,
810         }
811     }
812 }
813
814 /// Compares and returns the minimum of two values.
815 ///
816 /// Returns the first argument if the comparison determines them to be equal.
817 ///
818 /// Internally uses an alias to `Ord::min`.
819 ///
820 /// # Examples
821 ///
822 /// ```
823 /// use std::cmp;
824 ///
825 /// assert_eq!(1, cmp::min(1, 2));
826 /// assert_eq!(2, cmp::min(2, 2));
827 /// ```
828 #[inline]
829 #[stable(feature = "rust1", since = "1.0.0")]
830 pub fn min<T: Ord>(v1: T, v2: T) -> T {
831     v1.min(v2)
832 }
833
834 /// Compares and returns the maximum of two values.
835 ///
836 /// Returns the second argument if the comparison determines them to be equal.
837 ///
838 /// Internally uses an alias to `Ord::max`.
839 ///
840 /// # Examples
841 ///
842 /// ```
843 /// use std::cmp;
844 ///
845 /// assert_eq!(2, cmp::max(1, 2));
846 /// assert_eq!(2, cmp::max(2, 2));
847 /// ```
848 #[inline]
849 #[stable(feature = "rust1", since = "1.0.0")]
850 pub fn max<T: Ord>(v1: T, v2: T) -> T {
851     v1.max(v2)
852 }
853
854 // Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
855 mod impls {
856     use cmp::Ordering::{self, Less, Greater, Equal};
857
858     macro_rules! partial_eq_impl {
859         ($($t:ty)*) => ($(
860             #[stable(feature = "rust1", since = "1.0.0")]
861             impl PartialEq for $t {
862                 #[inline]
863                 fn eq(&self, other: &$t) -> bool { (*self) == (*other) }
864                 #[inline]
865                 fn ne(&self, other: &$t) -> bool { (*self) != (*other) }
866             }
867         )*)
868     }
869
870     #[stable(feature = "rust1", since = "1.0.0")]
871     impl PartialEq for () {
872         #[inline]
873         fn eq(&self, _other: &()) -> bool { true }
874         #[inline]
875         fn ne(&self, _other: &()) -> bool { false }
876     }
877
878     partial_eq_impl! {
879         bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64
880     }
881
882     macro_rules! eq_impl {
883         ($($t:ty)*) => ($(
884             #[stable(feature = "rust1", since = "1.0.0")]
885             impl Eq for $t {}
886         )*)
887     }
888
889     eq_impl! { () bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
890
891     macro_rules! partial_ord_impl {
892         ($($t:ty)*) => ($(
893             #[stable(feature = "rust1", since = "1.0.0")]
894             impl PartialOrd for $t {
895                 #[inline]
896                 fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
897                     match (self <= other, self >= other) {
898                         (false, false) => None,
899                         (false, true) => Some(Greater),
900                         (true, false) => Some(Less),
901                         (true, true) => Some(Equal),
902                     }
903                 }
904                 #[inline]
905                 fn lt(&self, other: &$t) -> bool { (*self) < (*other) }
906                 #[inline]
907                 fn le(&self, other: &$t) -> bool { (*self) <= (*other) }
908                 #[inline]
909                 fn ge(&self, other: &$t) -> bool { (*self) >= (*other) }
910                 #[inline]
911                 fn gt(&self, other: &$t) -> bool { (*self) > (*other) }
912             }
913         )*)
914     }
915
916     #[stable(feature = "rust1", since = "1.0.0")]
917     impl PartialOrd for () {
918         #[inline]
919         fn partial_cmp(&self, _: &()) -> Option<Ordering> {
920             Some(Equal)
921         }
922     }
923
924     #[stable(feature = "rust1", since = "1.0.0")]
925     impl PartialOrd for bool {
926         #[inline]
927         fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
928             (*self as u8).partial_cmp(&(*other as u8))
929         }
930     }
931
932     partial_ord_impl! { f32 f64 }
933
934     macro_rules! ord_impl {
935         ($($t:ty)*) => ($(
936             #[stable(feature = "rust1", since = "1.0.0")]
937             impl PartialOrd for $t {
938                 #[inline]
939                 fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
940                     Some(self.cmp(other))
941                 }
942                 #[inline]
943                 fn lt(&self, other: &$t) -> bool { (*self) < (*other) }
944                 #[inline]
945                 fn le(&self, other: &$t) -> bool { (*self) <= (*other) }
946                 #[inline]
947                 fn ge(&self, other: &$t) -> bool { (*self) >= (*other) }
948                 #[inline]
949                 fn gt(&self, other: &$t) -> bool { (*self) > (*other) }
950             }
951
952             #[stable(feature = "rust1", since = "1.0.0")]
953             impl Ord for $t {
954                 #[inline]
955                 fn cmp(&self, other: &$t) -> Ordering {
956                     if *self == *other { Equal }
957                     else if *self < *other { Less }
958                     else { Greater }
959                 }
960             }
961         )*)
962     }
963
964     #[stable(feature = "rust1", since = "1.0.0")]
965     impl Ord for () {
966         #[inline]
967         fn cmp(&self, _other: &()) -> Ordering { Equal }
968     }
969
970     #[stable(feature = "rust1", since = "1.0.0")]
971     impl Ord for bool {
972         #[inline]
973         fn cmp(&self, other: &bool) -> Ordering {
974             (*self as u8).cmp(&(*other as u8))
975         }
976     }
977
978     ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
979
980     #[unstable(feature = "never_type", issue = "35121")]
981     impl PartialEq for ! {
982         fn eq(&self, _: &!) -> bool {
983             *self
984         }
985     }
986
987     #[unstable(feature = "never_type", issue = "35121")]
988     impl Eq for ! {}
989
990     #[unstable(feature = "never_type", issue = "35121")]
991     impl PartialOrd for ! {
992         fn partial_cmp(&self, _: &!) -> Option<Ordering> {
993             *self
994         }
995     }
996
997     #[unstable(feature = "never_type", issue = "35121")]
998     impl Ord for ! {
999         fn cmp(&self, _: &!) -> Ordering {
1000             *self
1001         }
1002     }
1003
1004     // & pointers
1005
1006     #[stable(feature = "rust1", since = "1.0.0")]
1007     impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b B> for &'a A where A: PartialEq<B> {
1008         #[inline]
1009         fn eq(&self, other: & &'b B) -> bool { PartialEq::eq(*self, *other) }
1010         #[inline]
1011         fn ne(&self, other: & &'b B) -> bool { PartialEq::ne(*self, *other) }
1012     }
1013     #[stable(feature = "rust1", since = "1.0.0")]
1014     impl<'a, 'b, A: ?Sized, B: ?Sized> PartialOrd<&'b B> for &'a A where A: PartialOrd<B> {
1015         #[inline]
1016         fn partial_cmp(&self, other: &&'b B) -> Option<Ordering> {
1017             PartialOrd::partial_cmp(*self, *other)
1018         }
1019         #[inline]
1020         fn lt(&self, other: & &'b B) -> bool { PartialOrd::lt(*self, *other) }
1021         #[inline]
1022         fn le(&self, other: & &'b B) -> bool { PartialOrd::le(*self, *other) }
1023         #[inline]
1024         fn ge(&self, other: & &'b B) -> bool { PartialOrd::ge(*self, *other) }
1025         #[inline]
1026         fn gt(&self, other: & &'b B) -> bool { PartialOrd::gt(*self, *other) }
1027     }
1028     #[stable(feature = "rust1", since = "1.0.0")]
1029     impl<A: ?Sized> Ord for &A where A: Ord {
1030         #[inline]
1031         fn cmp(&self, other: &Self) -> Ordering { Ord::cmp(*self, *other) }
1032     }
1033     #[stable(feature = "rust1", since = "1.0.0")]
1034     impl<A: ?Sized> Eq for &A where A: Eq {}
1035
1036     // &mut pointers
1037
1038     #[stable(feature = "rust1", since = "1.0.0")]
1039     impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b mut B> for &'a mut A where A: PartialEq<B> {
1040         #[inline]
1041         fn eq(&self, other: &&'b mut B) -> bool { PartialEq::eq(*self, *other) }
1042         #[inline]
1043         fn ne(&self, other: &&'b mut B) -> bool { PartialEq::ne(*self, *other) }
1044     }
1045     #[stable(feature = "rust1", since = "1.0.0")]
1046     impl<'a, 'b, A: ?Sized, B: ?Sized> PartialOrd<&'b mut B> for &'a mut A where A: PartialOrd<B> {
1047         #[inline]
1048         fn partial_cmp(&self, other: &&'b mut B) -> Option<Ordering> {
1049             PartialOrd::partial_cmp(*self, *other)
1050         }
1051         #[inline]
1052         fn lt(&self, other: &&'b mut B) -> bool { PartialOrd::lt(*self, *other) }
1053         #[inline]
1054         fn le(&self, other: &&'b mut B) -> bool { PartialOrd::le(*self, *other) }
1055         #[inline]
1056         fn ge(&self, other: &&'b mut B) -> bool { PartialOrd::ge(*self, *other) }
1057         #[inline]
1058         fn gt(&self, other: &&'b mut B) -> bool { PartialOrd::gt(*self, *other) }
1059     }
1060     #[stable(feature = "rust1", since = "1.0.0")]
1061     impl<A: ?Sized> Ord for &mut A where A: Ord {
1062         #[inline]
1063         fn cmp(&self, other: &Self) -> Ordering { Ord::cmp(*self, *other) }
1064     }
1065     #[stable(feature = "rust1", since = "1.0.0")]
1066     impl<A: ?Sized> Eq for &mut A where A: Eq {}
1067
1068     #[stable(feature = "rust1", since = "1.0.0")]
1069     impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b mut B> for &'a A where A: PartialEq<B> {
1070         #[inline]
1071         fn eq(&self, other: &&'b mut B) -> bool { PartialEq::eq(*self, *other) }
1072         #[inline]
1073         fn ne(&self, other: &&'b mut B) -> bool { PartialEq::ne(*self, *other) }
1074     }
1075
1076     #[stable(feature = "rust1", since = "1.0.0")]
1077     impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b B> for &'a mut A where A: PartialEq<B> {
1078         #[inline]
1079         fn eq(&self, other: &&'b B) -> bool { PartialEq::eq(*self, *other) }
1080         #[inline]
1081         fn ne(&self, other: &&'b B) -> bool { PartialEq::ne(*self, *other) }
1082     }
1083 }