Skip to content

Allow both ::value_type and ::element_type in indirectly_readable_traits - #834

Merged
Casey Carter (CaseyCarter) merged 1 commit into
microsoft:masterfrom
CaseyCarter:value_type_element_type
May 15, 2020
Merged

Casey Carter (CaseyCarter) merged 1 commit into
microsoft:masterfrom
CaseyCarter:value_type_element_type

Conversation

@CaseyCarter

Copy link
Copy Markdown
Contributor

Per [readable.traits], indirectly_readable_traits::value_type is the same type as remove_cv_t if it denotes an object type, or remove_cv_t if it denotes an object type. If both T::value_type and T::element_type denote types, indirectly_readable_traits::value_type is ill-formed. This was perhaps not the best design, given that there are iterators in the wild (Boost's unordered containers) that define both nested types. indirectly_readable_traits should tolerate iterators that define both nested types consistently.

Fixes VSO-1121031.

Per [readable.traits], `indirectly_readable_traits::value_type` is the same type as `remove_cv_t` if it denotes an object type, or `remove_cv_t` if it denotes an object type. If both `T::value_type` and `T::element_type` denote types, `indirectly_readable_traits::value_type` is ill-formed. This was perhaps not the best design, given that there are iterators in the wild (Boost's unordered containers) that define both nested types. `indirectly_readable_traits` should tolerate iterators that define both nested types consistently.

Fixes VSO-1121031.
@CaseyCarter Casey Carter (CaseyCarter) added the bug Something isn't working label May 14, 2020
@CaseyCarter
Casey Carter (CaseyCarter) requested a review from a team as a code owner May 14, 2020 23:09

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks perfect to me - thanks for the "LWG issue pending" comment.

@miscco

Copy link
Copy Markdown
Contributor

I am gonna play dumb here (and you have to pretend that it is only a play Ha)

If the type does not have element_type but value_type is the second constraint-expression ill formed?

In my head I thought that we need to ensure that all constraints are well formed. Could we test that this does not blow up with a type that only features a value_type?

@cbezault

Copy link
Copy Markdown
Contributor

I believe that constraints are supposed to be short-circuited and evaluated from left to right.

From [temp.constr.op] A conjunction is a constraint taking two operands.
To determine if a conjunction is satisfied, the satisfaction of the first operand is checked.
If that is not satisfied, the conjunction is not satisfied.
Otherwise, the conjunction is satisfied if and only if the second operand is satisfied.

@CaseyCarter

Copy link
Copy Markdown
Contributor Author

SFINAE is in effect in constraints: substitution failure in an atomic constraint expression causes the constraint to be dissatisfied, rather than ill-formed. It's also the case, as Curtis J Bezault (@cbezault) mentions, that substitution and evaluation occur in lockstep, with satisfaction short-circuiting disjunctions and dissatisfaction short-circuiting conjunctions.

This constraint could equivalently be:

template <class T>
    requires same_as<remove_cv_t<typename T::value_type>,
        remove_cv_t<typename T::element_type>>
struct indirectly_readable_traits {};

but I have a style guideline that requires all typenames formed to be first mentioned in a type-requirement which hopefully makes it easier for compilers to provide good diagnostics.

@CaseyCarter
Casey Carter (CaseyCarter) merged commit 0e4c641 into microsoft:master May 15, 2020
@CaseyCarter
Casey Carter (CaseyCarter) deleted the value_type_element_type branch May 15, 2020 16:48
@CaseyCarter

Copy link
Copy Markdown
Contributor Author

Oops: I should have mentioned that MSVC has a substitution bug; it wants to substitute T into typename T::meow too early (https://godbolt.org/z/9w9uPZ):

template <class> inline constexpr auto meow = false;

template <class T> concept C = 
    true || meow<typename T::X>;

static_assert(C<int>);

which isn't a problem for this case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants