73 #define ENUM(Base, Class) \
74 class Class : public EnumElem \
79 ENUM_ELEM_CALL(ENUM_E_ENUM, Base, Class) \
82 static const int valMax = __VALMAX; \
86 Class(const Enum val) { operator=(val); } \
88 explicit Class(const int val) { operator=(static_cast<Enum>(enumInfo().elem(val).val)); } \
90 explicit Class(const Id& val) { operator=(static_cast<Enum>(enumInfo().elem(val).val)); } \
93 Class& operator=(const Enum rhs) { _val = rhs; return *this; } \
96 bool operator==(const Class& rhs) const { return val() == rhs.val(); } \
97 bool operator!=(const Class& rhs) const { return val() != rhs.val(); } \
98 bool operator< (const Class& rhs) const { return val() < rhs.val(); } \
99 bool operator> (const Class& rhs) const { return val() > rhs.val(); } \
100 bool operator<=(const Class& rhs) const { return val() <= rhs.val(); } \
101 bool operator>=(const Class& rhs) const { return val() >= rhs.val(); } \
103 bool operator==(const Enum rhs) const { return val() == rhs; } \
104 bool operator!=(const Enum rhs) const { return val() != rhs; } \
105 bool operator< (const Enum rhs) const { return val() < rhs; } \
106 bool operator> (const Enum rhs) const { return val() > rhs; } \
107 bool operator<=(const Enum rhs) const { return val() <= rhs; } \
108 bool operator>=(const Enum rhs) const { return val() >= rhs; } \
112 bool operator==(int) const { return false; } \
113 bool operator!=(int) const { return false; } \
114 bool operator< (int) const { return false; } \
115 bool operator> (int) const { return false; } \
116 bool operator<=(int) const { return false; } \
117 bool operator>=(int) const { return false; } \
118 template<class T> struct DisableCmp : mt::Value<bool, std::is_convertible<T,int>::value && !std::is_same<T,Enum>::value> {}; \
119 template<class T> friend typename std::enable_if<DisableCmp<T>::value, bool>::type operator==(const T&, const Class&) { static_assert(!mt::True<T>::value, "Enum compare type mismatch"); } \
120 template<class T> friend typename std::enable_if<DisableCmp<T>::value, bool>::type operator!=(const T&, const Class&) { static_assert(!mt::True<T>::value, "Enum compare type mismatch"); } \
121 template<class T> friend typename std::enable_if<DisableCmp<T>::value, bool>::type operator<=(const T&, const Class&) { static_assert(!mt::True<T>::value, "Enum compare type mismatch"); } \
122 template<class T> friend typename std::enable_if<DisableCmp<T>::value, bool>::type operator>=(const T&, const Class&) { static_assert(!mt::True<T>::value, "Enum compare type mismatch"); } \
123 template<class T> friend typename std::enable_if<DisableCmp<T>::value, bool>::type operator< (const T&, const Class&) { static_assert(!mt::True<T>::value, "Enum compare type mismatch"); } \
124 template<class T> friend typename std::enable_if<DisableCmp<T>::value, bool>::type operator> (const T&, const Class&) { static_assert(!mt::True<T>::value, "Enum compare type mismatch"); } \
128 const NameId& classId() const { return enumInfo().elem(val()).classId; } \
130 const NameId& id() const { return enumInfo().elem(val()).id; } \
132 friend ostream& operator<<(ostream& os, const Class& val) { return os << val.classId() << "::" << val.id(); } \
135 class EnumInfo : public EnumInfo_<Class> \
137 friend class Class; \
139 EnumInfo() { ENUM_ELEM_CALL(ENUM_E_CTOR, Base, Class) this->setup(); } \
142 static const EnumInfo& enumInfo() { static const EnumInfo info; return info; } \
147 #define ENUM_ELEM_CALL(EFunc, Base, Class) ENUM_LIST(EFunc, STRINGIFY(IFEMPTY(, UNBRACKET(Base)::, Base)Class))
149 #define ENUM_E_ENUM(...) EVAL(TOKCAT(ENUM_E_ENUM_, NUMARGS(__VA_ARGS__))(__VA_ARGS__))
150 #define ENUM_E_ENUM_2(ClassName, name) name,
151 #define ENUM_E_ENUM_4(ClassName, name, str, val) name IFEMPTY(,= UNBRACKET(val),val),
153 #define ENUM_E_CTOR(...) EVAL(TOKCAT(ENUM_E_CTOR_, NUMARGS(__VA_ARGS__))(__VA_ARGS__))
154 #define ENUM_E_CTOR_2(ClassName, name) ENUM_E_CTOR_4(ClassName, name, EMPTY, EMPTY)
155 #define ENUM_E_CTOR_4(ClassName, name, str, val) this->addElem(ClassName, IFEMPTY(#name, str, str), name);
174 operator int()
const {
return _val; }
185 template<
class EnumType>
190 typedef unordered_map<Id, int> IdElemMap;
191 typedef unordered_map<int, int> ValElemMap;
192 typedef vector<int> ValElemTable;
198 classId(className),
id(name), val(val) {}
208 const ElemList&
elemList()
const {
return _elemList; }
213 IdElemMap::const_iterator it = _idElemMap.find(
id);
214 if (it != _idElemMap.end())
return _elemList[it->second];
222 if (_valElemTable.size() > 0)
224 int index = val - _valMin;
225 if (index >= 0 && index < (
int)_valElemTable.size() && _valElemTable[index] != -1)
return _elemList[_valElemTable[index]];
230 ValElemMap::const_iterator it = _valElemMap.find(val);
231 if (it != _valElemMap.end())
return _elemList[it->second];
241 _elemList.push_back(
Elem(className, name, val));
242 _idElemMap[_elemList.back().id] = (int)_elemList.size()-1;
245 if (_elemList.size() == 1)
252 if (val < _valMin) _valMin = val;
253 if (val > _valMax) _valMax = val;
260 int range = _valMax - _valMin;
261 if (range <= _tableRangeMax)
263 _valElemTable.resize(range + 1, -1);
264 for (
int i = 0; i < (int)_elemList.size(); ++i)
265 _valElemTable[_elemList[i].val - _valMin] = i;
270 for (
int i = 0; i < (int)_elemList.size(); ++i)
271 _valElemMap[_elemList[i].val] = i;
277 IdElemMap _idElemMap;
278 ValElemMap _valElemMap;
280 static const int _tableRangeMax = 100;
281 ValElemTable _valElemTable;
const ElemList & elemList() const
Get all elements.
Definition: Enum.h:208
int val() const
Get integral value.
Definition: Enum.h:172
NameId classId
Definition: Enum.h:200
int val
Definition: Enum.h:202
Holds both a name string and its hashed value, and unlike Id the name is never compiled out...
Definition: Id.h:144
EnumInfo_()
Definition: Enum.h:237
void setup()
Definition: Enum.h:257
std::enable_if< mt::isIterator< Iter1 >::value, Range_< Iter1, Iter2 > >::type range(Iter1 &&first, Iter2 &&last)
Range from iterators [first, last)
Definition: Range.h:116
int _val
Definition: Enum.h:177
Elem(const String &className, const String &name, int val)
Definition: Enum.h:197
#define EXCEPTION(Class)
Declares methods required for every subclass of honey::Exception.
Definition: Exception.h:17
Run-time info about an enum class. Contains a list of elements and maps for element lookups...
Definition: Enum.h:186
void addElem(const String &className, const String &name, int val)
Definition: Enum.h:239
Unicode UTF-16 string class, wrapper around std::u16string.
Definition: String.h:23
vector< Elem > ElemList
Definition: Enum.h:205
const Elem & elem(int val) const
Get element by value, throws EnumError if not found.
Definition: Enum.h:219
Base exception class. Exceptions inherited from this class provide debug info and can be thrown polym...
Definition: Exception.h:45
#define throw_
Use in place of throw keyword to throw a honey::Exception object polymorphically and provide debug in...
Definition: Exception.h:11
EnumElem()
Definition: Enum.h:168
NameId id
Definition: Enum.h:201
Base class of all generated enum classes. A single element in the enumeration. See Enumeration Classe...
Definition: Enum.h:165
const Elem & elem(const Id &id) const
Get element by id, throws EnumError if not found.
Definition: Enum.h:211
Holds a name string and its hashed value for fast comparison ops. See String Identifier.
Definition: Id.h:25
Global Honeycomb namespace.
EnumElem(int val)
Definition: Enum.h:169