#ifndef ENTT_CORE_ENUM_HPP #define ENTT_CORE_ENUM_HPP #include "../stl/concepts.hpp" #include "../stl/type_traits.hpp" namespace entt { /** * @brief Enable bitmask support for enum classes. * @tparam Type The enum type for which to enable bitmask support. */ template struct enum_as_bitmask: stl::false_type {}; /*! @copydoc enum_as_bitmask */ template requires requires { requires stl::is_enum_v; { Type::_entt_enum_as_bitmask } -> stl::same_as; } struct enum_as_bitmask: stl::true_type {}; /** * @brief Helper variable template. * @tparam Type The enum class type for which to enable bitmask support. */ template inline constexpr bool enum_as_bitmask_v = enum_as_bitmask::value; /** * @brief Specifies that an enum class supports bitmask operations. * @tparam Type Enum class type. */ template // check again that it is an enum to deal with incorrect specializations concept enum_bitmask = stl::is_enum_v && enum_as_bitmask_v; } // namespace entt /** * @brief Operator available for enums for which bitmask support is enabled. * @tparam Type Enum class type. * @param lhs The first value to use. * @param rhs The second value to use. * @return The result of invoking the operator on the underlying types of the * two values provided. */ template [[nodiscard]] constexpr Type operator|(const Type lhs, const Type rhs) noexcept { return static_cast(static_cast>(lhs) | static_cast>(rhs)); } /*! @copydoc operator| */ template [[nodiscard]] constexpr Type operator&(const Type lhs, const Type rhs) noexcept { return static_cast(static_cast>(lhs) & static_cast>(rhs)); } /*! @copydoc operator| */ template [[nodiscard]] constexpr Type operator^(const Type lhs, const Type rhs) noexcept { return static_cast(static_cast>(lhs) ^ static_cast>(rhs)); } /** * @brief Operator available for enums for which bitmask support is enabled. * @tparam Type Enum class type. * @param value The value to use. * @return The result of invoking the operator on the underlying types of the * value provided. */ template [[nodiscard]] constexpr Type operator~(const Type value) noexcept { return static_cast(~static_cast>(value)); } /*! @copydoc operator~ */ template [[nodiscard]] constexpr bool operator!(const Type value) noexcept { return !static_cast>(value); } /*! @copydoc operator| */ template constexpr Type &operator|=(Type &lhs, const Type rhs) noexcept { return (lhs = (lhs | rhs)); } /*! @copydoc operator| */ template constexpr Type &operator&=(Type &lhs, const Type rhs) noexcept { return (lhs = (lhs & rhs)); } /*! @copydoc operator| */ template constexpr Type &operator^=(Type &lhs, const Type rhs) noexcept { return (lhs = (lhs ^ rhs)); } #endif