This page is an advanced demo showing the kind of code you can write on top of Better Enums. It's a valid program — you can download it and try it out. The program runs as part of the automated test suite.
C++17 reflection
Better Enums can be used to approximately implement the enums portion of the C++17 reflection proposal N4428 in C++11. The implementation is approximate in the following senses:
- It only applies to Better Enums, not built-in enums.
enum_traits<E>::enumerators::get<I>::identifieris a non-constexprfunction rather than aconstexprvariable. I could make it aconstexprvariable as in the proposal, but that requires compile-time name trimming to be enabled for the Better Enum on whichgetis used. Since that's an opt-in feature, I can't guarantee it. I preferred not to write feature-detection code, in order to keep the implementation simple.- The return type of
identifierisconst char*instead of the proposedstd::string_literal, because I don't have an implementation of the latter available. I'm also ignoring the requirements on encoding, and just taking whatever the preprocessor provides.
With that out of the way, we can look at a simple example.
The implementation is defined in extra/better-enums/n4428.h. Let's
assume that extra/ has been added as a directory to search for include files.
#include <iostream> #include <enum.h> #include <better-enums/n4428.h>
Let's declare an enum:
ENUM(Channel, char, Red = 1, Green, Blue)
N4428 proposes three constexpr traits, of which we have two implemented
exactly — that is, as constexpr:
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;Let's check the results:
static_assert(size == 3, ""); static_assert(value_0 == +Channel::Red, ""); static_assert(value_1 == +Channel::Green, "");
Finally, we can try using identifier:
int main()
{
std::cout
<< std::enum_traits<Channel>::enumerators::get<2>::identifier()
<< std::endl;
return 0;
}That prints Blue, as you would expect.