]> git.proxmox.com Git - rustc.git/blame - library/core/src/cmp.rs
New upstream version 1.66.0+dfsg1
[rustc.git] / library / core / src / cmp.rs
CommitLineData
f2b60f7d 1//! Utilities for comparing and ordering values.
1a4d82fc 2//!
f2b60f7d 3//! This module contains various tools for comparing and ordering values. In
0731742a 4//! summary:
54a0048b 5//!
0731742a
XL
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.
e1599b0c
XL
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.
54a0048b 17//!
0731742a 18//! For more details, see the respective documentation of each item in the list.
e1599b0c 19//!
3dfed10e
XL
20//! [`max`]: Ord::max
21//! [`min`]: Ord::min
1a4d82fc 22
85aaf69f 23#![stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 24
2b03887a 25use crate::const_closure::ConstFnMutClosure;
064997fb 26use crate::marker::Destruct;
f2b60f7d 27use crate::marker::StructuralPartialEq;
064997fb 28
1a4d82fc
JJ
29use self::Ordering::*;
30
62682a34 31/// Trait for equality comparisons which are [partial equivalence
3dfed10e 32/// relations](https://en.wikipedia.org/wiki/Partial_equivalence_relation).
1a4d82fc 33///
136023e0
XL
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///
62682a34 37/// This trait allows for partial equality, for types that do not have a full
9fa01778 38/// equivalence relation. For example, in floating point numbers `NaN != NaN`,
5869c6ff 39/// so floating point types implement `PartialEq` but not [`trait@Eq`].
1a4d82fc 40///
136023e0
XL
41/// Implementations must ensure that `eq` and `ne` are consistent with each other:
42///
f2b60f7d
FG
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.
136023e0
XL
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`):
1a4d82fc 55///
5869c6ff
XL
56/// - **Symmetric**: if `A: PartialEq<B>` and `B: PartialEq<A>`, then **`a == b`
57/// implies `b == a`**; and
1a4d82fc 58///
5869c6ff
XL
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.
1a4d82fc 65///
3157f602
XL
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
923072b8
FG
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.
3157f602
XL
72///
73/// ## How can I implement `PartialEq`?
74///
3157f602
XL
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/// ```
b7449926
XL
79/// enum BookFormat {
80/// Paperback,
81/// Hardback,
82/// Ebook,
83/// }
84///
3157f602
XL
85/// struct Book {
86/// isbn: i32,
87/// format: BookFormat,
88/// }
89///
90/// impl PartialEq for Book {
532ac7d7 91/// fn eq(&self, other: &Self) -> bool {
3157f602
XL
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/// ```
54a0048b 103///
b7449926
XL
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/// ```
9fa01778
XL
110/// // The derive implements <BookFormat> == <BookFormat> comparisons
111/// #[derive(PartialEq)]
b7449926
XL
112/// enum BookFormat {
113/// Paperback,
114/// Hardback,
115/// Ebook,
116/// }
117///
118/// struct Book {
119/// isbn: i32,
120/// format: BookFormat,
121/// }
122///
9fa01778 123/// // Implement <Book> == <BookFormat> comparisons
b7449926
XL
124/// impl PartialEq<BookFormat> for Book {
125/// fn eq(&self, other: &BookFormat) -> bool {
9fa01778
XL
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
b7449926
XL
134/// }
135/// }
136///
137/// let b1 = Book { isbn: 3, format: BookFormat::Paperback };
138///
139/// assert!(b1 == BookFormat::Paperback);
9fa01778 140/// assert!(BookFormat::Ebook != b1);
b7449926
XL
141/// ```
142///
143/// By changing `impl PartialEq for Book` to `impl PartialEq<BookFormat> for Book`,
9fa01778 144/// we allow `BookFormat`s to be compared with `Book`s.
b7449926 145///
60c5eb7d
XL
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
9fa01778 155/// #[derive(PartialEq)]
b7449926
XL
156/// enum BookFormat {
157/// Paperback,
158/// Hardback,
159/// Ebook,
160/// }
161///
60c5eb7d 162/// #[derive(PartialEq)]
b7449926
XL
163/// struct Book {
164/// isbn: i32,
165/// format: BookFormat,
166/// }
167///
168/// impl PartialEq<BookFormat> for Book {
169/// fn eq(&self, other: &BookFormat) -> bool {
9fa01778
XL
170/// self.format == *other
171/// }
172/// }
173///
174/// impl PartialEq<Book> for BookFormat {
175/// fn eq(&self, other: &Book) -> bool {
176/// *self == other.format
b7449926
XL
177/// }
178/// }
179///
60c5eb7d
XL
180/// fn main() {
181/// let b1 = Book { isbn: 1, format: BookFormat::Paperback };
182/// let b2 = Book { isbn: 2, format: BookFormat::Paperback };
b7449926 183///
60c5eb7d
XL
184/// assert!(b1 == BookFormat::Paperback);
185/// assert!(BookFormat::Paperback == b2);
b7449926 186///
60c5eb7d
XL
187/// // The following should hold by transitivity but doesn't.
188/// assert!(b1 == b2); // <-- PANICS
189/// }
b7449926
XL
190/// ```
191///
54a0048b
SL
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/// ```
74b04a01
XL
201///
202/// [`eq`]: PartialEq::eq
203/// [`ne`]: PartialEq::ne
d9579d0f 204#[lang = "eq"]
85aaf69f 205#[stable(feature = "rust1", since = "1.0.0")]
83c7162d
XL
206#[doc(alias = "==")]
207#[doc(alias = "!=")]
2b03887a
FG
208#[rustc_on_unimplemented(
209 message = "can't compare `{Self}` with `{Rhs}`",
210 label = "no implementation for `{Self} == {Rhs}`",
211 append_const_msg
8faf50e0 212)]
064997fb 213#[const_trait]
c295e0f8 214#[rustc_diagnostic_item = "PartialEq"]
1a4d82fc 215pub trait PartialEq<Rhs: ?Sized = Self> {
62682a34
SL
216 /// This method tests for `self` and `other` values to be equal, and is used
217 /// by `==`.
3b2f2976 218 #[must_use]
85aaf69f 219 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
220 fn eq(&self, other: &Rhs) -> bool;
221
f2b60f7d
FG
222 /// This method tests for `!=`. The default implementation is almost always
223 /// sufficient, and should not be overridden without very good reason.
1a4d82fc 224 #[inline]
3b2f2976 225 #[must_use]
85aaf69f 226 #[stable(feature = "rust1", since = "1.0.0")]
dfeec247
XL
227 fn ne(&self, other: &Rhs) -> bool {
228 !self.eq(other)
229 }
1a4d82fc
JJ
230}
231
416331ca 232/// Derive macro generating an impl of the trait `PartialEq`.
416331ca 233#[rustc_builtin_macro]
416331ca 234#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
e74abb32 235#[allow_internal_unstable(core_intrinsics, structural_match)]
dfeec247
XL
236pub macro PartialEq($item:item) {
237 /* compiler built-in */
238}
416331ca 239
1a4d82fc
JJ
240/// Trait for equality comparisons which are [equivalence relations](
241/// https://en.wikipedia.org/wiki/Equivalence_relation).
242///
85aaf69f
SL
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`):
1a4d82fc
JJ
245///
246/// - reflexive: `a == a`;
247/// - symmetric: `a == b` implies `b == a`; and
248/// - transitive: `a == b` and `b == c` implies `a == c`.
85aaf69f
SL
249///
250/// This property cannot be checked by the compiler, and therefore `Eq` implies
74b04a01 251/// [`PartialEq`], and has no extra methods.
92a42be0 252///
3157f602
XL
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
9e0c209e 258/// the `derive` strategy requires all fields are `Eq`, which isn't
3157f602
XL
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 {
532ac7d7 273/// fn eq(&self, other: &Self) -> bool {
3157f602
XL
274/// self.isbn == other.isbn
275/// }
276/// }
277/// impl Eq for Book {}
278/// ```
83c7162d
XL
279#[doc(alias = "==")]
280#[doc(alias = "!=")]
85aaf69f 281#[stable(feature = "rust1", since = "1.0.0")]
c295e0f8 282#[rustc_diagnostic_item = "Eq"]
1a4d82fc 283pub trait Eq: PartialEq<Self> {
ea8adc8c
XL
284 // this method is used solely by #[deriving] to assert
285 // that every component of a type implements #[deriving]
1a4d82fc
JJ
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)]
17df50a5 292 #[no_coverage] // rust-lang/rust#84605
3b2f2976 293 #[inline]
85aaf69f 294 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
295 fn assert_receiver_is_total_eq(&self) {}
296}
297
416331ca 298/// Derive macro generating an impl of the trait `Eq`.
416331ca 299#[rustc_builtin_macro]
416331ca 300#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
cdc7bbd5 301#[allow_internal_unstable(core_intrinsics, derive_eq, structural_match, no_coverage)]
dfeec247
XL
302pub macro Eq($item:item) {
303 /* compiler built-in */
304}
416331ca 305
9e0c209e
SL
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)]
dfeec247
XL
312#[unstable(feature = "derive_eq", reason = "deriving hack, should not be public", issue = "none")]
313pub struct AssertParamIsEq<T: Eq + ?Sized> {
314 _field: crate::marker::PhantomData<T>,
315}
9e0c209e 316
85aaf69f
SL
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/// ```
f2b60f7d 333#[derive(Clone, Copy, Eq, Debug, Hash)]
85aaf69f 334#[stable(feature = "rust1", since = "1.0.0")]
c295e0f8 335#[repr(i8)]
1a4d82fc 336pub enum Ordering {
48663c56 337 /// An ordering where a compared value is less than another.
85aaf69f
SL
338 #[stable(feature = "rust1", since = "1.0.0")]
339 Less = -1,
48663c56 340 /// An ordering where a compared value is equal to another.
85aaf69f
SL
341 #[stable(feature = "rust1", since = "1.0.0")]
342 Equal = 0,
48663c56 343 /// An ordering where a compared value is greater than another.
85aaf69f
SL
344 #[stable(feature = "rust1", since = "1.0.0")]
345 Greater = 1,
1a4d82fc
JJ
346}
347
348impl Ordering {
fc512014
XL
349 /// Returns `true` if the ordering is the `Equal` variant.
350 ///
351 /// # Examples
352 ///
353 /// ```
fc512014
XL
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]
cdc7bbd5
XL
362 #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
363 #[stable(feature = "ordering_helpers", since = "1.53.0")]
fc512014
XL
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 /// ```
fc512014
XL
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]
cdc7bbd5
XL
381 #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
382 #[stable(feature = "ordering_helpers", since = "1.53.0")]
fc512014
XL
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 /// ```
fc512014
XL
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]
cdc7bbd5
XL
400 #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
401 #[stable(feature = "ordering_helpers", since = "1.53.0")]
fc512014
XL
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 /// ```
fc512014
XL
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]
cdc7bbd5
XL
419 #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
420 #[stable(feature = "ordering_helpers", since = "1.53.0")]
fc512014
XL
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 /// ```
fc512014
XL
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]
cdc7bbd5
XL
438 #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
439 #[stable(feature = "ordering_helpers", since = "1.53.0")]
fc512014
XL
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 /// ```
fc512014
XL
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]
cdc7bbd5
XL
457 #[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
458 #[stable(feature = "ordering_helpers", since = "1.53.0")]
fc512014
XL
459 pub const fn is_ge(self) -> bool {
460 !matches!(self, Less)
461 }
462
cc61c64b 463 /// Reverses the `Ordering`.
1a4d82fc 464 ///
85aaf69f
SL
465 /// * `Less` becomes `Greater`.
466 /// * `Greater` becomes `Less`.
467 /// * `Equal` becomes `Equal`.
1a4d82fc 468 ///
85aaf69f 469 /// # Examples
1a4d82fc 470 ///
85aaf69f 471 /// Basic behavior:
1a4d82fc 472 ///
85aaf69f
SL
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 /// ```
416331ca 484 /// let data: &mut [_] = &mut [2, 10, 5, 8];
1a4d82fc
JJ
485 ///
486 /// // sort the array from largest to smallest.
487 /// data.sort_by(|a, b| a.cmp(b).reverse());
488 ///
85aaf69f 489 /// let b: &mut [_] = &mut [10, 8, 5, 2];
1a4d82fc
JJ
490 /// assert!(data == b);
491 /// ```
492 #[inline]
74b04a01 493 #[must_use]
1b1a35ee 494 #[rustc_const_stable(feature = "const_ordering", since = "1.48.0")]
85aaf69f 495 #[stable(feature = "rust1", since = "1.0.0")]
1b1a35ee 496 pub const fn reverse(self) -> Ordering {
7453a54e
SL
497 match self {
498 Less => Greater,
499 Equal => Equal,
500 Greater => Less,
1a4d82fc
JJ
501 }
502 }
c30ab7b3
SL
503
504 /// Chains two orderings.
505 ///
506 /// Returns `self` when it's not `Equal`. Otherwise returns `other`.
74b04a01 507 ///
c30ab7b3
SL
508 /// # Examples
509 ///
510 /// ```
c30ab7b3
SL
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 /// ```
cc61c64b 531 #[inline]
74b04a01 532 #[must_use]
1b1a35ee 533 #[rustc_const_stable(feature = "const_ordering", since = "1.48.0")]
8bb4bdeb 534 #[stable(feature = "ordering_chaining", since = "1.17.0")]
1b1a35ee 535 pub const fn then(self, other: Ordering) -> Ordering {
c30ab7b3
SL
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 /// ```
c30ab7b3
SL
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);
5869c6ff 565 /// let y: (i64, i64, i64) = (1, 5, 3);
c30ab7b3
SL
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 /// ```
cc61c64b 570 #[inline]
74b04a01 571 #[must_use]
8bb4bdeb 572 #[stable(feature = "ordering_chaining", since = "1.17.0")]
c30ab7b3
SL
573 pub fn then_with<F: FnOnce() -> Ordering>(self, f: F) -> Ordering {
574 match self {
575 Equal => f(),
576 _ => self,
577 }
578 }
1a4d82fc
JJ
579}
580
cc61c64b
XL
581/// A helper struct for reverse ordering.
582///
74b04a01 583/// This struct is a helper to be used with functions like [`Vec::sort_by_key`] and
cc61c64b
XL
584/// can be used to reverse order a part of a key.
585///
74b04a01
XL
586/// [`Vec::sort_by_key`]: ../../std/vec/struct.Vec.html#method.sort_by_key
587///
588/// # Examples
cc61c64b
XL
589///
590/// ```
cc61c64b
XL
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/// ```
17df50a5 597#[derive(PartialEq, Eq, Debug, Copy, Default, Hash)]
7cac9316 598#[stable(feature = "reverse_cmp_key", since = "1.19.0")]
6a06907d 599#[repr(transparent)]
7cac9316 600pub struct Reverse<T>(#[stable(feature = "reverse_cmp_key", since = "1.19.0")] pub T);
cc61c64b 601
7cac9316 602#[stable(feature = "reverse_cmp_key", since = "1.19.0")]
064997fb
FG
603#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
604impl<T: ~const PartialOrd> const PartialOrd for Reverse<T> {
cc61c64b
XL
605 #[inline]
606 fn partial_cmp(&self, other: &Reverse<T>) -> Option<Ordering> {
607 other.0.partial_cmp(&self.0)
608 }
609
610 #[inline]
dfeec247
XL
611 fn lt(&self, other: &Self) -> bool {
612 other.0 < self.0
613 }
cc61c64b 614 #[inline]
dfeec247
XL
615 fn le(&self, other: &Self) -> bool {
616 other.0 <= self.0
617 }
cc61c64b 618 #[inline]
dfeec247
XL
619 fn gt(&self, other: &Self) -> bool {
620 other.0 > self.0
621 }
60c5eb7d 622 #[inline]
dfeec247
XL
623 fn ge(&self, other: &Self) -> bool {
624 other.0 >= self.0
625 }
cc61c64b
XL
626}
627
7cac9316 628#[stable(feature = "reverse_cmp_key", since = "1.19.0")]
cc61c64b
XL
629impl<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
17df50a5
XL
636#[stable(feature = "reverse_cmp_key", since = "1.19.0")]
637impl<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
85aaf69f 649/// Trait for types that form a [total order](https://en.wikipedia.org/wiki/Total_order).
1a4d82fc 650///
136023e0
XL
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`:
1a4d82fc 667///
136023e0
XL
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 `>`.
c1a9b12d 670///
3157f602
XL
671/// ## Derivable
672///
5099ac24
FG
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:
94222f64
XL
682///
683/// ```
5099ac24
FG
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,
94222f64
XL
701/// }
702///
5099ac24 703/// assert!(E::Bottom < E::Top);
94222f64 704/// ```
3157f602 705///
29967ef6
XL
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///
3157f602
XL
716/// ## How can I implement `Ord`?
717///
74b04a01 718/// `Ord` requires that the type also be [`PartialOrd`] and [`Eq`] (which requires [`PartialEq`]).
3157f602 719///
74b04a01
XL
720/// Then you must define an implementation for [`cmp`]. You may find it useful to use
721/// [`cmp`] on your type's fields.
3157f602
XL
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 {
532ac7d7 737/// fn cmp(&self, other: &Self) -> Ordering {
3157f602
XL
738/// self.height.cmp(&other.height)
739/// }
740/// }
741///
742/// impl PartialOrd for Person {
532ac7d7 743/// fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
3157f602
XL
744/// Some(self.cmp(other))
745/// }
746/// }
747///
748/// impl PartialEq for Person {
532ac7d7 749/// fn eq(&self, other: &Self) -> bool {
3157f602
XL
750/// self.height == other.height
751/// }
752/// }
753/// ```
74b04a01
XL
754///
755/// [`cmp`]: Ord::cmp
83c7162d
XL
756#[doc(alias = "<")]
757#[doc(alias = ">")]
758#[doc(alias = "<=")]
759#[doc(alias = ">=")]
85aaf69f 760#[stable(feature = "rust1", since = "1.0.0")]
c295e0f8 761#[rustc_diagnostic_item = "Ord"]
064997fb 762#[const_trait]
1a4d82fc 763pub trait Ord: Eq + PartialOrd<Self> {
74b04a01 764 /// This method returns an [`Ordering`] between `self` and `other`.
85aaf69f
SL
765 ///
766 /// By convention, `self.cmp(&other)` returns the ordering matching the expression
767 /// `self <operator> other` if true.
1a4d82fc 768 ///
85aaf69f 769 /// # Examples
1a4d82fc
JJ
770 ///
771 /// ```
85aaf69f 772 /// use std::cmp::Ordering;
1a4d82fc 773 ///
85aaf69f
SL
774 /// assert_eq!(5.cmp(&10), Ordering::Less);
775 /// assert_eq!(10.cmp(&5), Ordering::Greater);
776 /// assert_eq!(5.cmp(&5), Ordering::Equal);
1a4d82fc 777 /// ```
74b04a01 778 #[must_use]
85aaf69f 779 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 780 fn cmp(&self, other: &Self) -> Ordering;
041b39d2
XL
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 /// ```
041b39d2
XL
789 /// assert_eq!(2, 1.max(2));
790 /// assert_eq!(2, 2.max(2));
791 /// ```
3b2f2976 792 #[stable(feature = "ord_max_min", since = "1.21.0")]
b7449926 793 #[inline]
74b04a01 794 #[must_use]
041b39d2 795 fn max(self, other: Self) -> Self
dfeec247
XL
796 where
797 Self: Sized,
064997fb 798 Self: ~const Destruct,
dfeec247 799 {
064997fb
FG
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 }
041b39d2
XL
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 /// ```
041b39d2
XL
816 /// assert_eq!(1, 1.min(2));
817 /// assert_eq!(2, 2.min(2));
818 /// ```
3b2f2976 819 #[stable(feature = "ord_max_min", since = "1.21.0")]
b7449926 820 #[inline]
74b04a01 821 #[must_use]
041b39d2 822 fn min(self, other: Self) -> Self
dfeec247
XL
823 where
824 Self: Sized,
064997fb 825 Self: ~const Destruct,
dfeec247 826 {
064997fb
FG
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 }
041b39d2 834 }
532ac7d7
XL
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 /// ```
532ac7d7
XL
848 /// assert!((-3).clamp(-2, 1) == -2);
849 /// assert!(0.clamp(-2, 1) == 0);
850 /// assert!(2.clamp(-2, 1) == 1);
851 /// ```
74b04a01 852 #[must_use]
fc512014 853 #[stable(feature = "clamp", since = "1.50.0")]
532ac7d7 854 fn clamp(self, min: Self, max: Self) -> Self
dfeec247
XL
855 where
856 Self: Sized,
064997fb
FG
857 Self: ~const Destruct,
858 Self: ~const PartialOrd,
dfeec247 859 {
532ac7d7
XL
860 assert!(min <= max);
861 if self < min {
862 min
863 } else if self > max {
864 max
865 } else {
866 self
867 }
868 }
1a4d82fc
JJ
869}
870
416331ca 871/// Derive macro generating an impl of the trait `Ord`.
416331ca 872#[rustc_builtin_macro]
416331ca
XL
873#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
874#[allow_internal_unstable(core_intrinsics)]
dfeec247
XL
875pub macro Ord($item:item) {
876 /* compiler built-in */
877}
416331ca 878
f2b60f7d
FG
879#[stable(feature = "rust1", since = "1.0.0")]
880impl StructuralPartialEq for Ordering {}
881
882#[stable(feature = "rust1", since = "1.0.0")]
883#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
884impl const PartialEq for Ordering {
885 #[inline]
886 fn eq(&self, other: &Self) -> bool {
887 (*self as i32).eq(&(*other as i32))
888 }
889}
890
85aaf69f 891#[stable(feature = "rust1", since = "1.0.0")]
064997fb
FG
892#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
893impl const Ord for Ordering {
1a4d82fc 894 #[inline]
1a4d82fc 895 fn cmp(&self, other: &Ordering) -> Ordering {
85aaf69f 896 (*self as i32).cmp(&(*other as i32))
1a4d82fc
JJ
897 }
898}
899
85aaf69f 900#[stable(feature = "rust1", since = "1.0.0")]
064997fb
FG
901#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
902impl const PartialOrd for Ordering {
1a4d82fc 903 #[inline]
1a4d82fc 904 fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
85aaf69f 905 (*self as i32).partial_cmp(&(*other as i32))
1a4d82fc
JJ
906 }
907}
908
5099ac24 909/// Trait for types that form a [partial order](https://en.wikipedia.org/wiki/Partial_order).
1a4d82fc 910///
136023e0
XL
911/// The `lt`, `le`, `gt`, and `ge` methods of this trait can be called using
912/// the `<`, `<=`, `>`, and `>=` operators, respectively.
913///
5e7ed085
FG
914/// The methods of this trait must be consistent with each other and with those of [`PartialEq`].
915/// The following conditions must hold:
136023e0 916///
5e7ed085
FG
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`].
136023e0
XL
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///
1a4d82fc
JJ
932/// The comparison must satisfy, for all `a`, `b` and `c`:
933///
85aaf69f 934/// - transitivity: `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
136023e0 935/// - duality: `a < b` if and only if `b > a`.
1a4d82fc 936///
85aaf69f
SL
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:
1a4d82fc
JJ
939/// PartialOrd<V>`.
940///
136023e0
XL
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///
3157f602
XL
949/// ## Derivable
950///
5099ac24
FG
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/// ```
3157f602 983///
32a655c1 984/// ## How can I implement `PartialOrd`?
3157f602 985///
74b04a01 986/// `PartialOrd` only requires implementation of the [`partial_cmp`] method, with the others
7cac9316 987/// generated from default implementations.
1a4d82fc 988///
85aaf69f
SL
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).
92a42be0 992///
74b04a01 993/// `PartialOrd` requires your type to be [`PartialEq`].
3157f602 994///
74b04a01 995/// If your type is [`Ord`], you can implement [`partial_cmp`] by using [`cmp`]:
3157f602
XL
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 {
1b1a35ee 1008/// fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
3157f602
XL
1009/// Some(self.cmp(other))
1010/// }
1011/// }
1012///
1013/// impl Ord for Person {
1b1a35ee 1014/// fn cmp(&self, other: &Self) -> Ordering {
3157f602
XL
1015/// self.height.cmp(&other.height)
1016/// }
1017/// }
1018///
1019/// impl PartialEq for Person {
1b1a35ee 1020/// fn eq(&self, other: &Self) -> bool {
3157f602
XL
1021/// self.height == other.height
1022/// }
1023/// }
1024/// ```
1025///
74b04a01 1026/// You may also find it useful to use [`partial_cmp`] on your type's fields. Here
3157f602
XL
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 {
532ac7d7 1040/// fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
3157f602
XL
1041/// self.height.partial_cmp(&other.height)
1042/// }
1043/// }
1044///
1045/// impl PartialEq for Person {
532ac7d7 1046/// fn eq(&self, other: &Self) -> bool {
3157f602
XL
1047/// self.height == other.height
1048/// }
1049/// }
1050/// ```
54a0048b
SL
1051///
1052/// # Examples
1053///
1054/// ```
5099ac24
FG
1055/// let x: u32 = 0;
1056/// let y: u32 = 1;
54a0048b
SL
1057///
1058/// assert_eq!(x < y, true);
1059/// assert_eq!(x.lt(&y), true);
1060/// ```
74b04a01
XL
1061///
1062/// [`partial_cmp`]: PartialOrd::partial_cmp
1063/// [`cmp`]: Ord::cmp
83c7162d 1064#[lang = "partial_ord"]
85aaf69f 1065#[stable(feature = "rust1", since = "1.0.0")]
83c7162d
XL
1066#[doc(alias = ">")]
1067#[doc(alias = "<")]
1068#[doc(alias = "<=")]
1069#[doc(alias = ">=")]
2b03887a
FG
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
8faf50e0 1074)]
064997fb 1075#[const_trait]
c295e0f8 1076#[rustc_diagnostic_item = "PartialOrd"]
1a4d82fc 1077pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
85aaf69f
SL
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 /// ```
ba9703b0 1098 /// let result = f64::NAN.partial_cmp(&1.0);
85aaf69f
SL
1099 /// assert_eq!(result, None);
1100 /// ```
3b2f2976 1101 #[must_use]
85aaf69f 1102 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
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.
85aaf69f
SL
1106 ///
1107 /// # Examples
1108 ///
1109 /// ```
85aaf69f
SL
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 /// ```
1a4d82fc 1116 #[inline]
3b2f2976 1117 #[must_use]
85aaf69f 1118 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 1119 fn lt(&self, other: &Rhs) -> bool {
dfeec247 1120 matches!(self.partial_cmp(other), Some(Less))
1a4d82fc
JJ
1121 }
1122
85aaf69f
SL
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 /// ```
1a4d82fc 1135 #[inline]
3b2f2976 1136 #[must_use]
85aaf69f 1137 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 1138 fn le(&self, other: &Rhs) -> bool {
f2b60f7d 1139 matches!(self.partial_cmp(other), Some(Less | Equal))
1a4d82fc
JJ
1140 }
1141
85aaf69f
SL
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 /// ```
1a4d82fc 1153 #[inline]
3b2f2976 1154 #[must_use]
85aaf69f 1155 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 1156 fn gt(&self, other: &Rhs) -> bool {
dfeec247 1157 matches!(self.partial_cmp(other), Some(Greater))
1a4d82fc
JJ
1158 }
1159
85aaf69f
SL
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 /// ```
1a4d82fc 1172 #[inline]
3b2f2976 1173 #[must_use]
85aaf69f 1174 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 1175 fn ge(&self, other: &Rhs) -> bool {
ba9703b0 1176 matches!(self.partial_cmp(other), Some(Greater | Equal))
1a4d82fc
JJ
1177 }
1178}
1179
416331ca 1180/// Derive macro generating an impl of the trait `PartialOrd`.
416331ca 1181#[rustc_builtin_macro]
416331ca
XL
1182#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
1183#[allow_internal_unstable(core_intrinsics)]
dfeec247
XL
1184pub macro PartialOrd($item:item) {
1185 /* compiler built-in */
1186}
416331ca 1187
cc61c64b 1188/// Compares and returns the minimum of two values.
85aaf69f 1189///
c34b1796
AL
1190/// Returns the first argument if the comparison determines them to be equal.
1191///
74b04a01 1192/// Internally uses an alias to [`Ord::min`].
041b39d2 1193///
85aaf69f
SL
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/// ```
1a4d82fc 1202#[inline]
74b04a01 1203#[must_use]
85aaf69f 1204#[stable(feature = "rust1", since = "1.0.0")]
064997fb 1205#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
136023e0 1206#[cfg_attr(not(test), rustc_diagnostic_item = "cmp_min")]
064997fb 1207pub const fn min<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T {
041b39d2 1208 v1.min(v2)
1a4d82fc
JJ
1209}
1210
e1599b0c
XL
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/// ```
e1599b0c
XL
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]
74b04a01 1224#[must_use]
cdc7bbd5 1225#[stable(feature = "cmp_min_max_by", since = "1.53.0")]
2b03887a
FG
1226#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1227pub const fn min_by<T, F: ~const FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T
1228where
1229 T: ~const Destruct,
1230 F: ~const Destruct,
1231{
e1599b0c
XL
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/// ```
e1599b0c
XL
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]
74b04a01 1251#[must_use]
cdc7bbd5 1252#[stable(feature = "cmp_min_max_by", since = "1.53.0")]
2b03887a
FG
1253#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1254pub const fn min_by_key<T, F: ~const FnMut(&T) -> K, K: ~const Ord>(v1: T, v2: T, mut f: F) -> T
1255where
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))
e1599b0c
XL
1271}
1272
cc61c64b 1273/// Compares and returns the maximum of two values.
85aaf69f 1274///
c34b1796
AL
1275/// Returns the second argument if the comparison determines them to be equal.
1276///
74b04a01 1277/// Internally uses an alias to [`Ord::max`].
041b39d2 1278///
85aaf69f
SL
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/// ```
1a4d82fc 1287#[inline]
74b04a01 1288#[must_use]
85aaf69f 1289#[stable(feature = "rust1", since = "1.0.0")]
064997fb 1290#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
136023e0 1291#[cfg_attr(not(test), rustc_diagnostic_item = "cmp_max")]
064997fb 1292pub const fn max<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T {
041b39d2 1293 v1.max(v2)
1a4d82fc
JJ
1294}
1295
e1599b0c
XL
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/// ```
e1599b0c
XL
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]
74b04a01 1309#[must_use]
cdc7bbd5 1310#[stable(feature = "cmp_min_max_by", since = "1.53.0")]
2b03887a
FG
1311#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1312pub const fn max_by<T, F: ~const FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T
1313where
1314 T: ~const Destruct,
1315 F: ~const Destruct,
1316{
e1599b0c
XL
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/// ```
e1599b0c
XL
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]
74b04a01 1336#[must_use]
cdc7bbd5 1337#[stable(feature = "cmp_min_max_by", since = "1.53.0")]
2b03887a
FG
1338#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1339pub const fn max_by_key<T, F: ~const FnMut(&T) -> K, K: ~const Ord>(v1: T, v2: T, mut f: F) -> T
1340where
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))
e1599b0c
XL
1356}
1357
1a4d82fc
JJ
1358// Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
1359mod impls {
dfeec247 1360 use crate::cmp::Ordering::{self, Equal, Greater, Less};
60c5eb7d 1361 use crate::hint::unreachable_unchecked;
1a4d82fc
JJ
1362
1363 macro_rules! partial_eq_impl {
1364 ($($t:ty)*) => ($(
85aaf69f 1365 #[stable(feature = "rust1", since = "1.0.0")]
064997fb
FG
1366 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1367 impl const PartialEq for $t {
1a4d82fc
JJ
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
85aaf69f 1376 #[stable(feature = "rust1", since = "1.0.0")]
064997fb
FG
1377 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1378 impl const PartialEq for () {
1a4d82fc 1379 #[inline]
dfeec247
XL
1380 fn eq(&self, _other: &()) -> bool {
1381 true
1382 }
1a4d82fc 1383 #[inline]
dfeec247
XL
1384 fn ne(&self, _other: &()) -> bool {
1385 false
1386 }
1a4d82fc
JJ
1387 }
1388
1389 partial_eq_impl! {
8bb4bdeb 1390 bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64
1a4d82fc
JJ
1391 }
1392
1393 macro_rules! eq_impl {
1394 ($($t:ty)*) => ($(
85aaf69f 1395 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
1396 impl Eq for $t {}
1397 )*)
1398 }
1399
8bb4bdeb 1400 eq_impl! { () bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
1a4d82fc
JJ
1401
1402 macro_rules! partial_ord_impl {
1403 ($($t:ty)*) => ($(
85aaf69f 1404 #[stable(feature = "rust1", since = "1.0.0")]
064997fb
FG
1405 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1406 impl const PartialOrd for $t {
1a4d82fc
JJ
1407 #[inline]
1408 fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
923072b8 1409 match (*self <= *other, *self >= *other) {
1a4d82fc
JJ
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
85aaf69f 1428 #[stable(feature = "rust1", since = "1.0.0")]
064997fb
FG
1429 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1430 impl const PartialOrd for () {
1a4d82fc
JJ
1431 #[inline]
1432 fn partial_cmp(&self, _: &()) -> Option<Ordering> {
1433 Some(Equal)
1434 }
1435 }
1436
85aaf69f 1437 #[stable(feature = "rust1", since = "1.0.0")]
064997fb
FG
1438 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1439 impl const PartialOrd for bool {
1a4d82fc
JJ
1440 #[inline]
1441 fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
fc512014 1442 Some(self.cmp(other))
1a4d82fc
JJ
1443 }
1444 }
1445
b039eaaf 1446 partial_ord_impl! { f32 f64 }
1a4d82fc
JJ
1447
1448 macro_rules! ord_impl {
1449 ($($t:ty)*) => ($(
b039eaaf 1450 #[stable(feature = "rust1", since = "1.0.0")]
064997fb
FG
1451 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1452 impl const PartialOrd for $t {
b039eaaf
SL
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
85aaf69f 1467 #[stable(feature = "rust1", since = "1.0.0")]
064997fb
FG
1468 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1469 impl const Ord for $t {
1a4d82fc
JJ
1470 #[inline]
1471 fn cmp(&self, other: &$t) -> Ordering {
e1599b0c
XL
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 }
b039eaaf 1476 else { Greater }
1a4d82fc
JJ
1477 }
1478 }
1479 )*)
1480 }
1481
85aaf69f 1482 #[stable(feature = "rust1", since = "1.0.0")]
064997fb
FG
1483 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1484 impl const Ord for () {
1a4d82fc 1485 #[inline]
dfeec247
XL
1486 fn cmp(&self, _other: &()) -> Ordering {
1487 Equal
1488 }
1a4d82fc
JJ
1489 }
1490
85aaf69f 1491 #[stable(feature = "rust1", since = "1.0.0")]
064997fb
FG
1492 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1493 impl const Ord for bool {
1a4d82fc
JJ
1494 #[inline]
1495 fn cmp(&self, other: &bool) -> Ordering {
60c5eb7d
XL
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 }
1a4d82fc
JJ
1506 }
1507 }
1508
8bb4bdeb 1509 ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
1a4d82fc 1510
ff7c6d11 1511 #[unstable(feature = "never_type", issue = "35121")]
064997fb
FG
1512 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1513 impl const PartialEq for ! {
9e0c209e
SL
1514 fn eq(&self, _: &!) -> bool {
1515 *self
1516 }
1517 }
5bcae85e 1518
ff7c6d11 1519 #[unstable(feature = "never_type", issue = "35121")]
9e0c209e 1520 impl Eq for ! {}
5bcae85e 1521
ff7c6d11 1522 #[unstable(feature = "never_type", issue = "35121")]
064997fb
FG
1523 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1524 impl const PartialOrd for ! {
9e0c209e
SL
1525 fn partial_cmp(&self, _: &!) -> Option<Ordering> {
1526 *self
5bcae85e
SL
1527 }
1528 }
1529
ff7c6d11 1530 #[unstable(feature = "never_type", issue = "35121")]
064997fb
FG
1531 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1532 impl const Ord for ! {
9e0c209e
SL
1533 fn cmp(&self, _: &!) -> Ordering {
1534 *self
1535 }
1536 }
5bcae85e 1537
1a4d82fc
JJ
1538 // & pointers
1539
85aaf69f 1540 #[stable(feature = "rust1", since = "1.0.0")]
064997fb
FG
1541 #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1542 impl<A: ?Sized, B: ?Sized> const PartialEq<&B> for &A
dfeec247 1543 where
064997fb 1544 A: ~const PartialEq<B>,
dfeec247 1545 {
1a4d82fc 1546 #[inline]
dfeec247
XL
1547 fn eq(&self, other: &&B) -> bool {
1548 PartialEq::eq(*self, *other)
1549 }
1a4d82fc 1550 #[inline]
dfeec247
XL
1551 fn ne(&self, other: &&B) -> bool {
1552 PartialEq::ne(*self, *other)
1553 }
1a4d82fc 1554 }
85aaf69f 1555 #[stable(feature = "rust1", since = "1.0.0")]
dfeec247
XL
1556 impl<A: ?Sized, B: ?Sized> PartialOrd<&B> for &A
1557 where
1558 A: PartialOrd<B>,
1559 {
1a4d82fc 1560 #[inline]
532ac7d7 1561 fn partial_cmp(&self, other: &&B) -> Option<Ordering> {
1a4d82fc
JJ
1562 PartialOrd::partial_cmp(*self, *other)
1563 }
1564 #[inline]
dfeec247
XL
1565 fn lt(&self, other: &&B) -> bool {
1566 PartialOrd::lt(*self, *other)
1567 }
1a4d82fc 1568 #[inline]
dfeec247
XL
1569 fn le(&self, other: &&B) -> bool {
1570 PartialOrd::le(*self, *other)
1571 }
1a4d82fc 1572 #[inline]
dfeec247
XL
1573 fn gt(&self, other: &&B) -> bool {
1574 PartialOrd::gt(*self, *other)
1575 }
60c5eb7d 1576 #[inline]
dfeec247
XL
1577 fn ge(&self, other: &&B) -> bool {
1578 PartialOrd::ge(*self, *other)
1579 }
1a4d82fc 1580 }
85aaf69f 1581 #[stable(feature = "rust1", since = "1.0.0")]
dfeec247
XL
1582 impl<A: ?Sized> Ord for &A
1583 where
1584 A: Ord,
1585 {
1a4d82fc 1586 #[inline]
dfeec247
XL
1587 fn cmp(&self, other: &Self) -> Ordering {
1588 Ord::cmp(*self, *other)
1589 }
1a4d82fc 1590 }
85aaf69f 1591 #[stable(feature = "rust1", since = "1.0.0")]
0bf4aa26 1592 impl<A: ?Sized> Eq for &A where A: Eq {}
1a4d82fc
JJ
1593
1594 // &mut pointers
1595
85aaf69f 1596 #[stable(feature = "rust1", since = "1.0.0")]
dfeec247
XL
1597 impl<A: ?Sized, B: ?Sized> PartialEq<&mut B> for &mut A
1598 where
1599 A: PartialEq<B>,
1600 {
1a4d82fc 1601 #[inline]
dfeec247
XL
1602 fn eq(&self, other: &&mut B) -> bool {
1603 PartialEq::eq(*self, *other)
1604 }
1a4d82fc 1605 #[inline]
dfeec247
XL
1606 fn ne(&self, other: &&mut B) -> bool {
1607 PartialEq::ne(*self, *other)
1608 }
1a4d82fc 1609 }
85aaf69f 1610 #[stable(feature = "rust1", since = "1.0.0")]
dfeec247
XL
1611 impl<A: ?Sized, B: ?Sized> PartialOrd<&mut B> for &mut A
1612 where
1613 A: PartialOrd<B>,
1614 {
1a4d82fc 1615 #[inline]
532ac7d7 1616 fn partial_cmp(&self, other: &&mut B) -> Option<Ordering> {
1a4d82fc
JJ
1617 PartialOrd::partial_cmp(*self, *other)
1618 }
1619 #[inline]
dfeec247
XL
1620 fn lt(&self, other: &&mut B) -> bool {
1621 PartialOrd::lt(*self, *other)
1622 }
1a4d82fc 1623 #[inline]
dfeec247
XL
1624 fn le(&self, other: &&mut B) -> bool {
1625 PartialOrd::le(*self, *other)
1626 }
1a4d82fc 1627 #[inline]
dfeec247
XL
1628 fn gt(&self, other: &&mut B) -> bool {
1629 PartialOrd::gt(*self, *other)
1630 }
60c5eb7d 1631 #[inline]
dfeec247
XL
1632 fn ge(&self, other: &&mut B) -> bool {
1633 PartialOrd::ge(*self, *other)
1634 }
1a4d82fc 1635 }
85aaf69f 1636 #[stable(feature = "rust1", since = "1.0.0")]
dfeec247
XL
1637 impl<A: ?Sized> Ord for &mut A
1638 where
1639 A: Ord,
1640 {
1a4d82fc 1641 #[inline]
dfeec247
XL
1642 fn cmp(&self, other: &Self) -> Ordering {
1643 Ord::cmp(*self, *other)
1644 }
1a4d82fc 1645 }
85aaf69f 1646 #[stable(feature = "rust1", since = "1.0.0")]
0bf4aa26 1647 impl<A: ?Sized> Eq for &mut A where A: Eq {}
1a4d82fc 1648
85aaf69f 1649 #[stable(feature = "rust1", since = "1.0.0")]
dfeec247
XL
1650 impl<A: ?Sized, B: ?Sized> PartialEq<&mut B> for &A
1651 where
1652 A: PartialEq<B>,
1653 {
1a4d82fc 1654 #[inline]
dfeec247
XL
1655 fn eq(&self, other: &&mut B) -> bool {
1656 PartialEq::eq(*self, *other)
1657 }
1a4d82fc 1658 #[inline]
dfeec247
XL
1659 fn ne(&self, other: &&mut B) -> bool {
1660 PartialEq::ne(*self, *other)
1661 }
1a4d82fc
JJ
1662 }
1663
85aaf69f 1664 #[stable(feature = "rust1", since = "1.0.0")]
dfeec247
XL
1665 impl<A: ?Sized, B: ?Sized> PartialEq<&B> for &mut A
1666 where
1667 A: PartialEq<B>,
1668 {
1a4d82fc 1669 #[inline]
dfeec247
XL
1670 fn eq(&self, other: &&B) -> bool {
1671 PartialEq::eq(*self, *other)
1672 }
1a4d82fc 1673 #[inline]
dfeec247
XL
1674 fn ne(&self, other: &&B) -> bool {
1675 PartialEq::ne(*self, *other)
1676 }
1a4d82fc
JJ
1677 }
1678}