]> git.sesse.net Git - casparcg/blobdiff - common/enum_class.h
[osc] Added possibility to completely disable sending OSC to connected AMCP clients...
[casparcg] / common / enum_class.h
index 933f7cba169853f17b1cc035ea15f9b4e278d721..54336823bfd4de3d8b968745d58a4a5532f1ce79 100644 (file)
@@ -1,50 +1,68 @@
 #pragma once\r
 \r
+#include <type_traits>\r
+\r
+#include <boost/range/irange.hpp>\r
+\r
+#include "linq.h"\r
+\r
+// Macro that defines & and &= for an enum class. Add more when needed.\r
+\r
+#define ENUM_ENABLE_BITWISE(enum_class) \\r
+       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) \\r
+       { \\r
+               lhs = lhs & rhs; \\r
+               return lhs; \\r
+       }; \\r
+       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) \\r
+       { \\r
+               lhs = lhs | rhs; \\r
+               return lhs; \\r
+       }; \\r
+       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) \\r
+       { \\r
+               lhs = lhs ^ rhs; \\r
+               return lhs; \\r
+       }; \\r
+       static enum_class operator~ (enum_class e) \\r
+       { \\r
+               return static_cast<enum_class>( \\r
+                               ~static_cast<std::underlying_type<enum_class>::type>(e)); \\r
+       };\r
+\r
 namespace caspar {\r
 \r
-template<typename def, typename inner = typename def::type>\r
-class enum_class : public def\r
+// For enum classes starting at 0 and without any gaps with a terminating count constant.\r
+template <typename E>\r
+const std::vector<E>& enum_constants()\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)\r
-       {\r
-               val_ = static_cast<type>(val_ & s.val_);\r
-               return *this;\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
-       enum_class& operator|=(const enum_class& s)\r
-       {\r
-               val_ = static_cast<type>(val_ | s.val_);\r
-               return *this;\r
-       }\r
-\r
-       //operator inner()\r
-       //{\r
-       //      return val_;\r
-       //}\r
-};\r
-\r
-}
\ No newline at end of file
+       typedef typename std::underlying_type<E>::type integer;\r
+\r
+       static const auto ints = boost::irange(static_cast<integer>(0), static_cast<integer>(E::count));\r
+       static const auto result = cpplinq::from(ints.begin(), ints.end())\r
+               //.cast<E>()\r
+               .select([](int i) { return static_cast<E>(i); })\r
+               .to_vector();\r
+\r
+       return result;\r
+}\r
+\r
+}\r