enum State {Idle, Fidget, Walk, Scan, Attack}; enum Direction {North, South, East, West};
State: Fidget
β is displayed in the console instead of β State: 1
β. Also, it is often necessary to serialize enums into JSON, YAML or another format, moreover in the form of string values. Besides the fact that strings are easier to perceive than numbers, their use in the serialization format increases the resistance to changes in the numerical values ββof enumeration constants. Ideally, "Fidget"
should reference the Fidget
, even if a new constant is declared, and Fidget
has a value other than 1. BETTER_ENUM(State, int, Idle, Fidget, Walk, Scan, Attack) BETTER_ENUM(Direction, int, North, South, East, West)
State state = State::Fidget; state._to_string(); // "Fidget" std::cout << "state: " << state; // "state: Fidget" state = State::_from_string("Scan"); // State::Scan (3) // switch, . switch (state) { case State::Idle: // ... break; // ... }
for (Direction direction : Direction._values()) character.try_moving_in_direction(direction);
BETTER_ENUM(Flags, char, Allocated = 1, InUse = 2, Visited = 4, Unreachable = 8) Flags::_size(); // 4
constexpr
functions. You can, for example, write a constexpr
function that will calculate the maximum value of an enumeration and make it available at compile time. Even if the values ββof the constants are chosen arbitrarily and are not declared in ascending order.enum.h
to the project folder. Try it, maybe it will help you in solving your problems. BETTER_ENUM(Direction, int, North = 1, South = 2, East = 4, West = 8)
struct Direction { enum _Enum : int {North = 1, South = 2, East = 4, West = 8}; static const int _values[] = {1, 2, 4, 8}; static const char * const _names[] = {"North", "South", "East", "West"}; int _value; // ..., ... };
_values
or _names
and return its corresponding value or string to another array._values
generated by referring to the constants of the internal enumeration _Enum
. This part of the macro looks like this: static const int _values[] = {__VA_ARGS__};
static const int _values[] = {North = 1, South = 2, East = 4, West = 8};
template <typename T> struct _eat { T _value; template <typename Any> _eat& operator =(Any value) { return *this; } // . explicit _eat(T value) : _value(value) { } // T. operator T() const { return _value; } // T. }
static const int _values[] = {(_eat<_Enum>)North = 1, (_eat<_Enum>)South = 2, (_eat<_Enum>)East = 4, (_eat<_Enum>)West = 8};
#
) - the preprocessor operator for string translation. It converts __VA_ARGS__
into something like this: static const char * const _names[] = {"North = 1", "South = 2", "East = 4", "West = 8"};
_names
in the _names
array _names
it perceives the characters of spaces and equality as additional line boundaries. So when searching for β North = 1
β, Better Enums will only find β North
β.constexpr
functions working with static
constexpr
, due to the constexpr
of different compilers. Also, certain difficulties may be associated with the decomposition of as much of the macro as possible into templates in order to speed up compilation (templates do not need to be reparsed during creation, but macro extensions are needed).Source: https://habr.com/ru/post/277757/
All Articles