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

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.

  1. 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.1) — Exactly one of bool(a < b), bool(a > b), or bool(a == b) is true.

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

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

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

    5. (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;
        };