فهرست منبع

enum: enum_bitmask concept

skypjack 1 ماه پیش
والد
کامیت
1bb590a57e
1فایلهای تغییر یافته به همراه30 افزوده شده و 26 حذف شده
  1. 30 26
      src/entt/core/enum.hpp

+ 30 - 26
src/entt/core/enum.hpp

@@ -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));
 }