Skip to content

Instantly share code, notes, and snippets.

@xentec
Last active October 4, 2017 07:02
Show Gist options
  • Save xentec/e9a50c38ce4ced0f82ef8f36c04b248a to your computer and use it in GitHub Desktop.
Save xentec/e9a50c38ce4ced0f82ef8f36c04b248a to your computer and use it in GitHub Desktop.
#pragma once
#include <optional>
#include <map>
/*
#define <GENERATOR>(XX) \
XX(OK, 0) \
XX(ERROR, 1) \
XX(..., ...) \
*/
#define ENUM_ITEM_ASSIGN(name, def) name = def,
#define ENUM_CLASS(GENETAOR, TYPE) \
enum class TYPE \
{ \
GENETAOR(ENUM_ITEM_ASSIGN) \
}
#define ENUM_MAP_BASE \
template<class ENUM> inline std::optional<const char*> enum_as_str(ENUM val); \
template<class ENUM> inline std::optional<ENUM> enum_from_str(const char* str); \
#define ENUM_ITEM_STRING(name, ...) { _E::name, #name },
#define ENUM_MAP_AS_STRING(GENERATOR, TYPE) \
template<> inline std::optional<const char*> enum_as_str(TYPE val) \
{ \
using _E = TYPE; \
static const std::map<TYPE, const char*> map = \
{ \
GENERATOR(ENUM_ITEM_STRING) \
}; \
std::optional<const char*> str; \
auto itr = map.find(val); \
if(itr != map.end()) \
str.emplace(itr->second); \
return str; \
}
#define ENUM_ITEM_UNSTRING(name, ...) { #name, _E::name },
#define ENUM_MAP_FROM_STRING(GENERATOR, TYPE) \
template<class ENUM> inline std::optional<ENUM> enum_from_str(const char* str) \
{ \
using _E = TYPE; \
static const std::map<const char*, TYPE> map = \
{ \
GENERATOR(ENUM_ITEM_UNSTRING) \
}; \
std::optional<TYPE> val; \
auto itr = map.find(str); \
if(itr != map.end()) \
val.emplace(itr->second); \
return val; \
}
#define ENUM_FROM_NUM_BASE \
template<class T> inline std::optional<T> enum_from_num(long val);
#define ENUM_ITEM_CASE(name, def) case def:
#define ENUM_FROM_NUM(GENERATOR, TYPE) \
template<> inline std::optional<TYPE> enum_from_num(long val) \
{ \
std::optional<TYPE> type; \
switch(val) \
{ \
GENERATOR(ENUM_ITEM_CASE) \
type.emplace(TYPE(val)); \
break; \
} \
return type; \
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment