diff -r 568fcfc6da71 -r 39d7a9642eea src/generics/enums.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/generics/enums.h Sat Mar 24 11:57:24 2018 +0200 @@ -0,0 +1,71 @@ +#pragma once +#include + +template +struct EnumLimits {}; + +// +// Iterates an enum +// +template +struct EnumIterShell +{ + struct Iterator + { + Iterator(typename std::underlying_type::type i) : + i(i) {} + + Iterator& operator++() { ++i; return *this; } + bool operator==(Iterator other) { return i == other.i; } + bool operator!=(Iterator other) { return i != other.i; } + Enum operator*() const { return Enum(i); } + + typename std::underlying_type::type i; + }; + + Iterator begin() + { + return Iterator(EnumLimits::First); + }; + + Iterator end() + { + return Iterator(EnumLimits::Last + 1); + } +}; + +template +EnumIterShell iterateEnum() +{ + return EnumIterShell(); +} + +/* + * Casts an enum into its underlying type. + */ +template +typename std::underlying_type::type& enum_cast(T& enu) +{ + return *reinterpret_cast::type*>(&enu); +} + +/* + * Returns whether an enum value is within proper bounds. + */ +template +bool valueInEnum(Enum enumerator) +{ + auto index = enum_cast(enumerator); + return index >= EnumLimits::First and index <= EnumLimits::Last; +} + +#define MAKE_ITERABLE_ENUM(T) \ + template<> \ + struct EnumLimits \ + {\ + enum { First = 0, Last = static_cast(T::_End) - 1, Count = Last + 1 };\ + }; \ + inline T operator++ (T& a) { a = static_cast(enum_cast(a) + 1); return a; } \ + inline T operator-- (T& a) { a = static_cast(enum_cast(a) - 1); return a; } \ + inline T operator++ (T& a, int) { T result = a; a = static_cast(enum_cast(a) + 1); return result; } \ + inline T operator-- (T& a, int) { T result = a; a = static_cast(enum_cast(a) - 1); return result; }