This is an archive of the discontinued LLVM Phabricator instance.

Implement P0340R3: Make `underlying_type` SFINAE-friendly
ClosedPublic

Authored by mclow.lists on Jun 19 2019, 2:27 PM.

Details

Summary

https://wg21.link/P0340R3

There are two possible approaches here:

  • A library-only solution (this patch)
  • Some compiler work (updating the __underlying_type intrinsic)

After working on this for a bit, I think this is the better approach.

Diff Detail

Event Timeline

mclow.lists created this revision.Jun 19 2019, 2:27 PM
mclow.lists marked an inline comment as done.Jun 19 2019, 2:33 PM

Note: There is no feature test macro for this.

libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.fail.cpp
20

I can add an expected-error {{cannot determine underlying type of incomplete enumeration type 'E1'}} here if people want.

How many of these should fail?

enum E1                   { E1Zero, E1One, E1Two = sizeof(std::underlying_type<E1>::type) };
enum E2 : char            { E2Zero, E2One, E2Two = sizeof(std::underlying_type<E2>::type) };
enum class E3             { E3Zero, E3One, E3Two = sizeof(std::underlying_type<E3>::type) };
enum struct E4 : unsigned { E4Zero, E4One, E4Two = sizeof(std::underlying_type<E4>::type) };
enum struct E5            { E5Zero, E5One, E5Two = sizeof(std::underlying_type<E5>::type) };
enum class E6 : unsigned  { E6Zero, E6One, E6Two = sizeof(std::underlying_type<E6>::type) };

@rsmith ?

How many of these should fail?

Turns out that only the first one should fail - and that's the one that clang rejects.

Some test cleanup.; add notes to the failing test to say why the other cases don't fail.

How many of these should fail?

Turns out that only the first one should fail - and that's the one that clang rejects.

That's right. A couple more testcases to exercise the corners here:

enum E7 : std::underlying_type_t<E7> {};
enum class E8 : std::underlying_type_t<E8> {};

(Clang gets the point of declaration for enums wrong at the moment and thinks that E7 and E8 are not in scope in the enum-base. But those two should be rejected either way.)

libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/underlying_type.fail.cpp
20

Given that conformance requires a diagnostic here ("Mandates:"), that'd seem like a good thing to test to me.

mclow.lists marked an inline comment as not done.

Update based on Richard's comments.

mclow.lists marked 2 inline comments as done.Jun 20 2019, 10:44 AM
EricWF requested changes to this revision.Jun 20 2019, 2:40 PM
EricWF added inline comments.
libcxx/include/type_traits
4729

This changes the mangling of underlying_type, and potentially it's usage as a "template template".
The specialization trick should be done in a impl base class.

This revision now requires changes to proceed.Jun 20 2019, 2:40 PM

Use an 'impl' class to prevent a name mangling change.

mclow.lists marked an inline comment as done.Jun 20 2019, 5:44 PM
EricWF accepted this revision.Jun 21 2019, 9:25 AM
This revision is now accepted and ready to land.Jun 21 2019, 9:25 AM
mclow.lists closed this revision.Jun 21 2019, 11:54 AM

Committed as revision 364094