-#pragma once\r
-\r
-namespace caspar {\r
-\r
-template<typename def, typename inner = typename def::type>\r
-class enum_class : public def\r
-{\r
- typedef typename def::type type;\r
- inner val_; \r
-public: \r
- explicit enum_class(int v) : val_(static_cast<type>(v)) {}\r
- enum_class(type v) : val_(v) {}\r
- inner value() const { return val_; }\r
- \r
- bool operator==(const enum_class& s) const { return val_ == s.val_; }\r
- bool operator!=(const enum_class& s) const { return val_ != s.val_; }\r
- bool operator<(const enum_class& s) const { return val_ < s.val_; }\r
- bool operator<=(const enum_class& s) const { return val_ <= s.val_; }\r
- bool operator>(const enum_class& s) const { return val_ > s.val_; }\r
- bool operator>=(const enum_class& s) const { return val_ >= s.val_; }\r
-\r
- enum_class operator&(const enum_class& s) const\r
- {\r
- return enum_class(static_cast<type>(val_ & s.val_));\r
- }\r
-\r
- enum_class operator|(const enum_class& s) const\r
- {\r
- return enum_class(static_cast<type>(val_ | s.val_));\r
- }\r
-\r
- //operator inner()\r
- //{\r
- // return val_;\r
- //}\r
-};\r
-\r
-#define CASPAR_ENUM_CLASS_DEF(name) name ## _def\r
-#define CASPAR_BEGIN_ENUM_CLASS typedef struct { enum type \r
-#define CASPAR_END_ENUM_CLASS(name) ;} CASPAR_ENUM_CLASS_DEF(name); typedef enum_class<CASPAR_ENUM_CLASS_DEF(name)> name;\r
-\r
-}
\ No newline at end of file
+#pragma once
+
+#include <type_traits>
+
+#include <boost/range/irange.hpp>
+
+#include "linq.h"
+
+// Macro that defines & and &= for an enum class. Add more when needed.
+
+#define ENUM_ENABLE_BITWISE(enum_class) \
+ static enum_class operator&(enum_class lhs, enum_class rhs) \
+ { \
+ return static_cast<enum_class>( \
+ static_cast<std::underlying_type<enum_class>::type>(lhs) \
+ & static_cast<std::underlying_type<enum_class>::type>(rhs)); \
+ }; \
+ static enum_class& operator&=(enum_class& lhs, enum_class rhs) \
+ { \
+ lhs = lhs & rhs; \
+ return lhs; \
+ }; \
+ static enum_class operator | (enum_class lhs, enum_class rhs) \\r
+ { \\r
+ return static_cast<enum_class>( \\r
+ static_cast<std::underlying_type<enum_class>::type>(lhs) \\r
+ | static_cast<std::underlying_type<enum_class>::type>(rhs)); \\r
+ }; \\r
+ static enum_class& operator|=(enum_class& lhs, enum_class rhs) \
+ { \
+ lhs = lhs | rhs; \
+ return lhs; \
+ }; \
+ static enum_class operator ^ (enum_class lhs, enum_class rhs) \\r
+ { \\r
+ return static_cast<enum_class>( \\r
+ static_cast<std::underlying_type<enum_class>::type>(lhs) \\r
+ ^ static_cast<std::underlying_type<enum_class>::type>(rhs)); \\r
+ }; \\r
+ static enum_class& operator^=(enum_class& lhs, enum_class rhs) \
+ { \
+ lhs = lhs ^ rhs; \
+ return lhs; \
+ };
+
+namespace caspar {
+
+// For enum classes starting at 0 and without any gaps with a terminating count constant.
+template <typename E>
+const std::vector<E>& enum_constants()
+{
+ typedef typename std::underlying_type<E>::type integer;
+
+ static const auto ints = boost::irange(static_cast<integer>(0), static_cast<integer>(E::count));
+ static const auto result = cpplinq::from(ints.begin(), ints.end())
+ //.cast<E>()
+ .select([](int i) { return static_cast<E>(i); })
+ .to_vector();
+
+ return result;
+}
+
+}