5.6 KiB
| title |
|---|
| compare |
{{< callout type="info">}}
Header: compare.h
Since: TBC
{{< /callout >}}
A helper for deriving comparison operations from a strict weak ordering.
etl::compare<T, TLess> exposes boolean predicates and a three-state comparison result.
etl::three_way_compare returns -1, 0, or 1 using the same comparison policy.
template <typename T, typename TLess = etl::less<T> >
struct compare
template <typename T, typename TLess = etl::less<T> >
ETL_CONSTEXPR14 int three_way_compare(const T& lhs, const T& rhs)
Types
first_argument_type;
second_argument_type;
cmp_result;
cmp_result defines the values Less, Equal, and Greater.
Members
static bool lt(first_argument_type lhs, second_argument_type rhs)
Description
Less than.
Return
true if TLess()(lhs, rhs), otherwise false.
static bool lte(first_argument_type lhs, second_argument_type rhs)
Description
Less than or equal.
Return
true if lhs is less than or equal to rhs, otherwise false.
static bool gt(first_argument_type lhs, second_argument_type rhs)
Description
Greater than.
Return
true if lhs is greater than rhs, otherwise false.
static bool gte(first_argument_type lhs, second_argument_type rhs)
Description
Greater than or equal.
Return
true if lhs is greater than or equal to rhs, otherwise false.
static bool eq(first_argument_type lhs, second_argument_type rhs)
Description
Equal.
Return
true if neither value compares less than the other, otherwise false.
static bool ne(first_argument_type lhs, second_argument_type rhs)
Description
Not equal.
Return
true if if either value compare less than the other, otherwise false.
static cmp_result cmp(first_argument_type lhs, second_argument_type rhs)
Return
Less, Equal, or Greater.
Three-way comparison
etl::three_way_compare(lhs, rhs) returns the same ordering as compare<T, TLess>::cmp(lhs, rhs),
but as an int with the values -1, 0, or 1.
C++20 comparison categories
When compiling as C++20, compare.h makes the comparison categories available in the etl
namespace, so ETL and user code can name them regardless of the STL configuration.
class strong_ordering;
class weak_ordering;
class partial_ordering;
- When the STL is available these are aliases for
std::strong_ordering,std::weak_orderingandstd::partial_ordering. - When the STL is not available,
compare.hprovides its own minimal implementations that follow the standard semantics: the named valuesless,equivalent,greater(plusequalforstrong_orderingandunorderedforpartial_ordering), comparison against the literal0only, and the implicit conversionsstrong_ordering→weak_ordering→partial_ordering.
An unordered result compares false against 0 for all of <, <=, ==, >= and >.
ETL_CONSTEXPR strong_ordering make_strong_ordering(int value) ETL_NOEXCEPT;
ETL_CONSTEXPR weak_ordering make_weak_ordering(int value) ETL_NOEXCEPT;
ETL_CONSTEXPR partial_ordering make_partial_ordering(int value) ETL_NOEXCEPT;
These helpers convert a three-way comparison result, such as the one returned by
etl::three_way_compare, into a comparison category. Negative values map to less, positive
values to greater, and zero to equal/equivalent. unordered cannot be expressed as an
integer result, so use etl::partial_ordering::unordered directly for that case.
Example 1
struct Test
{
int a;
int b;
};
using Compare = etl::compare<Test>;
// Define the 'less-than' operator.
bool operator <(const Test& lhs, const Test& rhs)
{
return (lhs.a + lhs.b) < (rhs.a + rhs.b);
}
// Define the rest in terms of Compare.
bool operator <=(const Test& lhs, const Test& rhs)
{
return Compare::lte(lhs, rhs);
}
bool operator >(const Test& lhs, const Test& rhs)
{
return Compare::gt(lhs, rhs);
}
bool operator >=(const Test& lhs, const Test& rhs)
{
return Compare::gte(lhs, rhs);
}
int operator <=>(const Test& lhs, const Test& rhs)
{
return etl::three_way_compare(lhs, rhs);
}
Example 2
Separate 'less-than' class.
struct Test
{
int a;
int b;
};
struct LessThan
{
bool operator()(const Test& lhs, const Test& rhs) const
{
return (lhs.a + lhs.b) < (rhs.a + rhs.b);
}
};
using Compare = etl::compare<Test, LessThan>;
bool operator <(const Test& lhs, const Test& rhs)
{
return Compare::lt(lhs, rhs);
}
bool operator <=(const Test& lhs, const Test& rhs)
{
return Compare::lte(lhs, rhs);
}
bool operator >(const Test& lhs, const Test& rhs)
{
return Compare::gt(lhs, rhs);
}
bool operator >=(const Test& lhs, const Test& rhs)
{
return Compare::gte(lhs, rhs);
}
int operator <=>(const Test& lhs, const Test& rhs)
{
return etl::three_way_compare<Test, LessThan>(lhs, rhs);
}
Example 3
Inheritance
struct Test : public etl::compare<Test>
{
int a;
int b;
};
// Define the 'less-than' operator.
bool operator <(const Test& lhs, const Test& rhs)
{
return (lhs.a + lhs.b) < (rhs.a + rhs.b);
}
// Define the rest.
bool operator <=(const Test& lhs, const Test& rhs)
{
return Test::lte(lhs, rhs);
}
bool operator >(const Test& lhs, const Test& rhs)
{
return Test::gt(lhs, rhs);
}
bool operator >=(const Test& lhs, const Test& rhs)
{
return Test::gte(lhs, rhs);
}
Example 4
C++20, with or without the STL.
etl::strong_ordering operator <=>(const Test& lhs, const Test& rhs)
{
return etl::make_strong_ordering(etl::three_way_compare(lhs, rhs));
}