You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When #[feature(const_if_match)] (#49146) lands almost all comparison logic could be const.
Problem
Most types that can be compared just derive or implement PartialOrd and Ord. However, as trait methods cannot be const (maybe in the far future if we have const traits), the logic inside these cmp and partial_cmp methods is unavailable in const contexts.
The only exceptions to this are the >, <, >=, <= operators for some primitives: floating-point numbers, integers, bool, char and !, which are (I think) const intrinsics. Note that these operators all result in a bool, there is no const comparison function resulting in a std::cmp::Ordering. This makes custom const lexicographical comparisons still hard to write compared to using std::cmp::Ordering::then (also not yet const).
Proposal
Add a const inherent comparison method to applicable types and let the Ord and PartialOrd delegate to this method:
As a conservative implementation, only implement a const comparison method for integers first. The operators >, <, >= and <= are already const for these types. Together with making std::cmp::Ordering::thenconst this will make doing a lexicographical on integer fields easier inside a const context.
After implementation for integers const comparison methods could be added to floating-point numbers and other primitives. Later more complex types could also be extended.
Decide on other types to implement a const comparison method for.
Drawbacks / open questions
Any comparisons involving generics like Vec<T> or (T, U) requires traits and can thus not be made const with this proposal.
The comparison of a type like String, which internally uses a Vec<u8>, could technically be const, just by special casing and by not relying on a generic Vec comparison implementation.
The same goes for any composition of primitives, such as arrays and tuples. This would however require even more special cases.
Name of the method: cmp? This would shadow the Ord trait, does that lead to complications? Alternative: compare, ...
Alternatives
Leave situation as is: >, <, <= and >= are already const for integers, thus a const cmp(self, other) -> std::cmp::Ordering does not pull it's weight to necessitate an addition to the standard library.
Wait for const traits and make a const version of Ord and PartialOrd,
Wait for const trait methods and make Ord::cmp and PartialOrd::partial_ordconst (breaking change).
If really necessary a local const helper method can easily be written by a user: const fn cmp(a: u8, b: u8) -> Ordering { if a < b { Less } else if a == b { Equal } else { Greater } }
The text was updated successfully, but these errors were encountered:
Const comparisons
Goal: Compare values inside
const
contexts.Most common cases of comparison logic:
When
#[feature(const_if_match)]
(#49146) lands almost all comparison logic could beconst
.Problem
Most types that can be compared just derive or implement
PartialOrd
andOrd
. However, as trait methods cannot beconst
(maybe in the far future if we have const traits), the logic inside thesecmp
andpartial_cmp
methods is unavailable inconst
contexts.The only exceptions to this are the
>
,<
,>=
,<=
operators for some primitives: floating-point numbers, integers,bool
,char
and!
, which are (I think)const
intrinsics. Note that these operators all result in abool
, there is noconst
comparison function resulting in astd::cmp::Ordering
. This makes customconst
lexicographical comparisons still hard to write compared to usingstd::cmp::Ordering::then
(also not yetconst
).Proposal
Add a const inherent comparison method to applicable types and let the
Ord
andPartialOrd
delegate to this method:As a conservative implementation, only implement a
const
comparison method for integers first. The operators>
,<
,>=
and<=
are alreadyconst
for these types. Together with makingstd::cmp::Ordering::then
const
this will make doing a lexicographical on integer fields easier inside aconst
context.After implementation for integers
const
comparison methods could be added to floating-point numbers and other primitives. Later more complex types could also be extended.Implementation
#[feature(const_if_match)]
(Tracking issue for RFC 2342, "Allowif
andmatch
in constants" #49146).const
comparison methods to integers (under Tracking Issue for more const int functions #53718).std::cmp::Ordering::then
const
.const
comparison method for.Drawbacks / open questions
Vec<T>
or(T, U)
requires traits and can thus not be madeconst
with this proposal.String
, which internally uses aVec<u8>
, could technically beconst
, just by special casing and by not relying on a genericVec
comparison implementation.cmp
? This would shadow theOrd
trait, does that lead to complications? Alternative:compare
, ...Alternatives
>
,<
,<=
and>=
are alreadyconst
for integers, thus aconst cmp(self, other) -> std::cmp::Ordering
does not pull it's weight to necessitate an addition to the standard library.const
traits and make aconst
version of Ord and PartialOrd,const
trait methods and makeOrd::cmp
andPartialOrd::partial_ord
const
(breaking change).const
helper method can easily be written by a user:const fn cmp(a: u8, b: u8) -> Ordering { if a < b { Less } else if a == b { Equal } else { Greater } }
The text was updated successfully, but these errors were encountered: