|
|
@@ -9,12 +9,16 @@ namespace entt {
|
|
|
* @brief Enable bitmask support for enum classes.
|
|
|
* @tparam Type The enum type for which to enable bitmask support.
|
|
|
*/
|
|
|
-template<typename Type, typename = void>
|
|
|
+template<typename Type>
|
|
|
struct enum_as_bitmask: std::false_type {};
|
|
|
|
|
|
/*! @copydoc enum_as_bitmask */
|
|
|
template<typename Type>
|
|
|
-struct enum_as_bitmask<Type, std::void_t<decltype(Type::_entt_enum_as_bitmask)>>: std::is_enum<Type> {};
|
|
|
+requires requires {
|
|
|
+ requires std::is_enum_v<Type>;
|
|
|
+ { Type::_entt_enum_as_bitmask } -> std::same_as<Type>;
|
|
|
+}
|
|
|
+struct enum_as_bitmask<Type>: std::true_type {};
|
|
|
|
|
|
/**
|
|
|
* @brief Helper variable template.
|
|
|
@@ -23,6 +27,14 @@ struct enum_as_bitmask<Type, std::void_t<decltype(Type::_entt_enum_as_bitmask)>>
|
|
|
template<typename Type>
|
|
|
inline constexpr bool enum_as_bitmask_v = enum_as_bitmask<Type>::value;
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Specify that an enum class supports bitmask operations.
|
|
|
+ * @tparam Type Enum class type.
|
|
|
+ */
|
|
|
+template<typename Type>
|
|
|
+// check again that it is an enum to deal with incorrect specializations
|
|
|
+concept enum_bitmask = std::is_enum_v<Type> && enum_as_bitmask_v<Type>;
|
|
|
+
|
|
|
} // namespace entt
|
|
|
|
|
|
/**
|
|
|
@@ -33,23 +45,20 @@ inline constexpr bool enum_as_bitmask_v = enum_as_bitmask<Type>::value;
|
|
|
* @return The result of invoking the operator on the underlying types of the
|
|
|
* two values provided.
|
|
|
*/
|
|
|
-template<typename Type>
|
|
|
-[[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type>
|
|
|
-operator|(const Type lhs, const Type rhs) noexcept {
|
|
|
+template<entt::enum_bitmask Type>
|
|
|
+[[nodiscard]] constexpr Type operator|(const Type lhs, const Type rhs) noexcept {
|
|
|
return static_cast<Type>(static_cast<std::underlying_type_t<Type>>(lhs) | static_cast<std::underlying_type_t<Type>>(rhs));
|
|
|
}
|
|
|
|
|
|
/*! @copydoc operator| */
|
|
|
-template<typename Type>
|
|
|
-[[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type>
|
|
|
-operator&(const Type lhs, const Type rhs) noexcept {
|
|
|
+template<entt::enum_bitmask Type>
|
|
|
+[[nodiscard]] constexpr Type operator&(const Type lhs, const Type rhs) noexcept {
|
|
|
return static_cast<Type>(static_cast<std::underlying_type_t<Type>>(lhs) & static_cast<std::underlying_type_t<Type>>(rhs));
|
|
|
}
|
|
|
|
|
|
/*! @copydoc operator| */
|
|
|
-template<typename Type>
|
|
|
-[[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type>
|
|
|
-operator^(const Type lhs, const Type rhs) noexcept {
|
|
|
+template<entt::enum_bitmask Type>
|
|
|
+[[nodiscard]] constexpr Type operator^(const Type lhs, const Type rhs) noexcept {
|
|
|
return static_cast<Type>(static_cast<std::underlying_type_t<Type>>(lhs) ^ static_cast<std::underlying_type_t<Type>>(rhs));
|
|
|
}
|
|
|
|
|
|
@@ -60,37 +69,32 @@ operator^(const Type lhs, const Type rhs) noexcept {
|
|
|
* @return The result of invoking the operator on the underlying types of the
|
|
|
* value provided.
|
|
|
*/
|
|
|
-template<typename Type>
|
|
|
-[[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type>
|
|
|
-operator~(const Type value) noexcept {
|
|
|
+template<entt::enum_bitmask Type>
|
|
|
+[[nodiscard]] constexpr Type operator~(const Type value) noexcept {
|
|
|
return static_cast<Type>(~static_cast<std::underlying_type_t<Type>>(value));
|
|
|
}
|
|
|
|
|
|
/*! @copydoc operator~ */
|
|
|
-template<typename Type>
|
|
|
-[[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, bool>
|
|
|
-operator!(const Type value) noexcept {
|
|
|
+template<entt::enum_bitmask Type>
|
|
|
+[[nodiscard]] constexpr bool operator!(const Type value) noexcept {
|
|
|
return !static_cast<std::underlying_type_t<Type>>(value);
|
|
|
}
|
|
|
|
|
|
/*! @copydoc operator| */
|
|
|
-template<typename Type>
|
|
|
-constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type &>
|
|
|
-operator|=(Type &lhs, const Type rhs) noexcept {
|
|
|
+template<entt::enum_bitmask Type>
|
|
|
+constexpr Type &operator|=(Type &lhs, const Type rhs) noexcept {
|
|
|
return (lhs = (lhs | rhs));
|
|
|
}
|
|
|
|
|
|
/*! @copydoc operator| */
|
|
|
-template<typename Type>
|
|
|
-constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type &>
|
|
|
-operator&=(Type &lhs, const Type rhs) noexcept {
|
|
|
+template<entt::enum_bitmask Type>
|
|
|
+constexpr Type &operator&=(Type &lhs, const Type rhs) noexcept {
|
|
|
return (lhs = (lhs & rhs));
|
|
|
}
|
|
|
|
|
|
/*! @copydoc operator| */
|
|
|
-template<typename Type>
|
|
|
-constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type &>
|
|
|
-operator^=(Type &lhs, const Type rhs) noexcept {
|
|
|
+template<entt::enum_bitmask Type>
|
|
|
+constexpr Type &operator^=(Type &lhs, const Type rhs) noexcept {
|
|
|
return (lhs = (lhs ^ rhs));
|
|
|
}
|
|
|
|