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