// File name: "EnumToString.h" #undef DECL_ENUM_ELEMENT #undef BEGIN_ENUM #undef END_ENUM #include #include #if (defined _WINDOWS) || (defined WIN32) #include #define NAME_CMP_FUNC _stricmp #else #define NAME_CMP_FUNC strcasecmp #endif #include "CyclopsCommon.h" #include #ifndef GENERATE_ENUM_STRINGS CYCLOPS_DLLSPEC const char* getEnumName(size_t enumHash, int value); CYCLOPS_DLLSPEC int fromEnumName(size_t enumHash, const char* name); bool addEnumName(size_t enumHash, const std::vector* pNameMap); #define DECL_ENUM_ELEMENT( element ) element #define BEGIN_ENUM( ENUM_NAME ) struct ENUM_NAME {\ enum NameEnum #define END_ENUM( ENUM_NAME ) ;\ int value;\ ENUM_NAME () : value(-1) {}\ ENUM_NAME (int _value) : value(_value) {}\ ENUM_NAME (NameEnum _value) : value(_value) {}\ static inline const char* GetEnumName() { return #ENUM_NAME; }\ static inline const char* GetName(ENUM_NAME _value) { return getEnumName(typeid(ENUM_NAME).hash_code(), _value.value); }\ static inline ENUM_NAME FromName(const char* n) {\ return ENUM_NAME(static_cast(fromEnumName(typeid(ENUM_NAME).hash_code(), n)));\ }\ bool equal(int _value) const { return value == _value; }\ bool operator >= (const NameEnum& other) const { return value >= other; }\ bool operator <= (const NameEnum& other) const { return value <= other; }\ bool operator == (const NameEnum& other) const { return value == other; }\ operator int() const { return value; }\ }; #else #define DECL_ENUM_ELEMENT( element ) #element #define BEGIN_ENUM( ENUM_NAME ) const std::vector gsNameMap##ENUM_NAME## = #define END_ENUM( ENUM_NAME ) ; bool ret##ENUM_NAME## = addEnumName(typeid(ENUM_NAME).hash_code(), &gsNameMap##ENUM_NAME##); static std::map* > gsNameMap; bool addEnumName(size_t enumHash, const std::vector* pNameMap) { gsNameMap[enumHash] = pNameMap; return true; } const char* getEnumName(size_t enumHash, int value) { auto it = gsNameMap.find(enumHash); if (it == gsNameMap.end()) return ""; const std::vector* pNameMap = it->second; if (!pNameMap || value < 0 || value >= pNameMap->size()) return ""; return pNameMap->at(value); } int fromEnumName(size_t enumHash, const char* name) { auto it = gsNameMap.find(enumHash); if (it == gsNameMap.end()) return 0; const std::vector* pNameMap = it->second; if (!pNameMap) return 0; for (size_t i = 0; i < pNameMap->size(); ++i) { if (NAME_CMP_FUNC(name, pNameMap->at(i)) == 0) return i; } return 0; } #endif #undef DECL_ENUM_ELEMENT2 #undef DECL_ENUM_ELEMENT2_S #undef BEGIN_ENUM2 #undef END_ENUM2 #ifndef GENERATE_ENUM_STRINGS struct NameEnumValueElement { int value; const char* name; const char* prettyName; NameEnumValueElement(int v, const char* n, const char* pn = nullptr) : value(v), name(n), prettyName(pn) {} }; CYCLOPS_DLLSPEC const char* getEnumName2(size_t enumHash, int value, bool pretty); CYCLOPS_DLLSPEC int fromEnumName2(size_t enumHash, const char* name); bool addEnumName2(size_t enumHash, const std::vector* pNameMap); #define DECL_ENUM_ELEMENT2( element, value, prettyName ) element = value #define DECL_ENUM_ELEMENT2_S( element, value ) element = value #define BEGIN_ENUM2( ENUM_NAME ) struct ENUM_NAME {\ enum NameEnum #define END_ENUM2( ENUM_NAME ) ;\ int value;\ ENUM_NAME () : value(-1) {}\ ENUM_NAME (int _value) : value(_value) {}\ ENUM_NAME (NameEnum _value) : value(_value) {}\ static inline const char* GetEnumName() { return #ENUM_NAME; }\ static inline const char* GetName(ENUM_NAME _value) {\ return getEnumName2(typeid(ENUM_NAME).hash_code(), _value.value, false);\ }\ static inline const char* GetPrettyName(ENUM_NAME _value){\ return getEnumName2(typeid(ENUM_NAME).hash_code(), _value.value, true);\ }\ static inline ENUM_NAME FromName(const char* n) {\ return ENUM_NAME (static_cast(fromEnumName2(typeid(ENUM_NAME).hash_code(), n)));\ }\ bool equal(int _value) const { return value == _value; }\ bool test(int _value) const { return (value & _value) != 0; }\ bool operator >= (const NameEnum& other) const { return value >= other; }\ bool operator <= (const NameEnum& other) const { return value <= other; }\ bool operator == (const NameEnum& other) const { return value == other; }\ bool operator += (const ENUM_NAME& other) { return value |= other.value; }\ operator int() const { return value; }\ }; #else #define DECL_ENUM_ELEMENT2( element, value, prettyName ) NameEnumValueElement(value, #element, prettyName) #define DECL_ENUM_ELEMENT2_S( element, value ) NameEnumValueElement(value, #element) #define BEGIN_ENUM2( ENUM_NAME ) const std::vector gsNameMap##ENUM_NAME## = #define END_ENUM2( ENUM_NAME ) ; bool ret##ENUM_NAME## = addEnumName2(typeid(ENUM_NAME).hash_code(), &gsNameMap##ENUM_NAME##); static std::map* > gsNameMap2; bool addEnumName2(size_t enumHash, const std::vector* pNameMap) { gsNameMap2[enumHash] = pNameMap; return true; } const char* getEnumName2(size_t enumHash, int value, bool pretty) { auto it = gsNameMap2.find(enumHash); if (it == gsNameMap2.end()) return ""; const std::vector* pNameMap = it->second; for (size_t i = 0; i < pNameMap->size(); i++) { const NameEnumValueElement& e = pNameMap->at(i); if (value == e.value) return pretty ? e.prettyName : e.name; } return ""; } int fromEnumName2(size_t enumHash, const char* name) { auto it = gsNameMap2.find(enumHash); if (it == gsNameMap2.end()) return 0; const std::vector* pNameMap = it->second; for (size_t i = 0; i < pNameMap->size(); i++) { const NameEnumValueElement& e = pNameMap->at(i); if (NAME_CMP_FUNC(name, e.name) == 0) return e.value; } return 0; } #endif