Add easy to use macro to generate enum helper functions for parsing, stringifying and iteration.
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
52
src/Core/Enum.hpp
Normal file
52
src/Core/Enum.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include "Exceptions/NotReachableException.hpp"
|
||||
#include "MacroUtils.hpp"
|
||||
|
||||
#define ENUM_CASE(x, name) \
|
||||
case name::x: \
|
||||
return #x;
|
||||
#
|
||||
#define ENUM_PARSE_CASE(x, name) \
|
||||
case ConstHash(#x): \
|
||||
return name::x;
|
||||
#
|
||||
#define ENUM_PARSE_CASE_INSENSITIVE(x, name) \
|
||||
case ConstHashCI(#x): \
|
||||
return name::x;
|
||||
#
|
||||
#define ARRAY_NAME(x, name) name::x,
|
||||
|
||||
#define ENUM(name, type, values...) \
|
||||
enum class name : type { values }; \
|
||||
class name##Helper { \
|
||||
inline static uint32_t constexpr ConstHash(char const* input) { \
|
||||
return *input ? static_cast<uint32_t>(*input) + 33 * ConstHash(input + 1) : 5381; \
|
||||
} \
|
||||
inline static constexpr char charToLower(const char c) { \
|
||||
return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c; \
|
||||
} \
|
||||
inline static uint32_t constexpr ConstHashCI(char const* input) { \
|
||||
return charToLower(*input) ? static_cast<uint32_t>(charToLower(*input)) + 33 * ConstHashCI(input + 1) \
|
||||
: 5381; \
|
||||
} \
|
||||
\
|
||||
public: \
|
||||
static std::string ToString(name value) { \
|
||||
switch (value) { FOR_EACH(ENUM_CASE, name, values) } \
|
||||
throw NotReachableException(); \
|
||||
} \
|
||||
static name Parse(const std::string& input, bool caseInsensitive = false) { \
|
||||
if (caseInsensitive) \
|
||||
return ParseCaseInsensitive(input); \
|
||||
switch (ConstHash(input.c_str())) { FOR_EACH(ENUM_PARSE_CASE, name, values) } \
|
||||
throw CreatureException("String '" + input + "' could not be parsed as " #name); \
|
||||
} \
|
||||
static std::vector<name> GetValues() { return {FOR_EACH(ARRAY_NAME, name, values)}; } \
|
||||
\
|
||||
private: \
|
||||
static name ParseCaseInsensitive(const std::string& input) { \
|
||||
switch (ConstHashCI(input.c_str())) { FOR_EACH(ENUM_PARSE_CASE_INSENSITIVE, name, values) } \
|
||||
throw CreatureException("String '" + input + "' could not be parsed as " #name); \
|
||||
} \
|
||||
};
|
||||
Reference in New Issue
Block a user