Reputation: 36451
I want to make sure I properly understand the constraint normalization process since cppreference is slightly fuzzy on this topic.
It seems that during the normalization, anything that is inside of a requires
expression is always considered an atom, no matter how specific/complex.
This seems to be supported by the different handling of:
template<typename T>
concept Decrementable = requires(T t) { --t; };
template<typename T>
concept RevIterator = Decrementable<T> && requires(T t) { *t; };
template<typename T>
concept RevIterator2 = requires(T t) { --t; *t; };
Where Decrementable < RevIterator
but Decrementable
and RevIterator2
are not ordered.
So, is this correct? Or can someone point me to the specific part of the standard that talks about this?
Upvotes: 5
Views: 126
Reputation: 170211
Yes your understanding is correct. For subsumption (what you denote by <
) to occur, there has to be a certain relationship between the normal forms of the constraint expression. And if one examines the constraint normalization process:
[temp.constr.normal]
1 The normal form of an expression E is a constraint that is defined as follows:
- The normal form of an expression
( E )
is the normal form ofE
.- The normal form of an expression
E1 || E2
is the disjunction of the normal forms ofE1
andE2
.- The normal form of an expression
E1 && E2
is the conjunction of the normal forms ofE1
andE2
.- The normal form of a concept-id
C<A1, A2, ..., An>
is the normal form of the constraint-expression ofC
, after substitutingA1
,A2
, ...,An
forC
's respective template parameters in the parameter mappings in each atomic constraint. If any such substitution results in an invalid type or expression, the program is ill-formed; no diagnostic is required.
[ ... ]- The normal form of any other expression
E
is the atomic constraint whose expression is E and whose parameter mapping is the identity mapping.
one sees that logical AND expressions, logical OR expressions, and concept-ids are the only expressions that get "broken down". Every other sort of expression pretty much forms its own atomic constraint, including a requires
expression like requires(T t) { --t; *t; }
.
Upvotes: 5
Reputation: 474316
The rules of constraint expression normalization act recursively top-down. If an expression is not a conjunction/disjunction of two expressions, is not a parenthesized expression, and is not a concept name, then it is an atomic constraint expression. A requires
expression is not one of those exceptions, so it is an atomic constraint expression.
Upvotes: 1