diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:11:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:11:28 +0000 |
commit | 94a0819fe3a0d679c3042a77bfe6a2afc505daea (patch) | |
tree | 2b827afe6a05f3538db3f7803a88c4587fe85648 /library/core/src/cmp.rs | |
parent | Adding upstream version 1.64.0+dfsg1. (diff) | |
download | rustc-94a0819fe3a0d679c3042a77bfe6a2afc505daea.tar.xz rustc-94a0819fe3a0d679c3042a77bfe6a2afc505daea.zip |
Adding upstream version 1.66.0+dfsg1.upstream/1.66.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/core/src/cmp.rs')
-rw-r--r-- | library/core/src/cmp.rs | 125 |
1 files changed, 80 insertions, 45 deletions
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 20bb67687..f0fa2e1d2 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -1,6 +1,6 @@ -//! Functionality for ordering and comparison. +//! Utilities for comparing and ordering values. //! -//! This module contains various tools for ordering and comparing values. In +//! This module contains various tools for comparing and ordering values. In //! summary: //! //! * [`Eq`] and [`PartialEq`] are traits that allow you to define total and @@ -22,7 +22,9 @@ #![stable(feature = "rust1", since = "1.0.0")] +use crate::const_closure::ConstFnMutClosure; use crate::marker::Destruct; +use crate::marker::StructuralPartialEq; use self::Ordering::*; @@ -38,8 +40,10 @@ use self::Ordering::*; /// /// Implementations must ensure that `eq` and `ne` are consistent with each other: /// -/// - `a != b` if and only if `!(a == b)` -/// (ensured by the default implementation). +/// - `a != b` if and only if `!(a == b)`. +/// +/// The default implementation of `ne` provides this consistency and is almost +/// always sufficient. It should not be overridden without very good reason. /// /// If [`PartialOrd`] or [`Ord`] are also implemented for `Self` and `Rhs`, their methods must also /// be consistent with `PartialEq` (see the documentation of those traits for the exact @@ -201,20 +205,10 @@ use self::Ordering::*; #[stable(feature = "rust1", since = "1.0.0")] #[doc(alias = "==")] #[doc(alias = "!=")] -#[cfg_attr( - bootstrap, - rustc_on_unimplemented( - message = "can't compare `{Self}` with `{Rhs}`", - label = "no implementation for `{Self} == {Rhs}`" - ) -)] -#[cfg_attr( - not(bootstrap), - rustc_on_unimplemented( - message = "can't compare `{Self}` with `{Rhs}`", - label = "no implementation for `{Self} == {Rhs}`", - append_const_msg, - ) +#[rustc_on_unimplemented( + message = "can't compare `{Self}` with `{Rhs}`", + label = "no implementation for `{Self} == {Rhs}`", + append_const_msg )] #[const_trait] #[rustc_diagnostic_item = "PartialEq"] @@ -225,7 +219,8 @@ pub trait PartialEq<Rhs: ?Sized = Self> { #[stable(feature = "rust1", since = "1.0.0")] fn eq(&self, other: &Rhs) -> bool; - /// This method tests for `!=`. + /// This method tests for `!=`. The default implementation is almost always + /// sufficient, and should not be overridden without very good reason. #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] @@ -335,7 +330,7 @@ pub struct AssertParamIsEq<T: Eq + ?Sized> { /// let result = 2.cmp(&1); /// assert_eq!(Ordering::Greater, result); /// ``` -#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, Copy, Eq, Debug, Hash)] #[stable(feature = "rust1", since = "1.0.0")] #[repr(i8)] pub enum Ordering { @@ -882,6 +877,18 @@ pub macro Ord($item:item) { } #[stable(feature = "rust1", since = "1.0.0")] +impl StructuralPartialEq for Ordering {} + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] +impl const PartialEq for Ordering { + #[inline] + fn eq(&self, other: &Self) -> bool { + (*self as i32).eq(&(*other as i32)) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] impl const Ord for Ordering { #[inline] @@ -1060,20 +1067,10 @@ impl const PartialOrd for Ordering { #[doc(alias = "<")] #[doc(alias = "<=")] #[doc(alias = ">=")] -#[cfg_attr( - bootstrap, - rustc_on_unimplemented( - message = "can't compare `{Self}` with `{Rhs}`", - label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`", - ) -)] -#[cfg_attr( - not(bootstrap), - rustc_on_unimplemented( - message = "can't compare `{Self}` with `{Rhs}`", - label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`", - append_const_msg, - ) +#[rustc_on_unimplemented( + message = "can't compare `{Self}` with `{Rhs}`", + label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`", + append_const_msg )] #[const_trait] #[rustc_diagnostic_item = "PartialOrd"] @@ -1139,11 +1136,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> { #[must_use] #[stable(feature = "rust1", since = "1.0.0")] fn le(&self, other: &Rhs) -> bool { - // Pattern `Some(Less | Eq)` optimizes worse than negating `None | Some(Greater)`. - // FIXME: The root cause was fixed upstream in LLVM with: - // https://github.com/llvm/llvm-project/commit/9bad7de9a3fb844f1ca2965f35d0c2a3d1e11775 - // Revert this workaround once support for LLVM 12 gets dropped. - !matches!(self.partial_cmp(other), None | Some(Greater)) + matches!(self.partial_cmp(other), Some(Less | Equal)) } /// This method tests greater than (for `self` and `other`) and is used by the `>` operator. @@ -1230,7 +1223,12 @@ pub const fn min<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T { #[inline] #[must_use] #[stable(feature = "cmp_min_max_by", since = "1.53.0")] -pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T { +#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] +pub const fn min_by<T, F: ~const FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T +where + T: ~const Destruct, + F: ~const Destruct, +{ match compare(&v1, &v2) { Ordering::Less | Ordering::Equal => v1, Ordering::Greater => v2, @@ -1252,8 +1250,24 @@ pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T { #[inline] #[must_use] #[stable(feature = "cmp_min_max_by", since = "1.53.0")] -pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T { - min_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2))) +#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] +pub const fn min_by_key<T, F: ~const FnMut(&T) -> K, K: ~const Ord>(v1: T, v2: T, mut f: F) -> T +where + T: ~const Destruct, + F: ~const Destruct, + K: ~const Destruct, +{ + const fn imp<T, F: ~const FnMut(&T) -> K, K: ~const Ord>( + f: &mut F, + (v1, v2): (&T, &T), + ) -> Ordering + where + T: ~const Destruct, + K: ~const Destruct, + { + f(v1).cmp(&f(v2)) + } + min_by(v1, v2, ConstFnMutClosure::new(&mut f, imp)) } /// Compares and returns the maximum of two values. @@ -1294,7 +1308,12 @@ pub const fn max<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T { #[inline] #[must_use] #[stable(feature = "cmp_min_max_by", since = "1.53.0")] -pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T { +#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] +pub const fn max_by<T, F: ~const FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T +where + T: ~const Destruct, + F: ~const Destruct, +{ match compare(&v1, &v2) { Ordering::Less | Ordering::Equal => v2, Ordering::Greater => v1, @@ -1316,8 +1335,24 @@ pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T { #[inline] #[must_use] #[stable(feature = "cmp_min_max_by", since = "1.53.0")] -pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T { - max_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2))) +#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] +pub const fn max_by_key<T, F: ~const FnMut(&T) -> K, K: ~const Ord>(v1: T, v2: T, mut f: F) -> T +where + T: ~const Destruct, + F: ~const Destruct, + K: ~const Destruct, +{ + const fn imp<T, F: ~const FnMut(&T) -> K, K: ~const Ord>( + f: &mut F, + (v1, v2): (&T, &T), + ) -> Ordering + where + T: ~const Destruct, + K: ~const Destruct, + { + f(v1).cmp(&f(v2)) + } + max_by(v1, v2, ConstFnMutClosure::new(&mut f, imp)) } // Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types |