aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/types/EnumBitfield.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic-simulation/types/EnumBitfield.hpp')
-rw-r--r--src/openvic-simulation/types/EnumBitfield.hpp84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/openvic-simulation/types/EnumBitfield.hpp b/src/openvic-simulation/types/EnumBitfield.hpp
new file mode 100644
index 0000000..2b0a1cf
--- /dev/null
+++ b/src/openvic-simulation/types/EnumBitfield.hpp
@@ -0,0 +1,84 @@
+#pragma once
+
+#include <type_traits>
+
+namespace OpenVic {
+ template<typename E>
+ struct is_scoped_enum final : std::bool_constant < requires {
+ requires std::is_enum_v<E>;
+ requires !std::is_convertible_v<E, std::underlying_type_t<E>>;
+ } > {};
+
+ template<class T>
+ inline constexpr bool is_scoped_enum_v = is_scoped_enum<T>::value;
+
+ template<typename T>
+ concept IsScopedEnum = is_scoped_enum_v<T>;
+
+ template<IsScopedEnum T>
+ struct enable_bitfield final : std::false_type {
+ };
+
+ template<IsScopedEnum T>
+ inline constexpr bool enable_bitfield_v = enable_bitfield<T>::value;
+
+ template<typename T>
+ concept EnumSupportBitfield = enable_bitfield_v<T>;
+}
+
+template<OpenVic::EnumSupportBitfield T>
+[[nodiscard]] constexpr inline auto operator|(const T lhs, const T rhs) noexcept {
+ using underlying_type = std::underlying_type_t<T>;
+ return static_cast<T>(static_cast<underlying_type>(lhs) | static_cast<underlying_type>(rhs));
+}
+
+template<OpenVic::EnumSupportBitfield T>
+[[nodiscard]] constexpr inline auto operator&(const T lhs, const T rhs) noexcept {
+ using underlying_type = std::underlying_type_t<T>;
+ return static_cast<T>(static_cast<underlying_type>(lhs) & static_cast<underlying_type>(rhs));
+}
+
+template<OpenVic::EnumSupportBitfield T>
+[[nodiscard]] constexpr inline auto operator^(const T lhs, const T rhs) noexcept {
+ using underlying_type = std::underlying_type_t<T>;
+ return static_cast<T>(static_cast<underlying_type>(lhs) ^ static_cast<underlying_type>(rhs));
+}
+
+template<OpenVic::EnumSupportBitfield T>
+[[nodiscard]] constexpr inline auto operator~(const T lhs) noexcept {
+ using underlying_type = std::underlying_type_t<T>;
+ return static_cast<T>(~static_cast<underlying_type>(lhs));
+}
+
+template<OpenVic::EnumSupportBitfield T>
+constexpr inline decltype(auto) operator|=(T& lhs, const T rhs) noexcept {
+ using underlying_type = std::underlying_type_t<T>;
+ lhs = static_cast<T>(static_cast<underlying_type>(lhs) | static_cast<underlying_type>(rhs));
+ return lhs;
+}
+
+template<OpenVic::EnumSupportBitfield T>
+constexpr inline decltype(auto) operator&=(T& lhs, const T rhs) noexcept {
+ using underlying_type = std::underlying_type_t<T>;
+ lhs = static_cast<T>(static_cast<underlying_type>(lhs) & static_cast<underlying_type>(rhs));
+ return lhs;
+}
+
+template<OpenVic::EnumSupportBitfield T>
+constexpr inline decltype(auto) operator^=(T& lhs, const T rhs) noexcept {
+ using underlying_type = std::underlying_type_t<T>;
+ lhs = static_cast<T>(static_cast<underlying_type>(lhs) ^ static_cast<underlying_type>(rhs));
+ return lhs;
+}
+
+template<OpenVic::EnumSupportBitfield T>
+[[nodiscard]] constexpr inline bool operator<<(const T lhs, const T rhs) noexcept {
+ using underlying_type = std::underlying_type_t<T>;
+ return (lhs & rhs) == rhs;
+}
+
+template<OpenVic::EnumSupportBitfield T>
+[[nodiscard]] constexpr inline bool operator>>(const T lhs, const T rhs) noexcept {
+ using underlying_type = std::underlying_type_t<T>;
+ return (lhs & rhs) == lhs;
+}