This library provides the following macros to create standard enums and enum classes with stringified enumerators
MAKE_NAMED_ENUM(enum_name,...)
creates a standard enum "enum_name" with named enumerators "..."MAKE_NAMED_ENUM_CLASS(enum_name,...)
creates a C++11 enum class "enum_name" with named enumerators "..."MAKE_NAMED_ENUM_WITH_TYPE(enum_name,enum_type,...)
creates a standard enum "enum_name" with named enumerators "..." and underlying type "enum_type"MAKE_NAMED_ENUM_CLASS_WITH_TYPE(enum_name,enum_type,...)
creates a C++11 enum class "enum_name" with named enumerators "..." and underlying type "enum_type"
#include "named_enum.hpp"
#include <iostream>
MAKE_NAMED_ENUM_CLASS(FirstThree, One, Two, Three);
int main( int argc, char **argv ){
for ( const auto & name : named_enum::names<FirstThree>() )
{
std::cout << name << "\n";
}
}
Output:
One
Two
Three
- Single header library
- The number of enumerators, i.e. the size, is available
- All enumerator names are available as std::array of const char *
- The current name is available as const char *
- All names are generated at compile time
- The macro does not support custom values for the enumerators
When an enum E
is created with any of the four macros, the specialized versions of the functions
below are created.
template<typename E>
constexpr auto size -> unsigned int ( );
template<typename E>
constexpr auto size -> unsigned int ( E const & ) {
return size<E>();
}
using string_t=const char *;
template<unsigned int N>
using string_array_t=std::array<string_t, N>;
template<typename E> constexpr
auto names( ) -> string_array_t<size<E>()> const &;
template<typename E> constexpr
auto names( E const & ) -> string_array_t<size<E>()> const & {
return names<E>( );
}
template<typename E> constexpr
auto name( E const & e ) -> string_t {
return names( e )[static_cast<unsigned int>(e)];
}
#include "named_enum.hpp"
#include <iostream>
MAKE_NAMED_ENUM_CLASS( Colors, GREEN, YELLOW, RED );
class TrafficLight {
public:
TrafficLight( Colors color ) :
color_( color ){
std::cout << "Initialized signal with: " << get_name( ) << std::endl;
}
void set_color( Colors color ){
color_ = color;
std::cout << "Set signal to: " << get_name( ) << std::endl;
}
Colors get_color( ) const{
return color_;
}
std::string get_name( ) const{
return named_enum::name( color_ );
}
private:
Colors color_;
};
int main( int argc, char **argv ){
TrafficLight signal( Colors::RED );
signal.set_color( Colors::YELLOW );
signal.set_color( Colors::GREEN );
auto current_color = signal.get_name( );
std::cout << "current_color: " << current_color << std::endl;
std::cout << "Available colors are:";
for ( const auto & color : named_enum::names<Colors>( ) ) {
std::cout << " " << color;
}
std::cout << std::endl;
}
Ouput:
Initialized signal with: RED
Set signal to: YELLOW
Set signal to: GREEN
current_color: GREEN
Available colors are: GREEN YELLOW RED
To create a map with a fixed number of named keys and constant time look up,
just combine a std::array
with the MAKED_NAMED_ENUM
macro, whose enumerators
automatically convert to integral types.
#include "../named_enum.hpp"
#include <array>
#include <iostream>
// Something healthy
MAKE_NAMED_ENUM( FRUIT, APPLE, ORANGE, BANANA, PLUM );
int main( int argc, char **argv )
{
static const size_t size=named_enum::size<FRUIT>( );
std::array<int, size> fruitMap;
fruitMap[FRUIT::APPLE] = 4;
fruitMap[FRUIT::ORANGE] = 1;
fruitMap[FRUIT::BANANA] = 3;
fruitMap[FRUIT::PLUM] = 2;
std::cout << "How much fruit is in the basket?" << std::endl;
for ( size_t i = 0; i < size; ++i )
{
auto names = named_enum::names<FRUIT>( );
std::cout << names[i] << " : " << fruitMap[i] << std::endl;
} // end of i -loop
}
Output:
How much fruit is in the basket?
APPLE : 4
ORANGE : 1
BANANA : 3
PLUM : 2