This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++20 status.

### 3331. Define `totally_ordered/_with` in terms of `partially-ordered-with`

Section: 18.5.4 [concept.totallyordered] Status: C++20 Submitter: Great Britain Opened: 2019-11-08 Last modified: 2021-02-25

Priority: 0

View all other issues in [concept.totallyordered].

View all issues with C++20 status.

Discussion:

Addresses GB 202

Define `totally_ordered[_with]` in terms of `partially-ordered-with`. This will simplify the definition of both concepts (particularly `totally_ordered_with`), and make them in-line with `equality_comparable[_with]`. Now that we've defined `partially-ordered-with` for 17.11.4 [cmp.concept], we should consider utilising it in as many locations as possible.

Proposed change:

    template<class T>
      concept totally_ordered =
        equality_comparable<T> &&
        partially-ordered-with<T, T>;

    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>&> &&
        totally_ordered<
          common_reference_t<
            const remove_reference_t<T>&,
            const remove_reference_t<U>&>> &&
        equality_comparable_with<T, U> &&
        partially-ordered-with<T, U>;

LWG discussion in Belfast notes that 3329 also touches the definition of `totally_ordered_with`; the two sets of changes are consistent.

[2019-11 Status to Ready Friday afternoon LWG in Belfast]

Proposed resolution:

This wording is relative to N4835.

1. Change 18.5.4 [concept.totallyordered] as follows:

   >     template<class T>
   >       concept totally_ordered =
   >         equality_comparable<T> && partially-ordered-with<T, T>;
   >         requires(const remove_reference_t<T>& a,
   >                  const remove_reference_t<T>& b) {
   >           { a <  b } -> boolean;
   >           { a >  b } -> boolean;
   >           { a <= b } -> boolean;
   >           { a >= b } -> boolean;
   >         };

   > -1- 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>&> &&
   >         totally_ordered<
   >           common_reference_t<
   >             const remove_reference_t<T>&,
   >             const remove_reference_t<U>&>> &&
   >           equality_comparable_with<T, U> &&
   >           partially-ordered-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;
   >           };

   > […]