[concepts.compare] (original) (raw)

18 Concepts library [concepts]

18.5 Comparison concepts [concepts.compare]

18.5.1 General [concepts.compare.general]

Subclause [concepts.compare] describes concepts that establish relationships and orderings on values of possibly differing object types.

Given an expression E and a type C, let CONVERT_TO_LVALUE<C>(E) be:

18.5.2 Boolean testability [concept.booleantestable]

Let e be an expression such thatdecltype((e)) is T.

T models boolean-testable-impl only if

A disqualifying parameteris a function parameter whose declared type P

A key parameter of a function template Dis a function parameter of type cv X or reference thereto, where X names a specialization of a class template that has the same innermost enclosing non-inline namespace as D, andX contains at least one template parameter that participates in template argument deduction.

[Example 1:

Innamespace Z { template<class> struct C {};template<class T> void operator&&(C<T> x, T y);template<class T> void operator||(C<type_identity_t<T>> x, T y);} the declaration of Z​::​operator&&contains one key parameter, C<T> x, and the declaration of Z​::​operator||contains no key parameters.

— _end example_]

A disqualifying declaration is

[Note 1:

The intention is to ensure that given two types T1 and T2that each model boolean-testable-impl, the && and || operators within the expressionsdeclval<T1>() && declval<T2>() anddeclval<T1>() || declval<T2>()resolve to the corresponding built-in operators.

— _end note_]

template<class T> concept [_boolean-testable_](#concept:boolean-testable "18.5.2 Boolean testability [concept.booleantestable]") = // _exposition only_ [_boolean-testable-impl_](#concept:boolean-testable-impl "18.5.2 Boolean testability [concept.booleantestable]")<T> && requires(T&& t) { { !std::forward<T>(t) } -> [_boolean-testable-impl_](#concept:boolean-testable-impl "18.5.2 Boolean testability [concept.booleantestable]");};

Let e be an expression such thatdecltype((e)) is T.

T models boolean-testable only ifbool(e) == !bool(!e).

[Example 2:

— _end example_]

18.5.3 Comparison common types [concept.comparisoncommontype]

template<class T, class U, class C = common_reference_t<const T&, const U&>> concept [_comparison-common-type-with-impl_](#concept:comparison-common-type-with-impl "18.5.3 Comparison common types [concept.comparisoncommontype]") = // _exposition only_ [same_as](concept.same#concept:same%5Fas "18.4.2 Concept same_­as [concept.same]")<common_reference_t<const T&, const U&>, common_reference_t<const U&, const T&>> && requires { requires [convertible_to](concept.convertible#concept:convertible%5Fto "18.4.4 Concept convertible_­to [concept.convertible]")<const T&, const C&> || [convertible_to](concept.convertible#concept:convertible%5Fto "18.4.4 Concept convertible_­to [concept.convertible]")<T, const C&>;requires [convertible_to](concept.convertible#concept:convertible%5Fto "18.4.4 Concept convertible_­to [concept.convertible]")<const U&, const C&> || [convertible_to](concept.convertible#concept:convertible%5Fto "18.4.4 Concept convertible_­to [concept.convertible]")<U, const C&>;};template<class T, class U> concept [_comparison-common-type-with_](#concept:comparison-common-type-with "18.5.3 Comparison common types [concept.comparisoncommontype]") = // _exposition only_ [_comparison-common-type-with-impl_](#concept:comparison-common-type-with-impl "18.5.3 Comparison common types [concept.comparisoncommontype]")<remove_cvref_t<T>, remove_cvref_t<U>>;

Let C be common_reference_t<const T&, const U&>.

Let t1 and t2 be equality-preserving expressions that are lvalues of type remove_cvref_t<T>, and let u1 and u2 be equality-preserving expressions that are lvalues of type remove_cvref_t<U>.

T and U modelcomparison-common-type-with<T, U> only if

18.5.4 Concept equality_comparable [concept.equalitycomparable]

template<class T, class U> concept [_weakly-equality-comparable-with_](#concept:weakly-equality-comparable-with "18.5.4 Concept equality_­comparable [concept.equalitycomparable]") = // _exposition only_ requires(const remove_reference_t<T>& t,const remove_reference_t<U>& u) { { t == u } -> [_boolean-testable_](#concept:boolean-testable "18.5.2 Boolean testability [concept.booleantestable]");{ t != u } -> [_boolean-testable_](#concept:boolean-testable "18.5.2 Boolean testability [concept.booleantestable]");{ u == t } -> [_boolean-testable_](#concept:boolean-testable "18.5.2 Boolean testability [concept.booleantestable]");{ u != t } -> [_boolean-testable_](#concept:boolean-testable "18.5.2 Boolean testability [concept.booleantestable]");};

Given types T and U, let t and u be lvalues of typesconst remove_reference_t<T> andconst remove_reference_t<U> respectively.

T and U modelweakly-equality-comparable-with<T, U> only if

template<class T> concept [equality_comparable](#concept:equality%5Fcomparable "18.5.4 Concept equality_­comparable [concept.equalitycomparable]") = [_weakly-equality-comparable-with_](#concept:weakly-equality-comparable-with "18.5.4 Concept equality_­comparable [concept.equalitycomparable]")<T, T>;

Let a and b be objects of type T.

T models equality_comparable only ifbool(a == b) is true when a is equal tob ([concepts.equality]), and false otherwise.

[Note 1:

The requirement that the expression a == b is equality-preserving implies that == is transitive and symmetric.

— _end note_]

template<class T, class U> concept [equality_comparable_with](#concept:equality%5Fcomparable%5Fwith "18.5.4 Concept equality_­comparable [concept.equalitycomparable]") = [equality_comparable](#concept:equality%5Fcomparable "18.5.4 Concept equality_­comparable [concept.equalitycomparable]")<T> && [equality_comparable](#concept:equality%5Fcomparable "18.5.4 Concept equality_­comparable [concept.equalitycomparable]")<U> && [_comparison-common-type-with_](#concept:comparison-common-type-with "18.5.3 Comparison common types [concept.comparisoncommontype]")<T, U> && [equality_comparable](#concept:equality%5Fcomparable "18.5.4 Concept equality_­comparable [concept.equalitycomparable]")< common_reference_t< const remove_reference_t<T>&,const remove_reference_t<U>&>> && [_weakly-equality-comparable-with_](#concept:weakly-equality-comparable-with "18.5.4 Concept equality_­comparable [concept.equalitycomparable]")<T, U>;

Given types T and U, let t and t2 be lvalues denoting distinct equal objects of types const remove_reference_t<T> andremove_cvref_t<T>, respectively, let u and u2 be lvalues denoting distinct equal objects of types const remove_reference_t<U> andremove_cvref_t<U>, respectively, and let C be:common_reference_t<const remove_reference_t<T>&, const remove_reference_t<U>&> T and U modelequality_comparable_with<T, U> only ifbool(t == u) == bool(CONVERT_TO_LVALUE<C>(t2) == CONVERT_TO_LVALUE<C>(u2))

18.5.5 Concept totally_ordered [concept.totallyordered]

Given a type T, let a, b, and c be lvalues of type const remove_reference_t<T>.

T models totally_ordered only if

template<class T, class U> concept [totally_ordered_with](#concept:totally%5Fordered%5Fwith "18.5.5 Concept totally_­ordered [concept.totallyordered]") = [totally_ordered](#concept:totally%5Fordered "18.5.5 Concept totally_­ordered [concept.totallyordered]")<T> && [totally_ordered](#concept:totally%5Fordered "18.5.5 Concept totally_­ordered [concept.totallyordered]")<U> && [equality_comparable_with](#concept:equality%5Fcomparable%5Fwith "18.5.4 Concept equality_­comparable [concept.equalitycomparable]")<T, U> && [totally_ordered](#concept:totally%5Fordered "18.5.5 Concept totally_­ordered [concept.totallyordered]")< common_reference_t< const remove_reference_t<T>&,const remove_reference_t<U>&>> && [_partially-ordered-with_](cmp.concept#concept:partially-ordered-with "17.12.4 Concept three_­way_­comparable [cmp.concept]")<T, U>;

Given types T and U, let t and t2 be lvalues denoting distinct equal objects of types const remove_reference_t<T> andremove_cvref_t<T>, respectively, let u and u2 be lvalues denoting distinct equal objects of types const remove_reference_t<U> andremove_cvref_t<U>, respectively, and let C be:common_reference_t<const remove_reference_t<T>&, const remove_reference_t<U>&> T and U modeltotally_ordered_with<T, U> only if