mirror of
https://github.com/ETLCPP/etl.git
synced 2026-11-10 15:19:50 +08:00
* Updated atomic documentation * Modified fetch_add and fetch_sub documentation * Various documantation fixes --------- Co-authored-by: John Wellbelove <john.wellbelove@etlcpp.com>
268 lines
5.6 KiB
Markdown
268 lines
5.6 KiB
Markdown
---
|
|
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.
|
|
|
|
```cpp
|
|
template <typename T, typename TLess = etl::less<T> >
|
|
struct compare
|
|
```
|
|
|
|
```cpp
|
|
template <typename T, typename TLess = etl::less<T> >
|
|
ETL_CONSTEXPR14 int three_way_compare(const T& lhs, const T& rhs)
|
|
```
|
|
|
|
## Types
|
|
```cpp
|
|
first_argument_type;
|
|
second_argument_type;
|
|
cmp_result;
|
|
```
|
|
|
|
`cmp_result` defines the values `Less`, `Equal`, and `Greater`.
|
|
|
|
## Members
|
|
```cpp
|
|
static bool lt(first_argument_type lhs, second_argument_type rhs)
|
|
```
|
|
**Description**
|
|
Less than.
|
|
|
|
**Return**
|
|
`true` if `TLess()(lhs, rhs)`, otherwise `false`.
|
|
|
|
---
|
|
|
|
```cpp
|
|
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`.
|
|
|
|
---
|
|
|
|
```cpp
|
|
static bool gt(first_argument_type lhs, second_argument_type rhs)
|
|
```
|
|
**Description**
|
|
Greater than.
|
|
|
|
**Return**
|
|
`true` if `lhs` is greater than `rhs`, otherwise `false`.
|
|
|
|
---
|
|
|
|
```cpp
|
|
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`.
|
|
|
|
---
|
|
|
|
```cpp
|
|
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`.
|
|
|
|
---
|
|
|
|
```cpp
|
|
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`.
|
|
|
|
---
|
|
|
|
```cpp
|
|
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.
|
|
|
|
```cpp
|
|
class strong_ordering;
|
|
class weak_ordering;
|
|
class partial_ordering;
|
|
```
|
|
|
|
* When the STL is available these are aliases for `std::strong_ordering`, `std::weak_ordering`
|
|
and `std::partial_ordering`.
|
|
* When the STL is not available, `compare.h` provides its own minimal implementations that
|
|
follow the standard semantics: the named values `less`, `equivalent`, `greater`
|
|
(plus `equal` for `strong_ordering` and `unordered` for `partial_ordering`), comparison
|
|
against the literal `0` only, and the implicit conversions
|
|
`strong_ordering` → `weak_ordering` → `partial_ordering`.
|
|
|
|
An `unordered` result compares `false` against `0` for all of `<`, `<=`, `==`, `>=` and `>`.
|
|
|
|
```cpp
|
|
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
|
|
```cpp
|
|
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.
|
|
```cpp
|
|
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
|
|
|
|
```cpp
|
|
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.
|
|
|
|
```cpp
|
|
etl::strong_ordering operator <=>(const Test& lhs, const Test& rhs)
|
|
{
|
|
return etl::make_strong_ordering(etl::three_way_compare(lhs, rhs));
|
|
}
|
|
```
|