## C++17 reflection proposal *You can try this demo [live online][live].* Better Enums can be used to implement the enums portion of the [$cxx17 reflection proposal N4428][n4428] in $cxx11. N4428 proposes the following traits interface: ~~~comment namespace std { template struct enum_traits { struct enumerators { constexpr static size_t size; template struct get { constexpr string_literal identifier; constexpr static E value; }; }; }; } ~~~ So, the basic usage would be: ~~~comment enum class Foo {A, B, C}; constexpr size_t size = std::enum_traits::enumerators::size; constexpr Foo value_0 = std::enum_traits::enumerators::get<0>::value; constexpr string_literal name_1 = std::enum_traits::enumerators::get<1>::identifier; ~~~ Resulting in the values `3`, `Foo::A`, and `"B"`, respectively. --- The interface is implemented in the optional header file [`extra/better-enums/n4428.h`][header]. There are two necessary differences. 1. The interface is only available for enums declared through the `BETTER_ENUM` macro. This is because the macro is what generates the information necessary for reflection. ### Demo So, with that out of the way, we can do a little test. Let's assume that `extra/` has been added as a directory to search for include files. #ifndef BETTER_ENUMS_CONSTEXPR_TO_STRING #define BETTER_ENUMS_CONSTEXPR_TO_STRING #endif #include #include <enum.h> #include <better-enums/n4428.h> --- Let's declare an enum: BETTER_ENUM(Channel, char, Red = 1, Green, Blue) ...and try N4428: constexpr std::size_t size = std::enum_traits<Channel>::enumerators::size; constexpr Channel value_0 = std::enum_traits<Channel>::enumerators::get<0>::value; constexpr Channel value_1 = std::enum_traits<Channel>::enumerators::get<1>::value; constexpr const char *identifier_2 = std::enum_traits<Channel>::enumerators::get<2>::identifier; ...and check the results: static_assert(size == 3, ""); static_assert(value_0 == +Channel::Red, ""); static_assert(value_1 == +Channel::Green, ""); int main() { std::cout << identifier_2 << std::endl; return 0; } That prints `Blue`, as you would expect. ### Quirk The reason for the `#define` in the code above is that there is one quirk: the interface above is available only for Better Enums for which [compile-time name trimming][slow-enum] is enabled — those declared when `BETTER_ENUMS_CONSTEXPR_TO_STRING` was defined, or declared with the `SLOW_ENUM` variant of `BETTER_ENUM`. As mentioned on the linked page, the reason compile-time name trimming is not the default is that, while still pretty fast, it is four times slower than program-startup-time name trimming. The latter is the default. Despite the above, a variation on the interface is available for enums without compile-time name trimming: ~~~comment namespace std { template struct enum_traits { struct enumerators { constexpr static size_t size; template struct get { constexpr const char *identifier; constexpr static E value; }; // For enums without compile-time name trimming. template struct get_alt { static const char* identifier(); constexpr static E value; }; }; }; } ~~~ As you can see, the difference is that `identifier` is a non-`constexpr` function, and you have to access it through `get_alt`. ~~~comment // Without compile-time name trimming. BETTER_ENUM(Depth, int, HighColor, TrueColor) int main() { std::cout << std::enum_traits::enumerators::get_alt<1>::identifier() << std::endl; return 0; } ~~~ ### The future N4428 is the fourth in a series of revisions: [N3815][n3815], [N4027][n4027], [N4113][n4113], N4428. If there are more revisions that change the proposal for enums, I will try to implement those as well. [n4428]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4428.pdf [n4113]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4113.pdf [n4027]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4027.pdf [n3815]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3815.html [slow-enum]: ${prefix}OptInFeatures.html#CompileTimeNameTrimming [header]: https://github.com/aantron/better-enums/blob/$ref/extra/better-enums/n4428.h [live]: http://melpon.org/wandbox/permlink/QelcwZNLi4gIx8Ux %% description = Approximate implementation of N4428 enum reflection based on Better Enums.