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);
////////////////////////////////////////////////////////////////////////////////