You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
5.9 KiB
C++
163 lines
5.9 KiB
C++
// File name: "EnumToString.h"
|
|
#undef DECL_ENUM_ELEMENT
|
|
#undef BEGIN_ENUM
|
|
#undef END_ENUM
|
|
|
|
#include <vector>
|
|
#include <map>
|
|
#if (defined _WINDOWS) || (defined WIN32)
|
|
#include <string.h>
|
|
#define NAME_CMP_FUNC _stricmp
|
|
#else
|
|
#define NAME_CMP_FUNC strcasecmp
|
|
#endif
|
|
|
|
#include "CyclopsCommon.h"
|
|
#include <typeinfo>
|
|
|
|
#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<const char*>* 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<NameEnum>(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<const char*> gsNameMap##ENUM_NAME## =
|
|
#define END_ENUM( ENUM_NAME ) ; bool ret##ENUM_NAME## = addEnumName(typeid(ENUM_NAME).hash_code(), &gsNameMap##ENUM_NAME##);
|
|
|
|
static std::map<size_t, const std::vector<const char*>* > gsNameMap;
|
|
|
|
bool addEnumName(size_t enumHash, const std::vector<const char*>* 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<const char*>* 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<const char*>* 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<const char*>* 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<NameEnum>(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<NameEnumValueElement> gsNameMap##ENUM_NAME## =
|
|
#define END_ENUM2( ENUM_NAME ) ; bool ret##ENUM_NAME## = addEnumName2(typeid(ENUM_NAME).hash_code(), &gsNameMap##ENUM_NAME##);
|
|
|
|
static std::map<size_t, const std::vector<NameEnumValueElement>* > gsNameMap2;
|
|
|
|
bool addEnumName2(size_t enumHash, const std::vector<NameEnumValueElement>* 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<NameEnumValueElement>* 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<NameEnumValueElement>* 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
|
|
|