Skip to content

Instantly share code, notes, and snippets.

@n00bmind
Last active February 23, 2021 11:09
Show Gist options
  • Save n00bmind/e46f754c520611a8eeabb45982946fb9 to your computer and use it in GitHub Desktop.
Save n00bmind/e46f754c520611a8eeabb45982946fb9 to your computer and use it in GitHub Desktop.
///// STRUCT ENUM /////
/* Usage:
struct V
{
char const* sVal;
int iVal;
};
#define VALUES(x) \
x(None, ("a", 100)) \
x(Animation, ("b", 200)) \
x(Landscape, ("c", 300)) \
x(Audio, ("d", 400)) \
x(Network, ("e", 500)) \
x(Scripting, ("f", 600)) \
// Values must go in () even if they're a single primitive type!
STRUCT_ENUM_WITH_VALUES(MemoryTag, V, VALUES)
#undef VALUES
int main()
{
// Can be used as normal
int index = MemoryTag::Audio;
// But also
MemoryTag const& t = MemoryTag::Values::Audio;
ASSERT( t.index == index );
V const& value = MemoryTag::Landscape.value;
for( int i = 0; i < MemoryTag::Values::count; ++i )
{
MemoryTag const& t = MemoryTag::Values::items[i];
std::cout << "sVal: " << t.value.sVal << "\tiVal: " << t.value.iVal << std::endl;
}
}
*/
#define _ENUM_ARGS(...) { __VA_ARGS__ }
#define _ENUM_ENTRY(x, ...) x,
#define _ENUM_NAME(x, ...) items[EnumName::x].name,
#define _ENUM_REF(x, ...) static constexpr EnumName const& x = items[EnumName::x];
#define _ENUM_ITEM(x) { #x, ValueType(), (i32)EnumName::x },
#define _ENUM_ITEM_WITH_NAMES(x, n) { n, ValueType(), (i32)EnumName::x },
#define _ENUM_ITEM_WITH_VALUES(x, v) { #x, _ENUM_ARGS v, (i32)EnumName::x },
#define _ENUM_ITEM_WITH_NAMES_VALUES(x, n, v) { n, _ENUM_ARGS v, (i32)EnumName::x },
#define _CREATE_ENUM(enumName, valueType, xValueList, xBuilder) \
struct enumName \
{ \
enum Enum : i32 \
{ \
xValueList(_ENUM_ENTRY) \
}; \
\
char const* name; \
valueType value; \
i32 index; \
\
bool operator ==( enumName const& other ) const \
{ return index == other.index; } \
bool operator !=( enumName const& other ) const \
{ return index != other.index; } \
\
/* Need to define this separately so the base type is fully defined */ \
struct Values; \
}; \
struct enumName::Values \
{ \
using EnumName = enumName; \
using ValueType = valueType; \
\
static constexpr enumName items[] = \
{ \
xValueList(xBuilder) \
}; \
static constexpr char const* const names[] = \
{ \
xValueList(_ENUM_NAME) \
}; \
static constexpr sz count = ARRAYCOUNT(items); \
\
xValueList(_ENUM_REF) \
}; \
#define STRUCT_ENUM(enumName, xValueList) _CREATE_ENUM(enumName, i32, xValueList, _ENUM_ITEM)
#define STRUCT_ENUM_WITH_NAMES(enumName, xValueList) _CREATE_ENUM(enumName, i32, xValueList, _ENUM_ITEM_WITH_NAMES)
#define STRUCT_ENUM_WITH_VALUES(enumName, valueType, xValueList) _CREATE_ENUM(enumName, valueType, xValueList, _ENUM_ITEM_WITH_VALUES)
#define STRUCT_ENUM_WITH_NAMES_VALUES(enumName, valueType, xValueList) _CREATE_ENUM(enumName, valueType, xValueList, _ENUM_ITEM_WITH_NAMES_VALUES)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment