99
1010namespace impeller {
1111
12+ template <typename EnumType_>
13+ struct MaskTraits {
14+ static constexpr bool kIsMask = false ;
15+ };
16+
17+ // ------------------------------------------------------------------------------
18+ // / @brief Declare this in the "impeller" namespace to make the enum
19+ // / maskable.
20+ // /
21+ #define IMPELLER_ENUM_IS_MASK (enum_name ) \
22+ template <> \
23+ struct MaskTraits <enum_name> { \
24+ static constexpr bool kIsMask = true ; \
25+ };
26+
1227// ------------------------------------------------------------------------------
1328// / @brief A mask of typed enums.
1429// /
@@ -110,42 +125,56 @@ struct Mask {
110125
111126// Construction from Enum Types
112127
113- template <typename EnumType>
128+ template <
129+ typename EnumType,
130+ typename std::enable_if<MaskTraits<EnumType>::kIsMask , bool >::type = true >
114131inline constexpr Mask<EnumType> operator |(const EnumType& lhs,
115132 const EnumType& rhs) {
116133 return Mask<EnumType>{lhs} | rhs;
117134}
118135
119- template <typename EnumType>
136+ template <
137+ typename EnumType,
138+ typename std::enable_if<MaskTraits<EnumType>::kIsMask , bool >::type = true >
120139inline constexpr Mask<EnumType> operator &(const EnumType& lhs,
121140 const EnumType& rhs) {
122141 return Mask<EnumType>{lhs} & rhs;
123142}
124143
125- template <typename EnumType>
144+ template <
145+ typename EnumType,
146+ typename std::enable_if<MaskTraits<EnumType>::kIsMask , bool >::type = true >
126147inline constexpr Mask<EnumType> operator ^(const EnumType& lhs,
127148 const EnumType& rhs) {
128149 return Mask<EnumType>{lhs} ^ rhs;
129150}
130151
131- template <typename EnumType>
152+ template <
153+ typename EnumType,
154+ typename std::enable_if<MaskTraits<EnumType>::kIsMask , bool >::type = true >
132155inline constexpr Mask<EnumType> operator ~(const EnumType& other) {
133156 return ~Mask<EnumType>{other};
134157}
135158
136- template <typename EnumType>
159+ template <
160+ typename EnumType,
161+ typename std::enable_if<MaskTraits<EnumType>::kIsMask , bool >::type = true >
137162inline constexpr Mask<EnumType> operator |(const EnumType& lhs,
138163 const Mask<EnumType>& rhs) {
139164 return Mask<EnumType>{lhs} | rhs;
140165}
141166
142- template <typename EnumType>
167+ template <
168+ typename EnumType,
169+ typename std::enable_if<MaskTraits<EnumType>::kIsMask , bool >::type = true >
143170inline constexpr Mask<EnumType> operator &(const EnumType& lhs,
144171 const Mask<EnumType>& rhs) {
145172 return Mask<EnumType>{lhs} & rhs;
146173}
147174
148- template <typename EnumType>
175+ template <
176+ typename EnumType,
177+ typename std::enable_if<MaskTraits<EnumType>::kIsMask , bool >::type = true >
149178inline constexpr Mask<EnumType> operator ^(const EnumType& lhs,
150179 const Mask<EnumType>& rhs) {
151180 return Mask<EnumType>{lhs} ^ rhs;
@@ -154,37 +183,43 @@ inline constexpr Mask<EnumType> operator^(const EnumType& lhs,
154183// Relational operators with EnumType promotion. These can be replaced by a
155184// defaulted spaceship operator post C++20.
156185
157- template <typename EnumType>
186+ template <typename EnumType,
187+ typename std::enable_if_t <MaskTraits<EnumType>::kIsMask , bool > = true >
158188inline constexpr bool operator <(const EnumType& lhs,
159189 const Mask<EnumType>& rhs) {
160190 return Mask<EnumType>{lhs} < rhs;
161191}
162192
163- template <typename EnumType>
193+ template <typename EnumType,
194+ typename std::enable_if_t <MaskTraits<EnumType>::kIsMask , bool > = true >
164195inline constexpr bool operator >(const EnumType& lhs,
165196 const Mask<EnumType>& rhs) {
166197 return Mask<EnumType>{lhs} > rhs;
167198}
168199
169- template <typename EnumType>
200+ template <typename EnumType,
201+ typename std::enable_if_t <MaskTraits<EnumType>::kIsMask , bool > = true >
170202inline constexpr bool operator <=(const EnumType& lhs,
171203 const Mask<EnumType>& rhs) {
172204 return Mask<EnumType>{lhs} <= rhs;
173205}
174206
175- template <typename EnumType>
207+ template <typename EnumType,
208+ typename std::enable_if_t <MaskTraits<EnumType>::kIsMask , bool > = true >
176209inline constexpr bool operator >=(const EnumType& lhs,
177210 const Mask<EnumType>& rhs) {
178211 return Mask<EnumType>{lhs} >= rhs;
179212}
180213
181- template <typename EnumType>
214+ template <typename EnumType,
215+ typename std::enable_if_t <MaskTraits<EnumType>::kIsMask , bool > = true >
182216inline constexpr bool operator ==(const EnumType& lhs,
183217 const Mask<EnumType>& rhs) {
184218 return Mask<EnumType>{lhs} == rhs;
185219}
186220
187- template <typename EnumType>
221+ template <typename EnumType,
222+ typename std::enable_if_t <MaskTraits<EnumType>::kIsMask , bool > = true >
188223inline constexpr bool operator !=(const EnumType& lhs,
189224 const Mask<EnumType>& rhs) {
190225 return Mask<EnumType>{lhs} != rhs;
0 commit comments