|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 /* MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS allows using a typed enum as bit flags. */ |
|
8 |
|
9 #ifndef mozilla_TypedEnumBits_h |
|
10 #define mozilla_TypedEnumBits_h |
|
11 |
|
12 #include "mozilla/IntegerTypeTraits.h" |
|
13 #include "mozilla/TypedEnumInternal.h" |
|
14 |
|
15 namespace mozilla { |
|
16 |
|
17 #define MOZ_CASTABLETYPEDENUMRESULT_BINOP(Op, OtherType, ReturnType) \ |
|
18 template<typename E> \ |
|
19 MOZ_CONSTEXPR ReturnType \ |
|
20 operator Op(const OtherType& e, const CastableTypedEnumResult<E>& r) \ |
|
21 { \ |
|
22 return ReturnType(e Op OtherType(r)); \ |
|
23 } \ |
|
24 template<typename E> \ |
|
25 MOZ_CONSTEXPR ReturnType \ |
|
26 operator Op(const CastableTypedEnumResult<E>& r, const OtherType& e) \ |
|
27 { \ |
|
28 return ReturnType(OtherType(r) Op e); \ |
|
29 } \ |
|
30 template<typename E> \ |
|
31 MOZ_CONSTEXPR ReturnType \ |
|
32 operator Op(const CastableTypedEnumResult<E>& r1, \ |
|
33 const CastableTypedEnumResult<E>& r2) \ |
|
34 { \ |
|
35 return ReturnType(OtherType(r1) Op OtherType(r2)); \ |
|
36 } |
|
37 |
|
38 MOZ_CASTABLETYPEDENUMRESULT_BINOP(|, E, CastableTypedEnumResult<E>) |
|
39 MOZ_CASTABLETYPEDENUMRESULT_BINOP(&, E, CastableTypedEnumResult<E>) |
|
40 MOZ_CASTABLETYPEDENUMRESULT_BINOP(^, E, CastableTypedEnumResult<E>) |
|
41 MOZ_CASTABLETYPEDENUMRESULT_BINOP(==, E, bool) |
|
42 MOZ_CASTABLETYPEDENUMRESULT_BINOP(!=, E, bool) |
|
43 MOZ_CASTABLETYPEDENUMRESULT_BINOP(||, bool, bool) |
|
44 MOZ_CASTABLETYPEDENUMRESULT_BINOP(&&, bool, bool) |
|
45 |
|
46 template <typename E> |
|
47 MOZ_CONSTEXPR CastableTypedEnumResult<E> |
|
48 operator ~(const CastableTypedEnumResult<E>& r) |
|
49 { |
|
50 return CastableTypedEnumResult<E>(~(E(r))); |
|
51 } |
|
52 |
|
53 #define MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(Op) \ |
|
54 template<typename E> \ |
|
55 E& \ |
|
56 operator Op(E& r1, \ |
|
57 const CastableTypedEnumResult<E>& r2) \ |
|
58 { \ |
|
59 return r1 Op E(r2); \ |
|
60 } |
|
61 |
|
62 MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(&=) |
|
63 MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(|=) |
|
64 MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP(^=) |
|
65 |
|
66 #undef MOZ_CASTABLETYPEDENUMRESULT_COMPOUND_ASSIGN_OP |
|
67 |
|
68 #undef MOZ_CASTABLETYPEDENUMRESULT_BINOP |
|
69 |
|
70 #ifndef MOZ_HAVE_CXX11_STRONG_ENUMS |
|
71 |
|
72 #define MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(Op, ReturnType) \ |
|
73 template<typename E> \ |
|
74 MOZ_CONSTEXPR ReturnType \ |
|
75 operator Op(typename E::Enum e, const CastableTypedEnumResult<E>& r) \ |
|
76 { \ |
|
77 return ReturnType(e Op E(r)); \ |
|
78 } \ |
|
79 template<typename E> \ |
|
80 MOZ_CONSTEXPR ReturnType \ |
|
81 operator Op(const CastableTypedEnumResult<E>& r, typename E::Enum e) \ |
|
82 { \ |
|
83 return ReturnType(E(r) Op e); \ |
|
84 } |
|
85 |
|
86 MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(|, CastableTypedEnumResult<E>) |
|
87 MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(&, CastableTypedEnumResult<E>) |
|
88 MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(^, CastableTypedEnumResult<E>) |
|
89 MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(==, bool) |
|
90 MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11(!=, bool) |
|
91 |
|
92 #undef MOZ_CASTABLETYPEDENUMRESULT_BINOP_EXTRA_NON_CXX11 |
|
93 |
|
94 #endif // not MOZ_HAVE_CXX11_STRONG_ENUMS |
|
95 |
|
96 namespace detail { |
|
97 template<typename E> |
|
98 struct UnsignedIntegerTypeForEnum |
|
99 : UnsignedStdintTypeForSize<sizeof(E)> |
|
100 {}; |
|
101 } |
|
102 |
|
103 } // namespace mozilla |
|
104 |
|
105 #define MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, Op) \ |
|
106 inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \ |
|
107 operator Op(Name a, Name b) \ |
|
108 { \ |
|
109 typedef mozilla::CastableTypedEnumResult<Name> Result; \ |
|
110 typedef mozilla::detail::UnsignedIntegerTypeForEnum<Name>::Type U; \ |
|
111 return Result(Name(U(a) Op U(b))); \ |
|
112 } \ |
|
113 \ |
|
114 inline Name& \ |
|
115 operator Op##=(Name& a, Name b) \ |
|
116 { \ |
|
117 return a = a Op b; \ |
|
118 } |
|
119 |
|
120 #define MOZ_MAKE_ENUM_CLASS_OPS_IMPL(Name) \ |
|
121 MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, |) \ |
|
122 MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, &) \ |
|
123 MOZ_MAKE_ENUM_CLASS_BINOP_IMPL(Name, ^) \ |
|
124 inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \ |
|
125 operator~(Name a) \ |
|
126 { \ |
|
127 typedef mozilla::CastableTypedEnumResult<Name> Result; \ |
|
128 typedef mozilla::detail::UnsignedIntegerTypeForEnum<Name>::Type U; \ |
|
129 return Result(Name(~(U(a)))); \ |
|
130 } |
|
131 |
|
132 #ifndef MOZ_HAVE_CXX11_STRONG_ENUMS |
|
133 # define MOZ_MAKE_ENUM_CLASS_BITWISE_BINOP_EXTRA_NON_CXX11(Name, Op) \ |
|
134 inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \ |
|
135 operator Op(Name a, Name::Enum b) \ |
|
136 { \ |
|
137 return a Op Name(b); \ |
|
138 } \ |
|
139 \ |
|
140 inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \ |
|
141 operator Op(Name::Enum a, Name b) \ |
|
142 { \ |
|
143 return Name(a) Op b; \ |
|
144 } \ |
|
145 \ |
|
146 inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \ |
|
147 operator Op(Name::Enum a, Name::Enum b) \ |
|
148 { \ |
|
149 return Name(a) Op Name(b); \ |
|
150 } \ |
|
151 \ |
|
152 inline Name& \ |
|
153 operator Op##=(Name& a, Name::Enum b) \ |
|
154 { \ |
|
155 return a = a Op Name(b); \ |
|
156 } |
|
157 |
|
158 # define MOZ_MAKE_ENUM_CLASS_OPS_EXTRA_NON_CXX11(Name) \ |
|
159 MOZ_MAKE_ENUM_CLASS_BITWISE_BINOP_EXTRA_NON_CXX11(Name, |) \ |
|
160 MOZ_MAKE_ENUM_CLASS_BITWISE_BINOP_EXTRA_NON_CXX11(Name, &) \ |
|
161 MOZ_MAKE_ENUM_CLASS_BITWISE_BINOP_EXTRA_NON_CXX11(Name, ^) \ |
|
162 inline MOZ_CONSTEXPR mozilla::CastableTypedEnumResult<Name> \ |
|
163 operator~(Name::Enum a) \ |
|
164 { \ |
|
165 return ~(Name(a)); \ |
|
166 } |
|
167 #endif |
|
168 |
|
169 /** |
|
170 * MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS generates standard bitwise operators |
|
171 * for the given enum type. Use this to enable using an enum type as bit-field. |
|
172 */ |
|
173 #ifdef MOZ_HAVE_CXX11_STRONG_ENUMS |
|
174 # define MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Name) \ |
|
175 MOZ_MAKE_ENUM_CLASS_OPS_IMPL(Name) |
|
176 #else |
|
177 # define MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Name) \ |
|
178 MOZ_MAKE_ENUM_CLASS_OPS_IMPL(Name) \ |
|
179 MOZ_MAKE_ENUM_CLASS_OPS_EXTRA_NON_CXX11(Name) |
|
180 #endif |
|
181 |
|
182 #endif // mozilla_TypedEnumBits_h |