### 3329. `totally_ordered_with` both directly and indirectly requires `common_reference_with`

**Section:** 18.5.5 [concept.totallyordered] **Status:** C++20
**Submitter:** United States **Opened:** 2019-11-07 **Last modified:** 2021-02-25 10:48:01 UTC

**Priority: **0

**View all other** issues in [concept.totallyordered].

**View all issues with** C++20 status.

**Discussion:**

**Addresses US 201**

The `totally_ordered_with<T, U>` redundantly requires both
`common_reference_with<const remove_reference_t&, const
remove_reference_t&>` and `equality_comparable_with<T,
U>` (which also has the `common_reference_with` requirement). The
redundant requirement should be removed.

Proposed change:

Change the definition of `totally_ordered_with` to:

template<class T, class U>
concept totally_ordered_with =
totally_ordered<T> && totally_ordered<U> &&
equality_comparable_with<T, U> &&
totally_ordered<
common_reference_t<
const remove_reference_t<T>&,
const remove_reference_t<U<&>> &&
requires(const remove_reference_t<T<& t,
const remove_reference_t>U>& u) {
[… as before …]

*[2019-11 Moved to Ready on Friday AM in Belfast]*

**Proposed resolution:**

This wording is relative to N4835.

Change 18.5.5 [concept.totallyordered] as indicated:

For some type `T`, let `a`, `b`, and `c` be lvalues
of type `const remove_reference_t<T>`. `T` models
`totally_ordered` only if

(1.1) — Exactly one of `bool(a < b)`, `bool(a > b)`, or `bool(a == b)` is
`true`.

(1.2) — If `bool(a < b)` and `bool(b < c)`, then `bool(a < c)`.

(1.3) — `bool(a > b) == bool(b < a)`.

(1.4) — `bool(a <= b) == !bool(b < a)`.

(1.5) — `bool(a >= b) == !bool(a < b)`.

template<class T, class U>
concept totally_ordered_with =
totally_ordered<T> && totally_ordered<U> &&
~~common_reference_with<const remove_reference_t<T>&, const remove_reference_t<U>&> &&~~
equality_comparable_with<T, U> &&
totally_ordered<
common_reference_t<
const remove_reference_t<T>&,
const remove_reference_t<U>&>> &&
~~equality_comparable_with<T, U> &&~~
requires(const remove_reference_t<T>& t,
const remove_reference_t<U>& u) {
{ t < u } -> boolean;
{ t > u } -> boolean;
{ t <= u } -> boolean;
{ t >= u } -> boolean;
{ u < t } -> boolean;
{ u > t } -> boolean;
{ u <= t } -> boolean;
{ u >= t } -> boolean;
};