]> git.lizzy.rs Git - rust.git/blob - library/core/src/cmp.rs
Auto merge of #100848 - xfix:use-metadata-for-slice-len, r=thomcc
[rust.git] / library / core / src / cmp.rs
1 //! Utilities for comparing and ordering values.
2 //!
3 //! This module contains various tools for comparing and ordering 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 //! [`max`]: Ord::max
21 //! [`min`]: Ord::min
22
23 #![stable(feature = "rust1", since = "1.0.0")]
24
25 use crate::const_closure::ConstFnMutClosure;
26 use crate::marker::Destruct;
27 use crate::marker::StructuralPartialEq;
28
29 use self::Ordering::*;
30
31 /// Trait for equality comparisons which are [partial equivalence
32 /// relations](https://en.wikipedia.org/wiki/Partial_equivalence_relation).
33 ///
34 /// `x.eq(y)` can also be written `x == y`, and `x.ne(y)` can be written `x != y`.
35 /// We use the easier-to-read infix notation in the remainder of this documentation.
36 ///
37 /// This trait allows for partial equality, for types that do not have a full
38 /// equivalence relation. For example, in floating point numbers `NaN != NaN`,
39 /// so floating point types implement `PartialEq` but not [`trait@Eq`].
40 ///
41 /// Implementations must ensure that `eq` and `ne` are consistent with each other:
42 ///
43 /// - `a != b` if and only if `!(a == b)`.
44 ///
45 /// The default implementation of `ne` provides this consistency and is almost
46 /// always sufficient. It should not be overridden without very good reason.
47 ///
48 /// If [`PartialOrd`] or [`Ord`] are also implemented for `Self` and `Rhs`, their methods must also
49 /// be consistent with `PartialEq` (see the documentation of those traits for the exact
50 /// requirements). It's easy to accidentally make them disagree by deriving some of the traits and
51 /// manually implementing others.
52 ///
53 /// The equality relation `==` must satisfy the following conditions
54 /// (for all `a`, `b`, `c` of type `A`, `B`, `C`):
55 ///
56 /// - **Symmetric**: if `A: PartialEq<B>` and `B: PartialEq<A>`, then **`a == b`
57 ///   implies `b == a`**; and
58 ///
59 /// - **Transitive**: if `A: PartialEq<B>` and `B: PartialEq<C>` and `A:
60 ///   PartialEq<C>`, then **`a == b` and `b == c` implies `a == c`**.
61 ///
62 /// Note that the `B: PartialEq<A>` (symmetric) and `A: PartialEq<C>`
63 /// (transitive) impls are not forced to exist, but these requirements apply
64 /// whenever they do exist.
65 ///
66 /// ## Derivable
67 ///
68 /// This trait can be used with `#[derive]`. When `derive`d on structs, two
69 /// instances are equal if all fields are equal, and not equal if any fields
70 /// are not equal. When `derive`d on enums, two instances are equal if they
71 /// are the same variant and all fields are equal.
72 ///
73 /// ## How can I implement `PartialEq`?
74 ///
75 /// An example implementation for a domain in which two books are considered
76 /// the same book if their ISBN matches, even if the formats differ:
77 ///
78 /// ```
79 /// enum BookFormat {
80 ///     Paperback,
81 ///     Hardback,
82 ///     Ebook,
83 /// }
84 ///
85 /// struct Book {
86 ///     isbn: i32,
87 ///     format: BookFormat,
88 /// }
89 ///
90 /// impl PartialEq for Book {
91 ///     fn eq(&self, other: &Self) -> bool {
92 ///         self.isbn == other.isbn
93 ///     }
94 /// }
95 ///
96 /// let b1 = Book { isbn: 3, format: BookFormat::Paperback };
97 /// let b2 = Book { isbn: 3, format: BookFormat::Ebook };
98 /// let b3 = Book { isbn: 10, format: BookFormat::Paperback };
99 ///
100 /// assert!(b1 == b2);
101 /// assert!(b1 != b3);
102 /// ```
103 ///
104 /// ## How can I compare two different types?
105 ///
106 /// The type you can compare with is controlled by `PartialEq`'s type parameter.
107 /// For example, let's tweak our previous code a bit:
108 ///
109 /// ```
110 /// // The derive implements <BookFormat> == <BookFormat> comparisons
111 /// #[derive(PartialEq)]
112 /// enum BookFormat {
113 ///     Paperback,
114 ///     Hardback,
115 ///     Ebook,
116 /// }
117 ///
118 /// struct Book {
119 ///     isbn: i32,
120 ///     format: BookFormat,
121 /// }
122 ///
123 /// // Implement <Book> == <BookFormat> comparisons
124 /// impl PartialEq<BookFormat> for Book {
125 ///     fn eq(&self, other: &BookFormat) -> bool {
126 ///         self.format == *other
127 ///     }
128 /// }
129 ///
130 /// // Implement <BookFormat> == <Book> comparisons
131 /// impl PartialEq<Book> for BookFormat {
132 ///     fn eq(&self, other: &Book) -> bool {
133 ///         *self == other.format
134 ///     }
135 /// }
136 ///
137 /// let b1 = Book { isbn: 3, format: BookFormat::Paperback };
138 ///
139 /// assert!(b1 == BookFormat::Paperback);
140 /// assert!(BookFormat::Ebook != b1);
141 /// ```
142 ///
143 /// By changing `impl PartialEq for Book` to `impl PartialEq<BookFormat> for Book`,
144 /// we allow `BookFormat`s to be compared with `Book`s.
145 ///
146 /// A comparison like the one above, which ignores some fields of the struct,
147 /// can be dangerous. It can easily lead to an unintended violation of the
148 /// requirements for a partial equivalence relation. For example, if we kept
149 /// the above implementation of `PartialEq<Book>` for `BookFormat` and added an
150 /// implementation of `PartialEq<Book>` for `Book` (either via a `#[derive]` or
151 /// via the manual implementation from the first example) then the result would
152 /// violate transitivity:
153 ///
154 /// ```should_panic
155 /// #[derive(PartialEq)]
156 /// enum BookFormat {
157 ///     Paperback,
158 ///     Hardback,
159 ///     Ebook,
160 /// }
161 ///
162 /// #[derive(PartialEq)]
163 /// struct Book {
164 ///     isbn: i32,
165 ///     format: BookFormat,
166 /// }
167 ///
168 /// impl PartialEq<BookFormat> for Book {
169 ///     fn eq(&self, other: &BookFormat) -> bool {
170 ///         self.format == *other
171 ///     }
172 /// }
173 ///
174 /// impl PartialEq<Book> for BookFormat {
175 ///     fn eq(&self, other: &Book) -> bool {
176 ///         *self == other.format
177 ///     }
178 /// }
179 ///
180 /// fn main() {
181 ///     let b1 = Book { isbn: 1, format: BookFormat::Paperback };
182 ///     let b2 = Book { isbn: 2, format: BookFormat::Paperback };
183 ///
184 ///     assert!(b1 == BookFormat::Paperback);
185 ///     assert!(BookFormat::Paperback == b2);
186 ///
187 ///     // The following should hold by transitivity but doesn't.
188 ///     assert!(b1 == b2); // <-- PANICS
189 /// }
190 /// ```
191 ///
192 /// # Examples
193 ///
194 /// ```
195 /// let x: u32 = 0;
196 /// let y: u32 = 1;
197 ///
198 /// assert_eq!(x == y, false);
199 /// assert_eq!(x.eq(&y), false);
200 /// ```
201 ///
202 /// [`eq`]: PartialEq::eq
203 /// [`ne`]: PartialEq::ne
204 #[lang = "eq"]
205 #[stable(feature = "rust1", since = "1.0.0")]
206 #[doc(alias = "==")]
207 #[doc(alias = "!=")]
208 #[rustc_on_unimplemented(
209     message = "can't compare `{Self}` with `{Rhs}`",
210     label = "no implementation for `{Self} == {Rhs}`",
211     append_const_msg
212 )]
213 #[const_trait]
214 #[rustc_diagnostic_item = "PartialEq"]
215 pub trait PartialEq<Rhs: ?Sized = Self> {
216     /// This method tests for `self` and `other` values to be equal, and is used
217     /// by `==`.
218     #[must_use]
219     #[stable(feature = "rust1", since = "1.0.0")]
220     fn eq(&self, other: &Rhs) -> bool;
221
222     /// This method tests for `!=`. The default implementation is almost always
223     /// sufficient, and should not be overridden without very good reason.
224     #[inline]
225     #[must_use]
226     #[stable(feature = "rust1", since = "1.0.0")]
227     fn ne(&self, other: &Rhs) -> bool {
228         !self.eq(other)
229     }
230 }
231
232 /// Derive macro generating an impl of the trait `PartialEq`.
233 #[rustc_builtin_macro]
234 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
235 #[allow_internal_unstable(core_intrinsics, structural_match)]
236 pub macro PartialEq($item:item) {
237     /* compiler built-in */
238 }
239
240 /// Trait for equality comparisons which are [equivalence relations](
241 /// https://en.wikipedia.org/wiki/Equivalence_relation).
242 ///
243 /// This means, that in addition to `a == b` and `a != b` being strict inverses, the equality must
244 /// be (for all `a`, `b` and `c`):
245 ///
246 /// - reflexive: `a == a`;
247 /// - symmetric: `a == b` implies `b == a`; and
248 /// - transitive: `a == b` and `b == c` implies `a == c`.
249 ///
250 /// This property cannot be checked by the compiler, and therefore `Eq` implies
251 /// [`PartialEq`], and has no extra methods.
252 ///
253 /// ## Derivable
254 ///
255 /// This trait can be used with `#[derive]`. When `derive`d, because `Eq` has
256 /// no extra methods, it is only informing the compiler that this is an
257 /// equivalence relation rather than a partial equivalence relation. Note that
258 /// the `derive` strategy requires all fields are `Eq`, which isn't
259 /// always desired.
260 ///
261 /// ## How can I implement `Eq`?
262 ///
263 /// If you cannot use the `derive` strategy, specify that your type implements
264 /// `Eq`, which has no methods:
265 ///
266 /// ```
267 /// enum BookFormat { Paperback, Hardback, Ebook }
268 /// struct Book {
269 ///     isbn: i32,
270 ///     format: BookFormat,
271 /// }
272 /// impl PartialEq for Book {
273 ///     fn eq(&self, other: &Self) -> bool {
274 ///         self.isbn == other.isbn
275 ///     }
276 /// }
277 /// impl Eq for Book {}
278 /// ```
279 #[doc(alias = "==")]
280 #[doc(alias = "!=")]
281 #[stable(feature = "rust1", since = "1.0.0")]
282 #[rustc_diagnostic_item = "Eq"]
283 pub trait Eq: PartialEq<Self> {
284     // this method is used solely by #[deriving] to assert
285     // that every component of a type implements #[deriving]
286     // itself, the current deriving infrastructure means doing this
287     // assertion without using a method on this trait is nearly
288     // impossible.
289     //
290     // This should never be implemented by hand.
291     #[doc(hidden)]
292     #[no_coverage] // rust-lang/rust#84605
293     #[inline]
294     #[stable(feature = "rust1", since = "1.0.0")]
295     fn assert_receiver_is_total_eq(&self) {}
296 }
297
298 /// Derive macro generating an impl of the trait `Eq`.
299 #[rustc_builtin_macro]
300 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
301 #[allow_internal_unstable(core_intrinsics, derive_eq, structural_match, no_coverage)]
302 pub macro Eq($item:item) {
303     /* compiler built-in */
304 }
305
306 // FIXME: this struct is used solely by #[derive] to
307 // assert that every component of a type implements Eq.
308 //
309 // This struct should never appear in user code.
310 #[doc(hidden)]
311 #[allow(missing_debug_implementations)]
312 #[unstable(feature = "derive_eq", reason = "deriving hack, should not be public", issue = "none")]
313 pub struct AssertParamIsEq<T: Eq + ?Sized> {
314     _field: crate::marker::PhantomData<T>,
315 }
316
317 /// An `Ordering` is the result of a comparison between two values.
318 ///
319 /// # Examples
320 ///
321 /// ```
322 /// use std::cmp::Ordering;
323 ///
324 /// let result = 1.cmp(&2);
325 /// assert_eq!(Ordering::Less, result);
326 ///
327 /// let result = 1.cmp(&1);
328 /// assert_eq!(Ordering::Equal, result);
329 ///
330 /// let result = 2.cmp(&1);
331 /// assert_eq!(Ordering::Greater, result);
332 /// ```
333 #[derive(Clone, Copy, Eq, Debug, Hash)]
334 #[stable(feature = "rust1", since = "1.0.0")]
335 #[repr(i8)]
336 pub enum Ordering {
337     /// An ordering where a compared value is less than another.
338     #[stable(feature = "rust1", since = "1.0.0")]
339     Less = -1,
340     /// An ordering where a compared value is equal to another.
341     #[stable(feature = "rust1", since = "1.0.0")]
342     Equal = 0,
343     /// An ordering where a compared value is greater than another.
344     #[stable(feature = "rust1", since = "1.0.0")]
345     Greater = 1,
346 }
347
348 impl Ordering {
349     /// Returns `true` if the ordering is the `Equal` variant.
350     ///
351     /// # Examples
352     ///
353     /// ```
354     /// use std::cmp::Ordering;
355     ///
356     /// assert_eq!(Ordering::Less.is_eq(), false);
357     /// assert_eq!(Ordering::Equal.is_eq(), true);
358     /// assert_eq!(Ordering::Greater.is_eq(), false);
359     /// ```
360     #[inline]
361     #[must_use]
362     #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
363     #[stable(feature = "ordering_helpers", since = "1.53.0")]
364     pub const fn is_eq(self) -> bool {
365         matches!(self, Equal)
366     }
367
368     /// Returns `true` if the ordering is not the `Equal` variant.
369     ///
370     /// # Examples
371     ///
372     /// ```
373     /// use std::cmp::Ordering;
374     ///
375     /// assert_eq!(Ordering::Less.is_ne(), true);
376     /// assert_eq!(Ordering::Equal.is_ne(), false);
377     /// assert_eq!(Ordering::Greater.is_ne(), true);
378     /// ```
379     #[inline]
380     #[must_use]
381     #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
382     #[stable(feature = "ordering_helpers", since = "1.53.0")]
383     pub const fn is_ne(self) -> bool {
384         !matches!(self, Equal)
385     }
386
387     /// Returns `true` if the ordering is the `Less` variant.
388     ///
389     /// # Examples
390     ///
391     /// ```
392     /// use std::cmp::Ordering;
393     ///
394     /// assert_eq!(Ordering::Less.is_lt(), true);
395     /// assert_eq!(Ordering::Equal.is_lt(), false);
396     /// assert_eq!(Ordering::Greater.is_lt(), false);
397     /// ```
398     #[inline]
399     #[must_use]
400     #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
401     #[stable(feature = "ordering_helpers", since = "1.53.0")]
402     pub const fn is_lt(self) -> bool {
403         matches!(self, Less)
404     }
405
406     /// Returns `true` if the ordering is the `Greater` variant.
407     ///
408     /// # Examples
409     ///
410     /// ```
411     /// use std::cmp::Ordering;
412     ///
413     /// assert_eq!(Ordering::Less.is_gt(), false);
414     /// assert_eq!(Ordering::Equal.is_gt(), false);
415     /// assert_eq!(Ordering::Greater.is_gt(), true);
416     /// ```
417     #[inline]
418     #[must_use]
419     #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
420     #[stable(feature = "ordering_helpers", since = "1.53.0")]
421     pub const fn is_gt(self) -> bool {
422         matches!(self, Greater)
423     }
424
425     /// Returns `true` if the ordering is either the `Less` or `Equal` variant.
426     ///
427     /// # Examples
428     ///
429     /// ```
430     /// use std::cmp::Ordering;
431     ///
432     /// assert_eq!(Ordering::Less.is_le(), true);
433     /// assert_eq!(Ordering::Equal.is_le(), true);
434     /// assert_eq!(Ordering::Greater.is_le(), false);
435     /// ```
436     #[inline]
437     #[must_use]
438     #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
439     #[stable(feature = "ordering_helpers", since = "1.53.0")]
440     pub const fn is_le(self) -> bool {
441         !matches!(self, Greater)
442     }
443
444     /// Returns `true` if the ordering is either the `Greater` or `Equal` variant.
445     ///
446     /// # Examples
447     ///
448     /// ```
449     /// use std::cmp::Ordering;
450     ///
451     /// assert_eq!(Ordering::Less.is_ge(), false);
452     /// assert_eq!(Ordering::Equal.is_ge(), true);
453     /// assert_eq!(Ordering::Greater.is_ge(), true);
454     /// ```
455     #[inline]
456     #[must_use]
457     #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
458     #[stable(feature = "ordering_helpers", since = "1.53.0")]
459     pub const fn is_ge(self) -> bool {
460         !matches!(self, Less)
461     }
462
463     /// Reverses the `Ordering`.
464     ///
465     /// * `Less` becomes `Greater`.
466     /// * `Greater` becomes `Less`.
467     /// * `Equal` becomes `Equal`.
468     ///
469     /// # Examples
470     ///
471     /// Basic behavior:
472     ///
473     /// ```
474     /// use std::cmp::Ordering;
475     ///
476     /// assert_eq!(Ordering::Less.reverse(), Ordering::Greater);
477     /// assert_eq!(Ordering::Equal.reverse(), Ordering::Equal);
478     /// assert_eq!(Ordering::Greater.reverse(), Ordering::Less);
479     /// ```
480     ///
481     /// This method can be used to reverse a comparison:
482     ///
483     /// ```
484     /// let data: &mut [_] = &mut [2, 10, 5, 8];
485     ///
486     /// // sort the array from largest to smallest.
487     /// data.sort_by(|a, b| a.cmp(b).reverse());
488     ///
489     /// let b: &mut [_] = &mut [10, 8, 5, 2];
490     /// assert!(data == b);
491     /// ```
492     #[inline]
493     #[must_use]
494     #[rustc_const_stable(feature = "const_ordering", since = "1.48.0")]
495     #[stable(feature = "rust1", since = "1.0.0")]
496     pub const fn reverse(self) -> Ordering {
497         match self {
498             Less => Greater,
499             Equal => Equal,
500             Greater => Less,
501         }
502     }
503
504     /// Chains two orderings.
505     ///
506     /// Returns `self` when it's not `Equal`. Otherwise returns `other`.
507     ///
508     /// # Examples
509     ///
510     /// ```
511     /// use std::cmp::Ordering;
512     ///
513     /// let result = Ordering::Equal.then(Ordering::Less);
514     /// assert_eq!(result, Ordering::Less);
515     ///
516     /// let result = Ordering::Less.then(Ordering::Equal);
517     /// assert_eq!(result, Ordering::Less);
518     ///
519     /// let result = Ordering::Less.then(Ordering::Greater);
520     /// assert_eq!(result, Ordering::Less);
521     ///
522     /// let result = Ordering::Equal.then(Ordering::Equal);
523     /// assert_eq!(result, Ordering::Equal);
524     ///
525     /// let x: (i64, i64, i64) = (1, 2, 7);
526     /// let y: (i64, i64, i64) = (1, 5, 3);
527     /// let result = x.0.cmp(&y.0).then(x.1.cmp(&y.1)).then(x.2.cmp(&y.2));
528     ///
529     /// assert_eq!(result, Ordering::Less);
530     /// ```
531     #[inline]
532     #[must_use]
533     #[rustc_const_stable(feature = "const_ordering", since = "1.48.0")]
534     #[stable(feature = "ordering_chaining", since = "1.17.0")]
535     pub const fn then(self, other: Ordering) -> Ordering {
536         match self {
537             Equal => other,
538             _ => self,
539         }
540     }
541
542     /// Chains the ordering with the given function.
543     ///
544     /// Returns `self` when it's not `Equal`. Otherwise calls `f` and returns
545     /// the result.
546     ///
547     /// # Examples
548     ///
549     /// ```
550     /// use std::cmp::Ordering;
551     ///
552     /// let result = Ordering::Equal.then_with(|| Ordering::Less);
553     /// assert_eq!(result, Ordering::Less);
554     ///
555     /// let result = Ordering::Less.then_with(|| Ordering::Equal);
556     /// assert_eq!(result, Ordering::Less);
557     ///
558     /// let result = Ordering::Less.then_with(|| Ordering::Greater);
559     /// assert_eq!(result, Ordering::Less);
560     ///
561     /// let result = Ordering::Equal.then_with(|| Ordering::Equal);
562     /// assert_eq!(result, Ordering::Equal);
563     ///
564     /// let x: (i64, i64, i64) = (1, 2, 7);
565     /// let y: (i64, i64, i64) = (1, 5, 3);
566     /// let result = x.0.cmp(&y.0).then_with(|| x.1.cmp(&y.1)).then_with(|| x.2.cmp(&y.2));
567     ///
568     /// assert_eq!(result, Ordering::Less);
569     /// ```
570     #[inline]
571     #[must_use]
572     #[stable(feature = "ordering_chaining", since = "1.17.0")]
573     pub fn then_with<F: FnOnce() -> Ordering>(self, f: F) -> Ordering {
574         match self {
575             Equal => f(),
576             _ => self,
577         }
578     }
579 }
580
581 /// A helper struct for reverse ordering.
582 ///
583 /// This struct is a helper to be used with functions like [`Vec::sort_by_key`] and
584 /// can be used to reverse order a part of a key.
585 ///
586 /// [`Vec::sort_by_key`]: ../../std/vec/struct.Vec.html#method.sort_by_key
587 ///
588 /// # Examples
589 ///
590 /// ```
591 /// use std::cmp::Reverse;
592 ///
593 /// let mut v = vec![1, 2, 3, 4, 5, 6];
594 /// v.sort_by_key(|&num| (num > 3, Reverse(num)));
595 /// assert_eq!(v, vec![3, 2, 1, 6, 5, 4]);
596 /// ```
597 #[derive(PartialEq, Eq, Debug, Copy, Default, Hash)]
598 #[stable(feature = "reverse_cmp_key", since = "1.19.0")]
599 #[repr(transparent)]
600 pub struct Reverse<T>(#[stable(feature = "reverse_cmp_key", since = "1.19.0")] pub T);
601
602 #[stable(feature = "reverse_cmp_key", since = "1.19.0")]
603 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
604 impl<T: ~const PartialOrd> const PartialOrd for Reverse<T> {
605     #[inline]
606     fn partial_cmp(&self, other: &Reverse<T>) -> Option<Ordering> {
607         other.0.partial_cmp(&self.0)
608     }
609
610     #[inline]
611     fn lt(&self, other: &Self) -> bool {
612         other.0 < self.0
613     }
614     #[inline]
615     fn le(&self, other: &Self) -> bool {
616         other.0 <= self.0
617     }
618     #[inline]
619     fn gt(&self, other: &Self) -> bool {
620         other.0 > self.0
621     }
622     #[inline]
623     fn ge(&self, other: &Self) -> bool {
624         other.0 >= self.0
625     }
626 }
627
628 #[stable(feature = "reverse_cmp_key", since = "1.19.0")]
629 impl<T: Ord> Ord for Reverse<T> {
630     #[inline]
631     fn cmp(&self, other: &Reverse<T>) -> Ordering {
632         other.0.cmp(&self.0)
633     }
634 }
635
636 #[stable(feature = "reverse_cmp_key", since = "1.19.0")]
637 impl<T: Clone> Clone for Reverse<T> {
638     #[inline]
639     fn clone(&self) -> Reverse<T> {
640         Reverse(self.0.clone())
641     }
642
643     #[inline]
644     fn clone_from(&mut self, other: &Self) {
645         self.0.clone_from(&other.0)
646     }
647 }
648
649 /// Trait for types that form a [total order](https://en.wikipedia.org/wiki/Total_order).
650 ///
651 /// Implementations must be consistent with the [`PartialOrd`] implementation, and ensure
652 /// `max`, `min`, and `clamp` are consistent with `cmp`:
653 ///
654 /// - `partial_cmp(a, b) == Some(cmp(a, b))`.
655 /// - `max(a, b) == max_by(a, b, cmp)` (ensured by the default implementation).
656 /// - `min(a, b) == min_by(a, b, cmp)` (ensured by the default implementation).
657 /// - For `a.clamp(min, max)`, see the [method docs](#method.clamp)
658 ///   (ensured by the default implementation).
659 ///
660 /// It's easy to accidentally make `cmp` and `partial_cmp` disagree by
661 /// deriving some of the traits and manually implementing others.
662 ///
663 /// ## Corollaries
664 ///
665 /// From the above and the requirements of `PartialOrd`, it follows that `<` defines a strict total order.
666 /// This means that for all `a`, `b` and `c`:
667 ///
668 /// - exactly one of `a < b`, `a == b` or `a > b` is true; and
669 /// - `<` is transitive: `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
670 ///
671 /// ## Derivable
672 ///
673 /// This trait can be used with `#[derive]`.
674 ///
675 /// When `derive`d on structs, it will produce a
676 /// [lexicographic](https://en.wikipedia.org/wiki/Lexicographic_order) ordering
677 /// based on the top-to-bottom declaration order of the struct's members.
678 ///
679 /// When `derive`d on enums, variants are ordered by their discriminants.
680 /// By default, the discriminant is smallest for variants at the top, and
681 /// largest for variants at the bottom. Here's an example:
682 ///
683 /// ```
684 /// #[derive(PartialEq, Eq, PartialOrd, Ord)]
685 /// enum E {
686 ///     Top,
687 ///     Bottom,
688 /// }
689 ///
690 /// assert!(E::Top < E::Bottom);
691 /// ```
692 ///
693 /// However, manually setting the discriminants can override this default
694 /// behavior:
695 ///
696 /// ```
697 /// #[derive(PartialEq, Eq, PartialOrd, Ord)]
698 /// enum E {
699 ///     Top = 2,
700 ///     Bottom = 1,
701 /// }
702 ///
703 /// assert!(E::Bottom < E::Top);
704 /// ```
705 ///
706 /// ## Lexicographical comparison
707 ///
708 /// Lexicographical comparison is an operation with the following properties:
709 ///  - Two sequences are compared element by element.
710 ///  - The first mismatching element defines which sequence is lexicographically less or greater than the other.
711 ///  - If one sequence is a prefix of another, the shorter sequence is lexicographically less than the other.
712 ///  - If two sequence have equivalent elements and are of the same length, then the sequences are lexicographically equal.
713 ///  - An empty sequence is lexicographically less than any non-empty sequence.
714 ///  - Two empty sequences are lexicographically equal.
715 ///
716 /// ## How can I implement `Ord`?
717 ///
718 /// `Ord` requires that the type also be [`PartialOrd`] and [`Eq`] (which requires [`PartialEq`]).
719 ///
720 /// Then you must define an implementation for [`cmp`]. You may find it useful to use
721 /// [`cmp`] on your type's fields.
722 ///
723 /// Here's an example where you want to sort people by height only, disregarding `id`
724 /// and `name`:
725 ///
726 /// ```
727 /// use std::cmp::Ordering;
728 ///
729 /// #[derive(Eq)]
730 /// struct Person {
731 ///     id: u32,
732 ///     name: String,
733 ///     height: u32,
734 /// }
735 ///
736 /// impl Ord for Person {
737 ///     fn cmp(&self, other: &Self) -> Ordering {
738 ///         self.height.cmp(&other.height)
739 ///     }
740 /// }
741 ///
742 /// impl PartialOrd for Person {
743 ///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
744 ///         Some(self.cmp(other))
745 ///     }
746 /// }
747 ///
748 /// impl PartialEq for Person {
749 ///     fn eq(&self, other: &Self) -> bool {
750 ///         self.height == other.height
751 ///     }
752 /// }
753 /// ```
754 ///
755 /// [`cmp`]: Ord::cmp
756 #[doc(alias = "<")]
757 #[doc(alias = ">")]
758 #[doc(alias = "<=")]
759 #[doc(alias = ">=")]
760 #[stable(feature = "rust1", since = "1.0.0")]
761 #[rustc_diagnostic_item = "Ord"]
762 #[const_trait]
763 pub trait Ord: Eq + PartialOrd<Self> {
764     /// This method returns an [`Ordering`] between `self` and `other`.
765     ///
766     /// By convention, `self.cmp(&other)` returns the ordering matching the expression
767     /// `self <operator> other` if true.
768     ///
769     /// # Examples
770     ///
771     /// ```
772     /// use std::cmp::Ordering;
773     ///
774     /// assert_eq!(5.cmp(&10), Ordering::Less);
775     /// assert_eq!(10.cmp(&5), Ordering::Greater);
776     /// assert_eq!(5.cmp(&5), Ordering::Equal);
777     /// ```
778     #[must_use]
779     #[stable(feature = "rust1", since = "1.0.0")]
780     fn cmp(&self, other: &Self) -> Ordering;
781
782     /// Compares and returns the maximum of two values.
783     ///
784     /// Returns the second argument if the comparison determines them to be equal.
785     ///
786     /// # Examples
787     ///
788     /// ```
789     /// assert_eq!(2, 1.max(2));
790     /// assert_eq!(2, 2.max(2));
791     /// ```
792     #[stable(feature = "ord_max_min", since = "1.21.0")]
793     #[inline]
794     #[must_use]
795     fn max(self, other: Self) -> Self
796     where
797         Self: Sized,
798         Self: ~const Destruct,
799     {
800         // HACK(fee1-dead): go back to using `self.max_by(other, Ord::cmp)`
801         // when trait methods are allowed to be used when a const closure is
802         // expected.
803         match self.cmp(&other) {
804             Ordering::Less | Ordering::Equal => other,
805             Ordering::Greater => self,
806         }
807     }
808
809     /// Compares and returns the minimum of two values.
810     ///
811     /// Returns the first argument if the comparison determines them to be equal.
812     ///
813     /// # Examples
814     ///
815     /// ```
816     /// assert_eq!(1, 1.min(2));
817     /// assert_eq!(2, 2.min(2));
818     /// ```
819     #[stable(feature = "ord_max_min", since = "1.21.0")]
820     #[inline]
821     #[must_use]
822     fn min(self, other: Self) -> Self
823     where
824         Self: Sized,
825         Self: ~const Destruct,
826     {
827         // HACK(fee1-dead): go back to using `self.min_by(other, Ord::cmp)`
828         // when trait methods are allowed to be used when a const closure is
829         // expected.
830         match self.cmp(&other) {
831             Ordering::Less | Ordering::Equal => self,
832             Ordering::Greater => other,
833         }
834     }
835
836     /// Restrict a value to a certain interval.
837     ///
838     /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
839     /// less than `min`. Otherwise this returns `self`.
840     ///
841     /// # Panics
842     ///
843     /// Panics if `min > max`.
844     ///
845     /// # Examples
846     ///
847     /// ```
848     /// assert!((-3).clamp(-2, 1) == -2);
849     /// assert!(0.clamp(-2, 1) == 0);
850     /// assert!(2.clamp(-2, 1) == 1);
851     /// ```
852     #[must_use]
853     #[stable(feature = "clamp", since = "1.50.0")]
854     fn clamp(self, min: Self, max: Self) -> Self
855     where
856         Self: Sized,
857         Self: ~const Destruct,
858         Self: ~const PartialOrd,
859     {
860         assert!(min <= max);
861         if self < min {
862             min
863         } else if self > max {
864             max
865         } else {
866             self
867         }
868     }
869 }
870
871 /// Derive macro generating an impl of the trait `Ord`.
872 #[rustc_builtin_macro]
873 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
874 #[allow_internal_unstable(core_intrinsics)]
875 pub macro Ord($item:item) {
876     /* compiler built-in */
877 }
878
879 #[stable(feature = "rust1", since = "1.0.0")]
880 impl StructuralPartialEq for Ordering {}
881
882 #[stable(feature = "rust1", since = "1.0.0")]
883 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
884 impl const PartialEq for Ordering {
885     #[inline]
886     fn eq(&self, other: &Self) -> bool {
887         (*self as i32).eq(&(*other as i32))
888     }
889 }
890
891 #[stable(feature = "rust1", since = "1.0.0")]
892 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
893 impl const Ord for Ordering {
894     #[inline]
895     fn cmp(&self, other: &Ordering) -> Ordering {
896         (*self as i32).cmp(&(*other as i32))
897     }
898 }
899
900 #[stable(feature = "rust1", since = "1.0.0")]
901 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
902 impl const PartialOrd for Ordering {
903     #[inline]
904     fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
905         (*self as i32).partial_cmp(&(*other as i32))
906     }
907 }
908
909 /// Trait for types that form a [partial order](https://en.wikipedia.org/wiki/Partial_order).
910 ///
911 /// The `lt`, `le`, `gt`, and `ge` methods of this trait can be called using
912 /// the `<`, `<=`, `>`, and `>=` operators, respectively.
913 ///
914 /// The methods of this trait must be consistent with each other and with those of [`PartialEq`].
915 /// The following conditions must hold:
916 ///
917 /// 1. `a == b` if and only if `partial_cmp(a, b) == Some(Equal)`.
918 /// 2. `a < b` if and only if `partial_cmp(a, b) == Some(Less)`
919 /// 3. `a > b` if and only if `partial_cmp(a, b) == Some(Greater)`
920 /// 4. `a <= b` if and only if `a < b || a == b`
921 /// 5. `a >= b` if and only if `a > b || a == b`
922 /// 6. `a != b` if and only if `!(a == b)`.
923 ///
924 /// Conditions 2–5 above are ensured by the default implementation.
925 /// Condition 6 is already ensured by [`PartialEq`].
926 ///
927 /// If [`Ord`] is also implemented for `Self` and `Rhs`, it must also be consistent with
928 /// `partial_cmp` (see the documentation of that trait for the exact requirements). It's
929 /// easy to accidentally make them disagree by deriving some of the traits and manually
930 /// implementing others.
931 ///
932 /// The comparison must satisfy, for all `a`, `b` and `c`:
933 ///
934 /// - transitivity: `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
935 /// - duality: `a < b` if and only if `b > a`.
936 ///
937 /// Note that these requirements mean that the trait itself must be implemented symmetrically and
938 /// transitively: if `T: PartialOrd<U>` and `U: PartialOrd<V>` then `U: PartialOrd<T>` and `T:
939 /// PartialOrd<V>`.
940 ///
941 /// ## Corollaries
942 ///
943 /// The following corollaries follow from the above requirements:
944 ///
945 /// - irreflexivity of `<` and `>`: `!(a < a)`, `!(a > a)`
946 /// - transitivity of `>`: if `a > b` and `b > c` then `a > c`
947 /// - duality of `partial_cmp`: `partial_cmp(a, b) == partial_cmp(b, a).map(Ordering::reverse)`
948 ///
949 /// ## Derivable
950 ///
951 /// This trait can be used with `#[derive]`.
952 ///
953 /// When `derive`d on structs, it will produce a
954 /// [lexicographic](https://en.wikipedia.org/wiki/Lexicographic_order) ordering
955 /// based on the top-to-bottom declaration order of the struct's members.
956 ///
957 /// When `derive`d on enums, variants are ordered by their discriminants.
958 /// By default, the discriminant is smallest for variants at the top, and
959 /// largest for variants at the bottom. Here's an example:
960 ///
961 /// ```
962 /// #[derive(PartialEq, PartialOrd)]
963 /// enum E {
964 ///     Top,
965 ///     Bottom,
966 /// }
967 ///
968 /// assert!(E::Top < E::Bottom);
969 /// ```
970 ///
971 /// However, manually setting the discriminants can override this default
972 /// behavior:
973 ///
974 /// ```
975 /// #[derive(PartialEq, PartialOrd)]
976 /// enum E {
977 ///     Top = 2,
978 ///     Bottom = 1,
979 /// }
980 ///
981 /// assert!(E::Bottom < E::Top);
982 /// ```
983 ///
984 /// ## How can I implement `PartialOrd`?
985 ///
986 /// `PartialOrd` only requires implementation of the [`partial_cmp`] method, with the others
987 /// generated from default implementations.
988 ///
989 /// However it remains possible to implement the others separately for types which do not have a
990 /// total order. For example, for floating point numbers, `NaN < 0 == false` and `NaN >= 0 ==
991 /// false` (cf. IEEE 754-2008 section 5.11).
992 ///
993 /// `PartialOrd` requires your type to be [`PartialEq`].
994 ///
995 /// If your type is [`Ord`], you can implement [`partial_cmp`] by using [`cmp`]:
996 ///
997 /// ```
998 /// use std::cmp::Ordering;
999 ///
1000 /// #[derive(Eq)]
1001 /// struct Person {
1002 ///     id: u32,
1003 ///     name: String,
1004 ///     height: u32,
1005 /// }
1006 ///
1007 /// impl PartialOrd for Person {
1008 ///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1009 ///         Some(self.cmp(other))
1010 ///     }
1011 /// }
1012 ///
1013 /// impl Ord for Person {
1014 ///     fn cmp(&self, other: &Self) -> Ordering {
1015 ///         self.height.cmp(&other.height)
1016 ///     }
1017 /// }
1018 ///
1019 /// impl PartialEq for Person {
1020 ///     fn eq(&self, other: &Self) -> bool {
1021 ///         self.height == other.height
1022 ///     }
1023 /// }
1024 /// ```
1025 ///
1026 /// You may also find it useful to use [`partial_cmp`] on your type's fields. Here
1027 /// is an example of `Person` types who have a floating-point `height` field that
1028 /// is the only field to be used for sorting:
1029 ///
1030 /// ```
1031 /// use std::cmp::Ordering;
1032 ///
1033 /// struct Person {
1034 ///     id: u32,
1035 ///     name: String,
1036 ///     height: f64,
1037 /// }
1038 ///
1039 /// impl PartialOrd for Person {
1040 ///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1041 ///         self.height.partial_cmp(&other.height)
1042 ///     }
1043 /// }
1044 ///
1045 /// impl PartialEq for Person {
1046 ///     fn eq(&self, other: &Self) -> bool {
1047 ///         self.height == other.height
1048 ///     }
1049 /// }
1050 /// ```
1051 ///
1052 /// # Examples
1053 ///
1054 /// ```
1055 /// let x: u32 = 0;
1056 /// let y: u32 = 1;
1057 ///
1058 /// assert_eq!(x < y, true);
1059 /// assert_eq!(x.lt(&y), true);
1060 /// ```
1061 ///
1062 /// [`partial_cmp`]: PartialOrd::partial_cmp
1063 /// [`cmp`]: Ord::cmp
1064 #[lang = "partial_ord"]
1065 #[stable(feature = "rust1", since = "1.0.0")]
1066 #[doc(alias = ">")]
1067 #[doc(alias = "<")]
1068 #[doc(alias = "<=")]
1069 #[doc(alias = ">=")]
1070 #[rustc_on_unimplemented(
1071     message = "can't compare `{Self}` with `{Rhs}`",
1072     label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`",
1073     append_const_msg
1074 )]
1075 #[const_trait]
1076 #[rustc_diagnostic_item = "PartialOrd"]
1077 pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
1078     /// This method returns an ordering between `self` and `other` values if one exists.
1079     ///
1080     /// # Examples
1081     ///
1082     /// ```
1083     /// use std::cmp::Ordering;
1084     ///
1085     /// let result = 1.0.partial_cmp(&2.0);
1086     /// assert_eq!(result, Some(Ordering::Less));
1087     ///
1088     /// let result = 1.0.partial_cmp(&1.0);
1089     /// assert_eq!(result, Some(Ordering::Equal));
1090     ///
1091     /// let result = 2.0.partial_cmp(&1.0);
1092     /// assert_eq!(result, Some(Ordering::Greater));
1093     /// ```
1094     ///
1095     /// When comparison is impossible:
1096     ///
1097     /// ```
1098     /// let result = f64::NAN.partial_cmp(&1.0);
1099     /// assert_eq!(result, None);
1100     /// ```
1101     #[must_use]
1102     #[stable(feature = "rust1", since = "1.0.0")]
1103     fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
1104
1105     /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
1106     ///
1107     /// # Examples
1108     ///
1109     /// ```
1110     /// let result = 1.0 < 2.0;
1111     /// assert_eq!(result, true);
1112     ///
1113     /// let result = 2.0 < 1.0;
1114     /// assert_eq!(result, false);
1115     /// ```
1116     #[inline]
1117     #[must_use]
1118     #[stable(feature = "rust1", since = "1.0.0")]
1119     fn lt(&self, other: &Rhs) -> bool {
1120         matches!(self.partial_cmp(other), Some(Less))
1121     }
1122
1123     /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
1124     /// operator.
1125     ///
1126     /// # Examples
1127     ///
1128     /// ```
1129     /// let result = 1.0 <= 2.0;
1130     /// assert_eq!(result, true);
1131     ///
1132     /// let result = 2.0 <= 2.0;
1133     /// assert_eq!(result, true);
1134     /// ```
1135     #[inline]
1136     #[must_use]
1137     #[stable(feature = "rust1", since = "1.0.0")]
1138     fn le(&self, other: &Rhs) -> bool {
1139         matches!(self.partial_cmp(other), Some(Less | Equal))
1140     }
1141
1142     /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
1143     ///
1144     /// # Examples
1145     ///
1146     /// ```
1147     /// let result = 1.0 > 2.0;
1148     /// assert_eq!(result, false);
1149     ///
1150     /// let result = 2.0 > 2.0;
1151     /// assert_eq!(result, false);
1152     /// ```
1153     #[inline]
1154     #[must_use]
1155     #[stable(feature = "rust1", since = "1.0.0")]
1156     fn gt(&self, other: &Rhs) -> bool {
1157         matches!(self.partial_cmp(other), Some(Greater))
1158     }
1159
1160     /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
1161     /// operator.
1162     ///
1163     /// # Examples
1164     ///
1165     /// ```
1166     /// let result = 2.0 >= 1.0;
1167     /// assert_eq!(result, true);
1168     ///
1169     /// let result = 2.0 >= 2.0;
1170     /// assert_eq!(result, true);
1171     /// ```
1172     #[inline]
1173     #[must_use]
1174     #[stable(feature = "rust1", since = "1.0.0")]
1175     fn ge(&self, other: &Rhs) -> bool {
1176         matches!(self.partial_cmp(other), Some(Greater | Equal))
1177     }
1178 }
1179
1180 /// Derive macro generating an impl of the trait `PartialOrd`.
1181 #[rustc_builtin_macro]
1182 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
1183 #[allow_internal_unstable(core_intrinsics)]
1184 pub macro PartialOrd($item:item) {
1185     /* compiler built-in */
1186 }
1187
1188 /// Compares and returns the minimum of two values.
1189 ///
1190 /// Returns the first argument if the comparison determines them to be equal.
1191 ///
1192 /// Internally uses an alias to [`Ord::min`].
1193 ///
1194 /// # Examples
1195 ///
1196 /// ```
1197 /// use std::cmp;
1198 ///
1199 /// assert_eq!(1, cmp::min(1, 2));
1200 /// assert_eq!(2, cmp::min(2, 2));
1201 /// ```
1202 #[inline]
1203 #[must_use]
1204 #[stable(feature = "rust1", since = "1.0.0")]
1205 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1206 #[cfg_attr(not(test), rustc_diagnostic_item = "cmp_min")]
1207 pub const fn min<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T {
1208     v1.min(v2)
1209 }
1210
1211 /// Returns the minimum of two values with respect to the specified comparison function.
1212 ///
1213 /// Returns the first argument if the comparison determines them to be equal.
1214 ///
1215 /// # Examples
1216 ///
1217 /// ```
1218 /// use std::cmp;
1219 ///
1220 /// assert_eq!(cmp::min_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), 1);
1221 /// assert_eq!(cmp::min_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), -2);
1222 /// ```
1223 #[inline]
1224 #[must_use]
1225 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
1226 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1227 pub const fn min_by<T, F: ~const FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T
1228 where
1229     T: ~const Destruct,
1230     F: ~const Destruct,
1231 {
1232     match compare(&v1, &v2) {
1233         Ordering::Less | Ordering::Equal => v1,
1234         Ordering::Greater => v2,
1235     }
1236 }
1237
1238 /// Returns the element that gives the minimum value from the specified function.
1239 ///
1240 /// Returns the first argument if the comparison determines them to be equal.
1241 ///
1242 /// # Examples
1243 ///
1244 /// ```
1245 /// use std::cmp;
1246 ///
1247 /// assert_eq!(cmp::min_by_key(-2, 1, |x: &i32| x.abs()), 1);
1248 /// assert_eq!(cmp::min_by_key(-2, 2, |x: &i32| x.abs()), -2);
1249 /// ```
1250 #[inline]
1251 #[must_use]
1252 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
1253 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1254 pub const fn min_by_key<T, F: ~const FnMut(&T) -> K, K: ~const Ord>(v1: T, v2: T, mut f: F) -> T
1255 where
1256     T: ~const Destruct,
1257     F: ~const Destruct,
1258     K: ~const Destruct,
1259 {
1260     const fn imp<T, F: ~const FnMut(&T) -> K, K: ~const Ord>(
1261         f: &mut F,
1262         (v1, v2): (&T, &T),
1263     ) -> Ordering
1264     where
1265         T: ~const Destruct,
1266         K: ~const Destruct,
1267     {
1268         f(v1).cmp(&f(v2))
1269     }
1270     min_by(v1, v2, ConstFnMutClosure::new(&mut f, imp))
1271 }
1272
1273 /// Compares and returns the maximum of two values.
1274 ///
1275 /// Returns the second argument if the comparison determines them to be equal.
1276 ///
1277 /// Internally uses an alias to [`Ord::max`].
1278 ///
1279 /// # Examples
1280 ///
1281 /// ```
1282 /// use std::cmp;
1283 ///
1284 /// assert_eq!(2, cmp::max(1, 2));
1285 /// assert_eq!(2, cmp::max(2, 2));
1286 /// ```
1287 #[inline]
1288 #[must_use]
1289 #[stable(feature = "rust1", since = "1.0.0")]
1290 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1291 #[cfg_attr(not(test), rustc_diagnostic_item = "cmp_max")]
1292 pub const fn max<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T {
1293     v1.max(v2)
1294 }
1295
1296 /// Returns the maximum of two values with respect to the specified comparison function.
1297 ///
1298 /// Returns the second argument if the comparison determines them to be equal.
1299 ///
1300 /// # Examples
1301 ///
1302 /// ```
1303 /// use std::cmp;
1304 ///
1305 /// assert_eq!(cmp::max_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), -2);
1306 /// assert_eq!(cmp::max_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), 2);
1307 /// ```
1308 #[inline]
1309 #[must_use]
1310 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
1311 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1312 pub const fn max_by<T, F: ~const FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T
1313 where
1314     T: ~const Destruct,
1315     F: ~const Destruct,
1316 {
1317     match compare(&v1, &v2) {
1318         Ordering::Less | Ordering::Equal => v2,
1319         Ordering::Greater => v1,
1320     }
1321 }
1322
1323 /// Returns the element that gives the maximum value from the specified function.
1324 ///
1325 /// Returns the second argument if the comparison determines them to be equal.
1326 ///
1327 /// # Examples
1328 ///
1329 /// ```
1330 /// use std::cmp;
1331 ///
1332 /// assert_eq!(cmp::max_by_key(-2, 1, |x: &i32| x.abs()), -2);
1333 /// assert_eq!(cmp::max_by_key(-2, 2, |x: &i32| x.abs()), 2);
1334 /// ```
1335 #[inline]
1336 #[must_use]
1337 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
1338 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1339 pub const fn max_by_key<T, F: ~const FnMut(&T) -> K, K: ~const Ord>(v1: T, v2: T, mut f: F) -> T
1340 where
1341     T: ~const Destruct,
1342     F: ~const Destruct,
1343     K: ~const Destruct,
1344 {
1345     const fn imp<T, F: ~const FnMut(&T) -> K, K: ~const Ord>(
1346         f: &mut F,
1347         (v1, v2): (&T, &T),
1348     ) -> Ordering
1349     where
1350         T: ~const Destruct,
1351         K: ~const Destruct,
1352     {
1353         f(v1).cmp(&f(v2))
1354     }
1355     max_by(v1, v2, ConstFnMutClosure::new(&mut f, imp))
1356 }
1357
1358 // Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
1359 mod impls {
1360     use crate::cmp::Ordering::{self, Equal, Greater, Less};
1361     use crate::hint::unreachable_unchecked;
1362
1363     macro_rules! partial_eq_impl {
1364         ($($t:ty)*) => ($(
1365             #[stable(feature = "rust1", since = "1.0.0")]
1366             #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1367             impl const PartialEq for $t {
1368                 #[inline]
1369                 fn eq(&self, other: &$t) -> bool { (*self) == (*other) }
1370                 #[inline]
1371                 fn ne(&self, other: &$t) -> bool { (*self) != (*other) }
1372             }
1373         )*)
1374     }
1375
1376     #[stable(feature = "rust1", since = "1.0.0")]
1377     #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1378     impl const PartialEq for () {
1379         #[inline]
1380         fn eq(&self, _other: &()) -> bool {
1381             true
1382         }
1383         #[inline]
1384         fn ne(&self, _other: &()) -> bool {
1385             false
1386         }
1387     }
1388
1389     partial_eq_impl! {
1390         bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64
1391     }
1392
1393     macro_rules! eq_impl {
1394         ($($t:ty)*) => ($(
1395             #[stable(feature = "rust1", since = "1.0.0")]
1396             impl Eq for $t {}
1397         )*)
1398     }
1399
1400     eq_impl! { () bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
1401
1402     macro_rules! partial_ord_impl {
1403         ($($t:ty)*) => ($(
1404             #[stable(feature = "rust1", since = "1.0.0")]
1405             #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1406             impl const PartialOrd for $t {
1407                 #[inline]
1408                 fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
1409                     match (*self <= *other, *self >= *other) {
1410                         (false, false) => None,
1411                         (false, true) => Some(Greater),
1412                         (true, false) => Some(Less),
1413                         (true, true) => Some(Equal),
1414                     }
1415                 }
1416                 #[inline]
1417                 fn lt(&self, other: &$t) -> bool { (*self) < (*other) }
1418                 #[inline]
1419                 fn le(&self, other: &$t) -> bool { (*self) <= (*other) }
1420                 #[inline]
1421                 fn ge(&self, other: &$t) -> bool { (*self) >= (*other) }
1422                 #[inline]
1423                 fn gt(&self, other: &$t) -> bool { (*self) > (*other) }
1424             }
1425         )*)
1426     }
1427
1428     #[stable(feature = "rust1", since = "1.0.0")]
1429     #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1430     impl const PartialOrd for () {
1431         #[inline]
1432         fn partial_cmp(&self, _: &()) -> Option<Ordering> {
1433             Some(Equal)
1434         }
1435     }
1436
1437     #[stable(feature = "rust1", since = "1.0.0")]
1438     #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1439     impl const PartialOrd for bool {
1440         #[inline]
1441         fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
1442             Some(self.cmp(other))
1443         }
1444     }
1445
1446     partial_ord_impl! { f32 f64 }
1447
1448     macro_rules! ord_impl {
1449         ($($t:ty)*) => ($(
1450             #[stable(feature = "rust1", since = "1.0.0")]
1451             #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1452             impl const PartialOrd for $t {
1453                 #[inline]
1454                 fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
1455                     Some(self.cmp(other))
1456                 }
1457                 #[inline]
1458                 fn lt(&self, other: &$t) -> bool { (*self) < (*other) }
1459                 #[inline]
1460                 fn le(&self, other: &$t) -> bool { (*self) <= (*other) }
1461                 #[inline]
1462                 fn ge(&self, other: &$t) -> bool { (*self) >= (*other) }
1463                 #[inline]
1464                 fn gt(&self, other: &$t) -> bool { (*self) > (*other) }
1465             }
1466
1467             #[stable(feature = "rust1", since = "1.0.0")]
1468             #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1469             impl const Ord for $t {
1470                 #[inline]
1471                 fn cmp(&self, other: &$t) -> Ordering {
1472                     // The order here is important to generate more optimal assembly.
1473                     // See <https://github.com/rust-lang/rust/issues/63758> for more info.
1474                     if *self < *other { Less }
1475                     else if *self == *other { Equal }
1476                     else { Greater }
1477                 }
1478             }
1479         )*)
1480     }
1481
1482     #[stable(feature = "rust1", since = "1.0.0")]
1483     #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1484     impl const Ord for () {
1485         #[inline]
1486         fn cmp(&self, _other: &()) -> Ordering {
1487             Equal
1488         }
1489     }
1490
1491     #[stable(feature = "rust1", since = "1.0.0")]
1492     #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1493     impl const Ord for bool {
1494         #[inline]
1495         fn cmp(&self, other: &bool) -> Ordering {
1496             // Casting to i8's and converting the difference to an Ordering generates
1497             // more optimal assembly.
1498             // See <https://github.com/rust-lang/rust/issues/66780> for more info.
1499             match (*self as i8) - (*other as i8) {
1500                 -1 => Less,
1501                 0 => Equal,
1502                 1 => Greater,
1503                 // SAFETY: bool as i8 returns 0 or 1, so the difference can't be anything else
1504                 _ => unsafe { unreachable_unchecked() },
1505             }
1506         }
1507     }
1508
1509     ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
1510
1511     #[unstable(feature = "never_type", issue = "35121")]
1512     #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1513     impl const PartialEq for ! {
1514         fn eq(&self, _: &!) -> bool {
1515             *self
1516         }
1517     }
1518
1519     #[unstable(feature = "never_type", issue = "35121")]
1520     impl Eq for ! {}
1521
1522     #[unstable(feature = "never_type", issue = "35121")]
1523     #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1524     impl const PartialOrd for ! {
1525         fn partial_cmp(&self, _: &!) -> Option<Ordering> {
1526             *self
1527         }
1528     }
1529
1530     #[unstable(feature = "never_type", issue = "35121")]
1531     #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1532     impl const Ord for ! {
1533         fn cmp(&self, _: &!) -> Ordering {
1534             *self
1535         }
1536     }
1537
1538     // & pointers
1539
1540     #[stable(feature = "rust1", since = "1.0.0")]
1541     #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1542     impl<A: ?Sized, B: ?Sized> const PartialEq<&B> for &A
1543     where
1544         A: ~const PartialEq<B>,
1545     {
1546         #[inline]
1547         fn eq(&self, other: &&B) -> bool {
1548             PartialEq::eq(*self, *other)
1549         }
1550         #[inline]
1551         fn ne(&self, other: &&B) -> bool {
1552             PartialEq::ne(*self, *other)
1553         }
1554     }
1555     #[stable(feature = "rust1", since = "1.0.0")]
1556     impl<A: ?Sized, B: ?Sized> PartialOrd<&B> for &A
1557     where
1558         A: PartialOrd<B>,
1559     {
1560         #[inline]
1561         fn partial_cmp(&self, other: &&B) -> Option<Ordering> {
1562             PartialOrd::partial_cmp(*self, *other)
1563         }
1564         #[inline]
1565         fn lt(&self, other: &&B) -> bool {
1566             PartialOrd::lt(*self, *other)
1567         }
1568         #[inline]
1569         fn le(&self, other: &&B) -> bool {
1570             PartialOrd::le(*self, *other)
1571         }
1572         #[inline]
1573         fn gt(&self, other: &&B) -> bool {
1574             PartialOrd::gt(*self, *other)
1575         }
1576         #[inline]
1577         fn ge(&self, other: &&B) -> bool {
1578             PartialOrd::ge(*self, *other)
1579         }
1580     }
1581     #[stable(feature = "rust1", since = "1.0.0")]
1582     impl<A: ?Sized> Ord for &A
1583     where
1584         A: Ord,
1585     {
1586         #[inline]
1587         fn cmp(&self, other: &Self) -> Ordering {
1588             Ord::cmp(*self, *other)
1589         }
1590     }
1591     #[stable(feature = "rust1", since = "1.0.0")]
1592     impl<A: ?Sized> Eq for &A where A: Eq {}
1593
1594     // &mut pointers
1595
1596     #[stable(feature = "rust1", since = "1.0.0")]
1597     impl<A: ?Sized, B: ?Sized> PartialEq<&mut B> for &mut A
1598     where
1599         A: PartialEq<B>,
1600     {
1601         #[inline]
1602         fn eq(&self, other: &&mut B) -> bool {
1603             PartialEq::eq(*self, *other)
1604         }
1605         #[inline]
1606         fn ne(&self, other: &&mut B) -> bool {
1607             PartialEq::ne(*self, *other)
1608         }
1609     }
1610     #[stable(feature = "rust1", since = "1.0.0")]
1611     impl<A: ?Sized, B: ?Sized> PartialOrd<&mut B> for &mut A
1612     where
1613         A: PartialOrd<B>,
1614     {
1615         #[inline]
1616         fn partial_cmp(&self, other: &&mut B) -> Option<Ordering> {
1617             PartialOrd::partial_cmp(*self, *other)
1618         }
1619         #[inline]
1620         fn lt(&self, other: &&mut B) -> bool {
1621             PartialOrd::lt(*self, *other)
1622         }
1623         #[inline]
1624         fn le(&self, other: &&mut B) -> bool {
1625             PartialOrd::le(*self, *other)
1626         }
1627         #[inline]
1628         fn gt(&self, other: &&mut B) -> bool {
1629             PartialOrd::gt(*self, *other)
1630         }
1631         #[inline]
1632         fn ge(&self, other: &&mut B) -> bool {
1633             PartialOrd::ge(*self, *other)
1634         }
1635     }
1636     #[stable(feature = "rust1", since = "1.0.0")]
1637     impl<A: ?Sized> Ord for &mut A
1638     where
1639         A: Ord,
1640     {
1641         #[inline]
1642         fn cmp(&self, other: &Self) -> Ordering {
1643             Ord::cmp(*self, *other)
1644         }
1645     }
1646     #[stable(feature = "rust1", since = "1.0.0")]
1647     impl<A: ?Sized> Eq for &mut A where A: Eq {}
1648
1649     #[stable(feature = "rust1", since = "1.0.0")]
1650     impl<A: ?Sized, B: ?Sized> PartialEq<&mut B> for &A
1651     where
1652         A: PartialEq<B>,
1653     {
1654         #[inline]
1655         fn eq(&self, other: &&mut B) -> bool {
1656             PartialEq::eq(*self, *other)
1657         }
1658         #[inline]
1659         fn ne(&self, other: &&mut B) -> bool {
1660             PartialEq::ne(*self, *other)
1661         }
1662     }
1663
1664     #[stable(feature = "rust1", since = "1.0.0")]
1665     impl<A: ?Sized, B: ?Sized> PartialEq<&B> for &mut A
1666     where
1667         A: PartialEq<B>,
1668     {
1669         #[inline]
1670         fn eq(&self, other: &&B) -> bool {
1671             PartialEq::eq(*self, *other)
1672         }
1673         #[inline]
1674         fn ne(&self, other: &&B) -> bool {
1675             PartialEq::ne(*self, *other)
1676         }
1677     }
1678 }