| /* |
| * Copyright 2023 Rive |
| */ |
| |
| #ifndef _RIVE_ENUM_BITSET_HPP_ |
| #define _RIVE_ENUM_BITSET_HPP_ |
| |
| #include <type_traits> |
| |
| namespace rive |
| { |
| // Wraps an enum containing a bitfield so that we can do implicit bool conversions. |
| template <typename T> class EnumBitset |
| { |
| public: |
| using UnderlyingType = typename std::underlying_type<T>::type; |
| constexpr EnumBitset() = default; |
| constexpr EnumBitset(T value) : m_bits(static_cast<UnderlyingType>(value)) {} |
| constexpr UnderlyingType bits() const { return m_bits; } |
| constexpr T value() const { return static_cast<T>(m_bits); } |
| constexpr operator T() const { return value(); } |
| constexpr operator bool() const { return m_bits != 0; } |
| |
| private: |
| UnderlyingType m_bits = 0; |
| }; |
| } // namespace rive |
| |
| #define RIVE_MAKE_ENUM_BITSET(ENUM) \ |
| constexpr inline ::rive::EnumBitset<ENUM> operator&(::rive::EnumBitset<ENUM> lhs, \ |
| ::rive::EnumBitset<ENUM> rhs) \ |
| { \ |
| return static_cast<ENUM>(lhs.bits() & rhs.bits()); \ |
| } \ |
| constexpr inline ::rive::EnumBitset<ENUM> operator&(ENUM lhs, ::rive::EnumBitset<ENUM> rhs) \ |
| { \ |
| return ::rive::EnumBitset<ENUM>(lhs) & rhs; \ |
| } \ |
| constexpr inline ::rive::EnumBitset<ENUM> operator&(::rive::EnumBitset<ENUM> lhs, ENUM rhs) \ |
| { \ |
| return lhs & ::rive::EnumBitset<ENUM>(rhs); \ |
| } \ |
| constexpr inline ::rive::EnumBitset<ENUM> operator&(ENUM lhs, ENUM rhs) \ |
| { \ |
| return ::rive::EnumBitset<ENUM>(lhs) & ::rive::EnumBitset<ENUM>(rhs); \ |
| } \ |
| \ |
| constexpr inline ::rive::EnumBitset<ENUM> operator|(::rive::EnumBitset<ENUM> lhs, \ |
| ::rive::EnumBitset<ENUM> rhs) \ |
| { \ |
| return static_cast<ENUM>(lhs.bits() | rhs.bits()); \ |
| } \ |
| constexpr inline ::rive::EnumBitset<ENUM> operator|(ENUM lhs, ::rive::EnumBitset<ENUM> rhs) \ |
| { \ |
| return ::rive::EnumBitset<ENUM>(lhs) | rhs; \ |
| } \ |
| constexpr inline ::rive::EnumBitset<ENUM> operator|(::rive::EnumBitset<ENUM> lhs, ENUM rhs) \ |
| { \ |
| return lhs | ::rive::EnumBitset<ENUM>(rhs); \ |
| } \ |
| constexpr inline ::rive::EnumBitset<ENUM> operator|(ENUM lhs, ENUM rhs) \ |
| { \ |
| return ::rive::EnumBitset<ENUM>(lhs) | ::rive::EnumBitset<ENUM>(rhs); \ |
| } \ |
| \ |
| constexpr inline ::rive::EnumBitset<ENUM> operator~(::rive::EnumBitset<ENUM> rhs) \ |
| { \ |
| return static_cast<ENUM>(~rhs.bits()); \ |
| } \ |
| constexpr inline ::rive::EnumBitset<ENUM> operator~(ENUM rhs) \ |
| { \ |
| return ~::rive::EnumBitset<ENUM>(rhs); \ |
| } \ |
| \ |
| inline ENUM& operator&=(ENUM& lhs, ::rive::EnumBitset<ENUM> rhs) { return lhs = lhs & rhs; } \ |
| inline ENUM& operator&=(ENUM& lhs, ENUM rhs) { return lhs = lhs & rhs; } \ |
| \ |
| inline ENUM& operator|=(ENUM& lhs, ::rive::EnumBitset<ENUM> rhs) { return lhs = lhs | rhs; } \ |
| inline ENUM& operator|=(ENUM& lhs, ENUM rhs) { return lhs = lhs | rhs; } |
| |
| #endif |