Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/concepts/totally ordered"

From cppreference.com
< cpp‎ | concepts
(P2404R3 Move-only types for equality_comparable_with, totally_ordered_with, and three_way_comparable_with)
m (fmt.)
 
(5 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{cpp/title|totally_ordered|totally_ordered_with}}
+
{{cpp/title|totally_ordered {{mark since c++20}}|totally_ordered_with {{mark since c++20}}}}
 
{{cpp/concepts/navbar}}
 
{{cpp/concepts/navbar}}
 
{{dcl begin}}
 
{{dcl begin}}
Line 6: Line 6:
 
template< class T >
 
template< class T >
 
concept totally_ordered =
 
concept totally_ordered =
  std::equality_comparable<T> && __PartiallyOrderedWith<T, T>;
+
    std::equality_comparable<T> && __PartiallyOrderedWith<T, T>;
 
}}
 
}}
 
{{dcl|since=c++20|num=2|1=
 
{{dcl|since=c++20|num=2|1=
 
template< class T, class U >
 
template< class T, class U >
 
concept totally_ordered_with =
 
concept totally_ordered_with =
  std::totally_ordered<T> &&
+
    std::totally_ordered<T> &&
  std::totally_ordered<U> &&
+
    std::totally_ordered<U> &&
  std::equality_comparable_with<T, U> &&
+
    std::equality_comparable_with<T, U> &&
  std::totally_ordered<
+
    std::totally_ordered<
    std::common_reference_t<
+
        std::common_reference_t<
      const std::remove_reference_t<T>&,
+
            const std::remove_reference_t<T>&,
      const std::remove_reference_t<U>&>> &&
+
            const std::remove_reference_t<U>&>> &&
  __PartiallyOrderedWith<T, U>;
+
    __PartiallyOrderedWith<T, U>;
 
}}
 
}}
 +
{{dcl h|Helper concepts}}
 
{{dcl|notes={{mark expos}}|num=3|1=
 
{{dcl|notes={{mark expos}}|num=3|1=
 
template< class T, class U >
 
template< class T, class U >
 
concept __PartiallyOrderedWith =
 
concept __PartiallyOrderedWith =
  requires(const std::remove_reference_t<T>& t,
+
    requires(const std::remove_reference_t<T>& t,
          const std::remove_reference_t<U>& u) {
+
            const std::remove_reference_t<U>& u) {
    { t <  u } -> boolean-testable;
+
        { t <  u } -> boolean-testable;
    { t >  u } -> boolean-testable;
+
        { t >  u } -> boolean-testable;
    { t <= u } -> boolean-testable;
+
        { t <= u } -> boolean-testable;
    { t >= u } -> boolean-testable;
+
        { t >= u } -> boolean-testable;
    { u <  t } -> boolean-testable;
+
        { u <  t } -> boolean-testable;
    { u >  t } -> boolean-testable;
+
        { u >  t } -> boolean-testable;
    { u <= t } -> boolean-testable;
+
        { u <= t } -> boolean-testable;
    { u >= t } -> boolean-testable;
+
        { u >= t } -> boolean-testable;
  };
+
    };
 
}}
 
}}
 
{{dcl end}}
 
{{dcl end}}
Line 41: Line 42:
 
@2@ The concept {{tt|std::totally_ordered_with}} specifies that the comparison operators {{tt|1===,!=,<,>,<=,>=}} on (possibly mixed) {{tt|T}} and {{tt|U}} operands yield results consistent with a strict total order. Comparing mixed operands yields results equivalent to comparing the operands converted to their common type.
 
@2@ The concept {{tt|std::totally_ordered_with}} specifies that the comparison operators {{tt|1===,!=,<,>,<=,>=}} on (possibly mixed) {{tt|T}} and {{tt|U}} operands yield results consistent with a strict total order. Comparing mixed operands yields results equivalent to comparing the operands converted to their common type.
  
@3@ The exposition-only concept {{tt|''__PartiallyOrderedWith''}} specifies that a value of type {{tt|T}} and a value of type {{tt|U}} can be compared in a partial order with each other (in either order) using {{tt|<}}, {{tt|>}}, {{tt|1=<=}}, and {{tt|1=>=}}, and the results of the comparisons are consistent.
+
@3@ The exposition-only concept {{tti|__PartiallyOrderedWith}} specifies that a value of type {{tt|T}} and a value of type {{tt|U}} can be compared in a partial order with each other (in either order) using {{tt|<}}, {{tt|>}}, {{tt|1=<=}}, and {{tt|1=>=}}, and the results of the comparisons are consistent.
  
 
===Semantic requirements===
 
===Semantic requirements===
Line 47: Line 48:
  
 
@1@ {{c|std::totally_ordered<T>}} is modeled only if, given lvalues {{tt|a}}, {{tt|b}} and {{tt|c}} of type {{c|const std::remove_reference_t<T>}}:
 
@1@ {{c|std::totally_ordered<T>}} is modeled only if, given lvalues {{tt|a}}, {{tt|b}} and {{tt|c}} of type {{c|const std::remove_reference_t<T>}}:
* Exactly one of {{c|bool(a < b)}}, {{c|bool(a > b)}} and {{c|bool(a {{==}} b)}} is {{c|true}};
+
* Exactly one of {{c|bool(a < b)}}, {{c|bool(a > b)}} and {{c|1=bool(a == b)}} is {{c|true}};
 
* If {{c|bool(a < b)}} and {{c|bool(b < c)}} are both {{c|true}}, then {{c|bool(a < c)}} is {{c|true}};
 
* If {{c|bool(a < b)}} and {{c|bool(b < c)}} are both {{c|true}}, then {{c|bool(a < c)}} is {{c|true}};
 
* {{c|1=bool(a > b) == bool(b < a)}}
 
* {{c|1=bool(a > b) == bool(b < a)}}
Line 86: Line 87:
  
 
{{cpp/concepts/implicit expression variations}}
 
{{cpp/concepts/implicit expression variations}}
 +
 +
===References===
 +
{{ref std c++23}}
 +
{{ref std|section=18.5.5|title=Concept {{tt|totally_ordered}}|id=concept.totallyordered}}
 +
{{ref std end}}
 +
{{ref std c++20}}
 +
{{ref std|section=18.5.4|title=Concept {{tt|totally_ordered}}|id=concept.totallyordered}}
 +
{{ref std end}}
  
 
===See also===
 
===See also===

Latest revision as of 16:24, 7 September 2024

Defined in header <concepts>
template< class T >

concept totally_ordered =

    std::equality_comparable<T> && __PartiallyOrderedWith<T, T>;
(1) (since C++20)
template< class T, class U >

concept totally_ordered_with =
    std::totally_ordered<T> &&
    std::totally_ordered<U> &&
    std::equality_comparable_with<T, U> &&
    std::totally_ordered<
        std::common_reference_t<
            const std::remove_reference_t<T>&,
            const std::remove_reference_t<U>&>> &&

    __PartiallyOrderedWith<T, U>;
(2) (since C++20)
Helper concepts
template< class T, class U >

concept __PartiallyOrderedWith =
    requires(const std::remove_reference_t<T>& t,
             const std::remove_reference_t<U>& u) {
        { t <  u } -> boolean-testable;
        { t >  u } -> boolean-testable;
        { t <= u } -> boolean-testable;
        { t >= u } -> boolean-testable;
        { u <  t } -> boolean-testable;
        { u >  t } -> boolean-testable;
        { u <= t } -> boolean-testable;
        { u >= t } -> boolean-testable;

    };
(3) (exposition only*)
1) The concept std::totally_ordered specifies that the comparison operators ==,!=,<,>,<=,>= on a type yield results consistent with a strict total order on the type.
2) The concept std::totally_ordered_with specifies that the comparison operators ==,!=,<,>,<=,>= on (possibly mixed) T and U operands yield results consistent with a strict total order. Comparing mixed operands yields results equivalent to comparing the operands converted to their common type.
3) The exposition-only concept __PartiallyOrderedWith specifies that a value of type T and a value of type U can be compared in a partial order with each other (in either order) using <, >, <=, and >=, and the results of the comparisons are consistent.

Contents

[edit] Semantic requirements

These concepts are modeled only if they are satisfied and all concepts they subsume are modeled.

1) std::totally_ordered<T> is modeled only if, given lvalues a, b and c of type const std::remove_reference_t<T>:
  • Exactly one of bool(a < b), bool(a > b) and bool(a == b) is true;
  • If bool(a < b) and bool(b < c) are both true, then bool(a < c) is true;
  • bool(a > b) == bool(b < a)
  • bool(a >= b) == !bool(a < b)
  • bool(a <= b) == !bool(b < a)
2) std::totally_ordered_with<T, U> is modeled only if, given

let C be std::common_reference_t<const std::remove_reference_t<T>&, const std::remove_reference_t<U>&>, and, given an expression E and a type C, let CONVERT_TO<C>(E) be:

(until C++23)
  • static_cast<const C&>(std::as_const(E)) if that is a valid expression,
  • static_cast<const C&>(std::move(E)) otherwise.
(since C++23)

the following are true:

  • bool(t < u) == bool(CONVERT_TO<C>(t2) < CONVERT_TO<C>(u2))
  • bool(t > u) == bool(CONVERT_TO<C>(t2) > CONVERT_TO<C>(u2))
  • bool(t <= u) == bool(CONVERT_TO<C>(t2) <= CONVERT_TO<C>(u2))
  • bool(t >= u) == bool(CONVERT_TO<C>(t2) >= CONVERT_TO<C>(u2))
  • bool(u < t) == bool(CONVERT_TO<C>(u2) < CONVERT_TO<C>(t2))
  • bool(u > t) == bool(CONVERT_TO<C>(u2) > CONVERT_TO<C>(t2))
  • bool(u <= t) == bool(CONVERT_TO<C>(u2) <= CONVERT_TO<C>(t2))
  • bool(u >= t) == bool(CONVERT_TO<C>(u2) >= CONVERT_TO<C>(t2))
3) __PartiallyOrderedWith<T, U> is modeled only if given

the following are true:

  • t < u, t <= u, t > u, t >= u, u < t, u <= t, u > t, and u >= t have the same domain;
  • bool(t < u) == bool(u > t);
  • bool(u < t) == bool(t > u);
  • bool(t <= u) == bool(u >= t); and
  • bool(u <= t) == bool(t >= u).

[edit] Equality preservation

Expressions declared in requires expressions of the standard library concepts are required to be equality-preserving (except where stated otherwise).

[edit] Implicit expression variations

A requires expression that uses an expression that is non-modifying for some constant lvalue operand also requires implicit expression variations.

[edit] References

  • C++23 standard (ISO/IEC 14882:2024):
  • 18.5.5 Concept totally_ordered [concept.totallyordered]
  • C++20 standard (ISO/IEC 14882:2020):
  • 18.5.4 Concept totally_ordered [concept.totallyordered]

[edit] See also

specifies that operator <=> produces consistent result on given types
(concept) [edit]