Šimon Tóth
Šimon Tóth

Reputation: 36451

Is a requires expression an atom when normalizing constraints?

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

Answers (2)

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 of E.
  • The normal form of an expression E1 || E2 is the disjunction of the normal forms of E1 and E2.
  • The normal form of an expression E1 && E2 is the conjunction of the normal forms of E1 and E2.
  • The normal form of a concept-id C<A1, A2, ..., An> is the normal form of the constraint-expression of C, after substituting A1, A2, ..., An for C'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

Nicol Bolas
Nicol Bolas

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

Related Questions