| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- // Copyright (c) 2008-2023 the Urho3D project
- // License: MIT
- #pragma once
- #include "../Base/PrimitiveTypes.h"
- #include <type_traits>
- namespace Urho3D
- {
- /// Define bitwise operators for scoped enum.
- /// Use !! to convert scoped enum to bool
- #define URHO3D_FLAGS(EnumClass) \
- inline constexpr EnumClass operator |(const EnumClass lhs, const EnumClass rhs) \
- { \
- using UT = std::underlying_type_t<EnumClass>; \
- return static_cast<EnumClass>(static_cast<UT>(lhs) | static_cast<UT>(rhs)); \
- } \
- inline constexpr EnumClass& operator |=(EnumClass& lhs, const EnumClass rhs) \
- { \
- using UT = std::underlying_type_t<EnumClass>; \
- lhs = static_cast<EnumClass>(static_cast<UT>(lhs) | static_cast<UT>(rhs)); \
- return lhs; \
- } \
- inline constexpr EnumClass operator &(const EnumClass lhs, const EnumClass rhs) \
- { \
- using UT = std::underlying_type_t<EnumClass>; \
- return static_cast<EnumClass>(static_cast<UT>(lhs) & static_cast<UT>(rhs)); \
- } \
- inline constexpr EnumClass& operator &=(EnumClass& lhs, const EnumClass rhs) \
- { \
- using UT = std::underlying_type_t<EnumClass>; \
- lhs = static_cast<EnumClass>(static_cast<UT>(lhs) & static_cast<UT>(rhs)); \
- return lhs; \
- } \
- inline constexpr EnumClass operator ^(const EnumClass lhs, const EnumClass rhs) \
- { \
- using UT = std::underlying_type_t<EnumClass>; \
- return static_cast<EnumClass>(static_cast<UT>(lhs) ^ static_cast<UT>(rhs)); \
- } \
- inline constexpr EnumClass& operator ^=(EnumClass& lhs, const EnumClass rhs) \
- { \
- using UT = std::underlying_type_t<EnumClass>; \
- lhs = static_cast<EnumClass>(static_cast<UT>(lhs) ^ static_cast<UT>(rhs)); \
- return lhs; \
- } \
- inline constexpr EnumClass operator ~(const EnumClass rhs) \
- { \
- using UT = std::underlying_type_t<EnumClass>; \
- return static_cast<EnumClass>(~static_cast<UT>(rhs)); \
- } \
- inline constexpr bool operator ==(const EnumClass lhs, const std::underlying_type_t<EnumClass> rhs) \
- { \
- using UT = std::underlying_type_t<EnumClass>; \
- return static_cast<UT>(lhs) == rhs; \
- } \
- inline constexpr bool operator ==(const std::underlying_type_t<EnumClass> lhs, const EnumClass rhs) \
- { \
- using UT = std::underlying_type_t<EnumClass>; \
- return lhs == static_cast<UT>(rhs); \
- } \
- inline constexpr bool operator !=(const EnumClass lhs, const std::underlying_type_t<EnumClass> rhs) \
- { \
- using UT = std::underlying_type_t<EnumClass>; \
- return static_cast<UT>(lhs) != rhs; \
- } \
- inline constexpr bool operator !=(const std::underlying_type_t<EnumClass> lhs, const EnumClass rhs) \
- { \
- using UT = std::underlying_type_t<EnumClass>; \
- return lhs != static_cast<UT>(rhs); \
- } \
- inline constexpr bool operator !(const EnumClass rhs) \
- { \
- using UT = std::underlying_type_t<EnumClass>; \
- return static_cast<UT>(rhs) == 0; \
- }
- /// Make bitwise operators (| & ^ ~) automatically construct FlagSet from Enum.
- #define URHO3D_AUTOMATIC_FLAGSET(Enum) \
- inline Urho3D::FlagSet<Enum> operator | (const Enum lhs, const Enum rhs) { return Urho3D::FlagSet<Enum>(lhs) | rhs; } \
- inline Urho3D::FlagSet<Enum> operator & (const Enum lhs, const Enum rhs) { return Urho3D::FlagSet<Enum>(lhs) & rhs; } \
- inline Urho3D::FlagSet<Enum> operator ^ (const Enum lhs, const Enum rhs) { return Urho3D::FlagSet<Enum>(lhs) ^ rhs; } \
- inline Urho3D::FlagSet<Enum> operator ~ (const Enum rhs) { return ~Urho3D::FlagSet<Enum>(rhs); }
- /// Declare FlagSet for specific enum and create operators for automatic FlagSet construction.
- #define URHO3D_FLAGSET(enumName, flagsetName) \
- URHO3D_AUTOMATIC_FLAGSET(enumName) \
- using flagsetName = Urho3D::FlagSet<enumName>
- /// A set of flags defined by an Enum.
- template <class E>
- class FlagSet
- {
- public:
- /// Enum type.
- using Enum = E;
- /// Integer type.
- using Integer = typename std::underlying_type<Enum>::type;
- public:
- /// Ctor by integer.
- explicit FlagSet(Integer value)
- : value_(value)
- {
- }
- /// Empty constructor.
- FlagSet() = default;
- /// Copy constructor.
- FlagSet(const FlagSet& another) = default;
- /// Construct from Enum value.
- FlagSet(const Enum value)
- : value_(static_cast<Integer>(value))
- {
- }
- /// Assignment operator from flagset.
- FlagSet& operator = (const FlagSet& rhs) = default;
- /// Bitwise AND against Enum value.
- FlagSet& operator &= (const Enum value)
- {
- value_ &= static_cast<Integer>(value);
- return *this;
- }
- /// Bitwise AND against flagset value.
- FlagSet& operator &= (const FlagSet value)
- {
- value_ &= value.value_;
- return *this;
- }
- /// Bitwise OR against Enum value.
- FlagSet& operator |= (const Enum value)
- {
- value_ |= static_cast<Integer>(value);
- return *this;
- }
- /// Bitwise OR against flagset value.
- FlagSet& operator |= (const FlagSet value)
- {
- value_ |= value.value_;
- return *this;
- }
- /// Bitwise XOR against Enum value.
- FlagSet& operator ^= (const Enum value)
- {
- value_ ^= static_cast<Integer>(value);
- return *this;
- }
- /// Bitwise XOR against flagset value.
- FlagSet& operator ^= (const FlagSet value)
- {
- value_ ^= value.value_;
- return *this;
- }
- /// Bitwise AND against Enum value.
- FlagSet operator & (const Enum value) const
- {
- return FlagSet(value_ & static_cast<Integer>(value));
- }
- /// Bitwise AND against flagset value.
- FlagSet operator & (const FlagSet value) const
- {
- return FlagSet(value_ & value.value_);
- }
- /// Bitwise OR against Enum value.
- FlagSet operator | (const Enum value) const
- {
- return FlagSet(value_ | static_cast<Integer>(value));
- }
- /// Bitwise OR against flagset value.
- FlagSet operator | (const FlagSet value) const
- {
- return FlagSet(value_ | value.value_);
- }
- /// Bitwise XOR against Enum value.
- FlagSet operator ^ (const Enum value) const
- {
- return FlagSet(value_ ^ static_cast<Integer>(value));
- }
- /// Bitwise XOR against flagset value.
- FlagSet operator ^ (const FlagSet value) const
- {
- return FlagSet(value_ ^ value.value_);
- }
- /// Bitwise negation.
- FlagSet operator ~ () const
- {
- return FlagSet(~value_);
- }
- /// Boolean negation.
- bool operator ! () const
- {
- return !value_;
- }
- /// Returns true if any flag is set.
- explicit operator bool () const
- {
- return value_ != 0;
- }
- /// Cast to underlying type of enum.
- operator Integer() const
- {
- return value_;
- }
- /// Cast to enum value.
- explicit operator Enum() const
- {
- return static_cast<Enum>(value_);
- }
- /// Cast to double. Used by Lua bindings.
- explicit operator double() const
- {
- return static_cast<double>(value_);
- }
- /// Equality check against enum value.
- bool operator ==(Enum rhs) const
- {
- return value_ == static_cast<Integer>(rhs);
- }
- /// Equality check against another flagset.
- bool operator ==(FlagSet rhs) const
- {
- return value_ == rhs.value_;
- }
- /// Non-equality check against enum value.
- bool operator !=(Enum rhs) const
- {
- return !(*this == rhs);
- }
- /// Non-equality check against another flagset value.
- bool operator !=(FlagSet rhs) const
- {
- return !(*this == rhs);
- }
- /// Return true if specified enum value is set.
- inline bool Test(const Enum value) const
- {
- return Test(static_cast<Integer>(value));
- }
- /// Return true if specified bits are set.
- inline bool Test(const Integer flags) const
- {
- return (value_ & flags) == flags && (flags != 0 || value_ == flags);
- }
- /// Return underlying integer (constant).
- Integer AsInteger() const { return value_; }
- /// Return underlying integer (non-constant).
- Integer& AsInteger() { return value_; }
- /// Return hash value.
- hash32 ToHash() const { return static_cast<hash32>(value_); }
- protected:
- /// Value.
- Integer value_ = 0;
- };
- }
|