src/generics/enums.h

changeset 1319
39d7a9642eea
child 1326
69a90bd2dba2
--- /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 <type_traits>
+
+template<typename T>
+struct EnumLimits {};
+
+//
+// Iterates an enum
+//
+template<typename Enum>
+struct EnumIterShell
+{
+	struct Iterator
+	{
+		Iterator(typename std::underlying_type<Enum>::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<Enum>::type i;
+	};
+
+	Iterator begin()
+	{
+		return Iterator(EnumLimits<Enum>::First);
+	};
+
+	Iterator end()
+	{
+		return Iterator(EnumLimits<Enum>::Last + 1);
+	}
+};
+
+template<typename Enum>
+EnumIterShell<Enum> iterateEnum()
+{
+	return EnumIterShell<Enum>();
+}
+
+/*
+ * Casts an enum into its underlying type.
+ */
+template<typename T>
+typename std::underlying_type<T>::type& enum_cast(T& enu)
+{
+	return *reinterpret_cast<typename std::underlying_type<T>::type*>(&enu);
+}
+
+/*
+ * Returns whether an enum value is within proper bounds.
+ */
+template<typename Enum>
+bool valueInEnum(Enum enumerator)
+{
+	auto index = enum_cast(enumerator);
+	return index >= EnumLimits<Enum>::First and index <= EnumLimits<Enum>::Last;
+}
+
+#define MAKE_ITERABLE_ENUM(T) \
+	template<> \
+	struct EnumLimits<T> \
+	{\
+		enum { First = 0, Last = static_cast<int>(T::_End) - 1, Count = Last + 1 };\
+	}; \
+	inline T operator++ (T& a) { a = static_cast<T>(enum_cast(a) + 1); return a; } \
+	inline T operator-- (T& a) { a = static_cast<T>(enum_cast(a) - 1); return a; } \
+	inline T operator++ (T& a, int) { T result = a; a = static_cast<T>(enum_cast(a) + 1); return result; } \
+	inline T operator-- (T& a, int) { T result = a; a = static_cast<T>(enum_cast(a) - 1); return result; }

mercurial