![]() |
Arene Base
Fundamental Utilities For Safety Critical C++
|
A "Three-way comparison" between two objects yields a result indicating which of the 3 relative orderings apply: are the values equal, the first less than the second, or the first greater than the second. This is the fundamental operation that the C++20 three-way-comparison operator (also known as the spaceship operator) performs, as does the C strcmp function.
arene::base::three_way_compare is a function object type that performs this three-way comparison for any types that provide ordering comparisons. Instances of arene::base::three_way_compare can be called with two arguments, and the result is a arene::base::strong_ordering value indicating the result of the comparison. For built-in types, and types without a custom three-way comparison, the result is determined either using operator== and operator< if both are available, or just operator< if that is all that is available. If the operators are not available, and the first argument type does not provide a custom three-way comparison, then the comparison is ill-formed.
You can specify a three-way comparison operation for your type by writing a static member function called three_way_compare that accepts the two values to be compared and returns an instance of arene::base::strong_ordering:
This member function will then be used by the arene::base::three_way_compare function object in preference to any comparison operators: if the first parameter is a class type that has a static member function named three_way_compare that accepts the values to be compared and returns arene::base::strong_ordering, then that member function is used for the comparison.
Note that the second argument does not have to be the same as your class type, so this can be used to define three-way comparison with other types.
The arene::base::three_way_compare function object might be used for the implementation, if the result is just the result of comparing data members.
If you have a class with multiple data members, and you wish to write a three_way_compare function that compares all the data members, you can use std::tie to do this:
This creates std::tuples that hold references to the data members, and compares those. This is a lexicographical ordering based on the order specified to std::tie, so if lhs.val1 is less than rhs.val1 then the result is arene::base::strong_ordering::less even if lhs.val2 is greater than rhs.val2.
Currently this uses the operator< and operator== for the individual elements, rather than any three_way_compare operations defined for the data member types, but future versions will use three_way_compare for the data members if available.