Add GrTFlagsMask<> wrapper for C++11 bitfield enums
Previously, operator& for enum class bitfields was reserved only to return a bool. e.g: if (flags & Flags::kFlag) This change adds a new template class GrTFlagsMask<> that gets instantiated by operator~ and allows us to write expressions like: flags &= ~Flags::kFlag (flags & ~Flags::kFlag1) | Flags::kFlag2 BUG=skia: Change-Id: I21e5eb9304135e82cdda459e8a833a3489f6beaf Reviewed-on: https://skia-review.googlesource.com/8563 Commit-Queue: Chris Dalton <csmartdalton@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
a9d0d9e71a
commit
ad2a2becb6
@ -53,25 +53,75 @@
|
||||
template <typename T> \
|
||||
friend X operator &(X a, T b); \
|
||||
|
||||
/**
|
||||
* Wraps a C++11 enum that we use as a bitfield, and enables a limited amount of
|
||||
* masking with type safety. Instantiated with the ~ operator.
|
||||
*/
|
||||
template<typename TFlags> class GrTFlagsMask {
|
||||
public:
|
||||
constexpr explicit GrTFlagsMask(TFlags value) : GrTFlagsMask(static_cast<int>(value)) {}
|
||||
constexpr explicit GrTFlagsMask(int value) : fValue(value) {}
|
||||
constexpr int value() const { return fValue; }
|
||||
private:
|
||||
const int fValue;
|
||||
};
|
||||
|
||||
// Or-ing a mask always returns another mask.
|
||||
template<typename TFlags> constexpr GrTFlagsMask<TFlags> operator|(GrTFlagsMask<TFlags> a,
|
||||
GrTFlagsMask<TFlags> b) {
|
||||
return GrTFlagsMask<TFlags>(a.value() | b.value());
|
||||
}
|
||||
template<typename TFlags> constexpr GrTFlagsMask<TFlags> operator|(GrTFlagsMask<TFlags> a,
|
||||
TFlags b) {
|
||||
return GrTFlagsMask<TFlags>(a.value() | static_cast<int>(b));
|
||||
}
|
||||
template<typename TFlags> constexpr GrTFlagsMask<TFlags> operator|(TFlags a,
|
||||
GrTFlagsMask<TFlags> b) {
|
||||
return GrTFlagsMask<TFlags>(static_cast<int>(a) | b.value());
|
||||
}
|
||||
template<typename TFlags> inline GrTFlagsMask<TFlags>& operator|=(GrTFlagsMask<TFlags>& a,
|
||||
GrTFlagsMask<TFlags> b) {
|
||||
return (a = a | b);
|
||||
}
|
||||
|
||||
// And-ing two masks returns another mask; and-ing one with regular flags returns flags.
|
||||
template<typename TFlags> constexpr GrTFlagsMask<TFlags> operator&(GrTFlagsMask<TFlags> a,
|
||||
GrTFlagsMask<TFlags> b) {
|
||||
return GrTFlagsMask<TFlags>(a.value() & b.value());
|
||||
}
|
||||
template<typename TFlags> constexpr TFlags operator&(GrTFlagsMask<TFlags> a, TFlags b) {
|
||||
return static_cast<TFlags>(a.value() & static_cast<int>(b));
|
||||
}
|
||||
template<typename TFlags> constexpr TFlags operator&(TFlags a, GrTFlagsMask<TFlags> b) {
|
||||
return static_cast<TFlags>(static_cast<int>(a) & b.value());
|
||||
}
|
||||
template<typename TFlags> inline TFlags& operator&=(TFlags& a, GrTFlagsMask<TFlags> b) {
|
||||
return (a = a & b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines bitwise operators that make it possible to use an enum class as a
|
||||
* very basic bitfield.
|
||||
* basic bitfield.
|
||||
*/
|
||||
#define GR_MAKE_BITFIELD_CLASS_OPS(X) \
|
||||
inline X operator |(X a, X b) { \
|
||||
return (X) ((int)a | (int)b); \
|
||||
constexpr GrTFlagsMask<X> operator~(X a) { \
|
||||
return GrTFlagsMask<X>(~static_cast<int>(a)); \
|
||||
} \
|
||||
inline X& operator |=(X& a, X b) { \
|
||||
constexpr X operator|(X a, X b) { \
|
||||
return static_cast<X>(static_cast<int>(a) | static_cast<int>(b)); \
|
||||
} \
|
||||
inline X& operator|=(X& a, X b) { \
|
||||
return (a = a | b); \
|
||||
} \
|
||||
inline bool operator &(X a, X b) { \
|
||||
return SkToBool((int)a & (int)b); \
|
||||
}
|
||||
constexpr bool operator&(X a, X b) { \
|
||||
return SkToBool(static_cast<int>(a) & static_cast<int>(b)); \
|
||||
} \
|
||||
|
||||
#define GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(X) \
|
||||
friend X operator |(X a, X b); \
|
||||
friend X& operator |=(X& a, X b); \
|
||||
friend bool operator &(X a, X b);
|
||||
friend constexpr GrTFlagsMask<X> operator ~(X); \
|
||||
friend constexpr X operator |(X, X); \
|
||||
friend X& operator |=(X&, X); \
|
||||
friend constexpr bool operator &(X, X);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user