diff --git a/Include/AuroraEnum.hpp b/Include/AuroraEnum.hpp index 3df70b7..8b3015e 100644 --- a/Include/AuroraEnum.hpp +++ b/Include/AuroraEnum.hpp @@ -11,7 +11,11 @@ /// Configuration /////////////////////////////////////////////////////////////////////////////////////////// -#if defined(AUE_OUT_OF_ECOSYSTEM) +#if defined(AUE_OUT_OF_ECOSYSTEM) && defined(__cplusplus) + + #if !defined(AU_LANG_CPP) + #define AU_LANG_CPP + #endif #if !defined(AUE_NOCPPSTL) #include @@ -65,6 +69,9 @@ /// @hideinitializer #define _AUE_EMIT_D(name, val) name::val, +/// @hideinitializer +#define _AUE_EMIT_E(name, val) val, + /// @hideinitializer #define _AUE_EMIT_PAIRNAME(name, val) {#val, name::val}, @@ -78,36 +85,58 @@ // API /////////////////////////////////////////////////////////////////////////////////////////// #define AUE_DEFINE_VA(name, ...) AUE_DEFINE(name, (__VA_ARGS__)) + +#if defined(AU_LANG_CPP) + #define AUE_DEFINE_DECL_LANG(name, vals) enum class name : AuUInt32 { AU_FOR_EACH(_AUE_EMIT_ARRAY, _AUE_STRIP_BRACKETS(vals)) kEnumCount, kEnumInvalid = (AuUInt32) -1, eEnumInvalid = (AuUInt32)-1, eEnumCount = kEnumCount }; + #define AUE_DEFINE_DECL_EXT(name, vals, ext) enum name : ext { AU_FOR_EACH(_AUE_EMIT_ARRAY, _AUE_STRIP_BRACKETS(vals)) kEnumCount, kEnumInvalid = (ext) -1, eEnumInvalid = (ext)-1, eEnumCount = kEnumCount }; -#define AUE_DEFINE(name, vals) enum class name { AU_FOR_EACH(_AUE_EMIT_ARRAY, _AUE_STRIP_BRACKETS(vals)) kEnumCount, kEnumInvalid = -1, eEnumInvalid = -1, eEnumCount = kEnumCount }; \ - static inline const AuString k ## name ## ToString[static_cast(name::kEnumCount)] = { AU_FOR_EACH(_AUE_EMIT_A, _AUE_STRIP_BRACKETS(vals)) }; \ - static inline const name k ## name ## Values[static_cast(name::kEnumCount)] = { AU_FOR_EACH_THAT(_AUE_EMIT_D, name, _AUE_STRIP_BRACKETS(vals)) }; \ - inline const AuHashMap k ## name ## FromString = { AU_FOR_EACH_THAT(_AUE_EMIT_PAIRNAME, name, _AUE_STRIP_BRACKETS(vals)) {"kEnumCount", name::kEnumCount} }; \ - static inline name name ## FromString (const AuString &codename) { AU_FOR_EACH_THAT(_AUE_EMIT_CHECK, name, _AUE_STRIP_BRACKETS(vals)) return name::kEnumCount; } \ - static inline name name ## FromHashString(const AuString &codename) { auto itr = k ## name ## FromString.find(codename); if (itr == k ## name ## FromString.end()) return name::kEnumCount; return itr->second; } \ - static inline const AuString & name ## ToString(name val) { static const AuString invalid = "kEnumCount"; if (static_cast(val) >= static_cast(name::kEnumCount)) return invalid; return k ## name ## ToString[static_cast(val)]; } \ - static inline bool name ## IsValid(name val) { return static_cast(val) < static_cast(name::kEnumCount); } \ - static inline void name ## ForEach(const AuConsumer &consumer) { AU_FOR_EACH_THAT(_AUE_EMIT_CALL, name, _AUE_STRIP_BRACKETS(vals)) } \ - static const AuUInt k ## name ## Count = static_cast(name::kEnumCount); \ - static const name k ## name ## Invalid = name::kEnumCount; \ - static const name k ## name ## MaxLegal = static_cast(k ## name ## Count - 1); \ - static const name k ## name ## MinLegal = static_cast(0); +#else + #define AUE_DEFINE_DECL_LANG(name, vals) enum name : uint32_ct { AU_FOR_EACH(_AUE_EMIT_ARRAY, _AUE_STRIP_BRACKETS(vals)) k ## name ## EnumCount, k ## name ## EnumInvalid = (uint32_ct) -1, e ## name ## EnumInvalid = (uint32_ct)-1, e ## name ## EnumCount = k ## name ## EnumCount }; + #define AUE_DEFINE_DECL_EXT(name, vals, ext) enum name : ext { AU_FOR_EACH(_AUE_EMIT_ARRAY, _AUE_STRIP_BRACKETS(vals)) k ## name ## EnumCount, k ## name ## EnumInvalid = (ext) -1, e ## name ## EnumInvalid = (ext)-1, e ## name ## EnumCount = k ## name ## EnumCount }; -#define AUE_ITERATE(name, index) name index = static_cast(0); static_cast(index) < static_cast(name::kEnumCount); index = static_cast(static_cast(index) + 1) - -/////////////////////////////////////////////////////////////////////////////////////////// -// Limited support for when there is no STL or STL-like library available -/////////////////////////////////////////////////////////////////////////////////////////// +#endif #if defined(AUE_NOCPPSTL) - #undef AUE_DEFINE - #define AUE_DEFINE(name, vals) enum class name { AU_FOR_EACH(_AUE_EMIT_ARRAY, _AUE_STRIP_BRACKETS(vals)) kEnumCount, kEnumInvalid = -1, eEnumInvalid = -1, eEnumCount = kEnumCount }; \ - static inline const char * k ## name ## ToString[static_cast(name::kEnumCount)] = { AU_FOR_EACH(_AUE_EMIT_A, _AUE_STRIP_BRACKETS(vals)) }; \ - static inline const name k ## name ## Values[static_cast(name::kEnumCount)] = { AU_FOR_EACH_THAT(_AUE_EMIT_D, name, _AUE_STRIP_BRACKETS(vals)) }; \ - static inline const char * name ## ToString(name val) { static const char * invalid = "kEnumCount"; if (static_cast(val) >= static_cast(name::kEnumCount)) return invalid; return k ## name ## ToString[static_cast(val)]; } \ - static inline bool name ## IsValid(name val) { return static_cast(val) < static_cast(name::kEnumCount); } \ - static const AuUInt k ## name ## Count = static_cast(name::kEnumCount); \ - static const name k ## name ## Invalid = name::kEnumCount; \ - static const name k ## name ## MaxLegal = static_cast(k ## name ## Count - 1); \ - static const name k ## name ## MinLegal = static_cast(0); -#endif \ No newline at end of file + #define AUE_DEFINE_BODY(name, vals) \ + inline const char * k ## name ## ToString[static_cast(name::kEnumCount)] = { AU_FOR_EACH(_AUE_EMIT_A, _AUE_STRIP_BRACKETS(vals)) }; \ + inline const name k ## name ## Values[static_cast(name::kEnumCount)] = { AU_FOR_EACH_THAT(_AUE_EMIT_D, name, _AUE_STRIP_BRACKETS(vals)) }; \ + inline const char * name ## ToString(name val) { static const char * invalid = "kEnumCount"; if (static_cast(val) >= static_cast(name::kEnumCount)) return invalid; return k ## name ## ToString[static_cast(val)]; } \ + inline bool name ## IsValid(name val) { return static_cast(val) < static_cast(name::kEnumCount); } \ + static const AuUInt k ## name ## Count = static_cast(name::kEnumCount); \ + static const name k ## name ## Invalid = name::kEnumCount; \ + static const name k ## name ## MaxLegal = static_cast(k ## name ## Count - 1); \ + static const name k ## name ## MinLegal = static_cast(0); + +#elif defined(AU_LANG_CPP) + #define AUE_DEFINE_BODY(name, vals) \ + inline const AuString k ## name ## ToString[static_cast(name::kEnumCount)] = {AU_FOR_EACH(_AUE_EMIT_A, _AUE_STRIP_BRACKETS(vals))}; \ + inline const name k ## name ## Values[static_cast(name::kEnumCount)] = {AU_FOR_EACH_THAT(_AUE_EMIT_D, name, _AUE_STRIP_BRACKETS(vals))}; \ + inline const AuHashMap k ## name ## FromString = {AU_FOR_EACH_THAT(_AUE_EMIT_PAIRNAME, name, _AUE_STRIP_BRACKETS(vals)) { "kEnumCount", name::kEnumCount }}; \ + inline name name ## FromString(const AuString & codename) { AU_FOR_EACH_THAT(_AUE_EMIT_CHECK, name, _AUE_STRIP_BRACKETS(vals)) return name::kEnumCount; } \ + inline name name ## FromHashString(const AuString & codename) { auto itr = k ## name ## FromString.find(codename); if (itr == k ## name ## FromString.end()) return name::kEnumCount; return itr->second; } \ + inline const AuString &name ## ToString(name val) { static const AuString invalid = "kEnumCount"; if (static_cast(val) >= static_cast(name::kEnumCount)) return invalid; return k ## name ## ToString[static_cast(val)]; } \ + inline bool name ## IsValid(name val) { return static_cast(val) < static_cast(name::kEnumCount); } \ + inline void name ## ForEach(const AuConsumer &consumer) { AU_FOR_EACH_THAT(_AUE_EMIT_CALL, name, _AUE_STRIP_BRACKETS(vals)) } \ + static const AuUInt k ## name ## Count = static_cast(name::kEnumCount); \ + static const name k ## name ## Invalid = name::kEnumCount; \ + static const name k ## name ## MaxLegal = static_cast(k ## name ## Count - 1); \ + static const name k ## name ## MinLegal = static_cast(0); + +#elif defined(AU_LANG_C) + #define AUE_DEFINE_BODY(name, vals) \ + static const char * k ## name ## ToString[(size_ct)(k ## name ## EnumCount)] = { AU_FOR_EACH(_AUE_EMIT_A, _AUE_STRIP_BRACKETS(vals)) }; \ + static const name k ## name ## Values[(size_ct)(k ## name ## EnumCount)] = { AU_FOR_EACH_THAT(_AUE_EMIT_E, name, _AUE_STRIP_BRACKETS(vals)) }; \ + static const char * name ## ToString(name val) { static const char * invalid = "kEnumCount"; if ((size_ct)(val) >= (size_ct)(k ## name ## EnumCount)) return invalid; return k ## name ## ToString[(size_ct)(val)]; } \ + static bool name ## IsValid(name val) { return (size_ct)(val) < (size_ct)(k ## name ## EnumCount); } \ + static const size_ct k ## name ## Count = (size_ct)(k ## name ## EnumCount); \ + static const name k ## name ## Invalid = k ## name ## EnumCount; \ + static const name k ## name ## MaxLegal = (name)(k ## name ## Count - 1); \ + static const name k ## name ## MinLegal = (name)(0); + +#endif + +#define AUE_DEFINE(name, vals) AUE_DEFINE_DECL_LANG(name, vals) AUE_DEFINE_BODY(name, vals) + +#define AUE_DEFINE_EXT(name, vals, ext) AUE_DEFINE_DECL_EXT(name, vals, ext) AUE_DEFINE_BODY(name, vals) + +#define AUE_ITERATE(name, index) name index = static_cast(0); static_cast(index) < static_cast(name::kEnumCount); index = static_cast(static_cast(index) + 1) \ No newline at end of file