diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h index 330aefd0e4..654febd3ca 100644 --- a/include/gpu/GrTypes.h +++ b/include/gpu/GrTypes.h @@ -53,25 +53,75 @@ template \ 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 class GrTFlagsMask { +public: + constexpr explicit GrTFlagsMask(TFlags value) : GrTFlagsMask(static_cast(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 constexpr GrTFlagsMask operator|(GrTFlagsMask a, + GrTFlagsMask b) { + return GrTFlagsMask(a.value() | b.value()); +} +template constexpr GrTFlagsMask operator|(GrTFlagsMask a, + TFlags b) { + return GrTFlagsMask(a.value() | static_cast(b)); +} +template constexpr GrTFlagsMask operator|(TFlags a, + GrTFlagsMask b) { + return GrTFlagsMask(static_cast(a) | b.value()); +} +template inline GrTFlagsMask& operator|=(GrTFlagsMask& a, + GrTFlagsMask b) { + return (a = a | b); +} + +// And-ing two masks returns another mask; and-ing one with regular flags returns flags. +template constexpr GrTFlagsMask operator&(GrTFlagsMask a, + GrTFlagsMask b) { + return GrTFlagsMask(a.value() & b.value()); +} +template constexpr TFlags operator&(GrTFlagsMask a, TFlags b) { + return static_cast(a.value() & static_cast(b)); +} +template constexpr TFlags operator&(TFlags a, GrTFlagsMask b) { + return static_cast(static_cast(a) & b.value()); +} +template inline TFlags& operator&=(TFlags& a, GrTFlagsMask 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 operator~(X a) { \ + return GrTFlagsMask(~static_cast(a)); \ } \ - inline X& operator |=(X& a, X b) { \ + constexpr X operator|(X a, X b) { \ + return static_cast(static_cast(a) | static_cast(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(a) & static_cast(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 operator ~(X); \ + friend constexpr X operator |(X, X); \ + friend X& operator |=(X&, X); \ + friend constexpr bool operator &(X, X); ////////////////////////////////////////////////////////////////////////////////