|
8 | 8 | #ifndef ADOBE_ENUM_OPS_HPP |
9 | 9 | #define ADOBE_ENUM_OPS_HPP |
10 | 10 |
|
11 | | -/**************************************************************************************************/ |
12 | | - |
13 | | -#include <type_traits> |
14 | | - |
15 | | -/**************************************************************************************************/ |
16 | | - |
17 | | -/*! |
18 | | - \defgroup enum_ops Typesafe Integers and Bit Fields (enums) |
19 | | - \ingroup utility |
20 | | -
|
21 | | - \section Description Description |
22 | | -
|
23 | | - \c enum_ops provides optional typesafe bitset and arithmetic operations for enumeration types. |
24 | | - Without these typesafe operations, the compiler will promote the operand(s) to the appropriate |
25 | | - integral type, and the result will be an integral type. When the typesafe operations have been |
26 | | - defined for an enumeration type, \c E, the result will be of type \c E exactly when the |
27 | | - operand(s) are of type \c E. |
28 | | -
|
29 | | - \c ADOBE_DEFINE_BITSET_OPS(E) or auto adobe_enable_bitmask_enum(E) -> std::true_type; |
30 | | - enables the bitset operations <code>~, |, &, ^, |=, &=, ^= </code> |
31 | | - for enumeration type \c E. |
32 | | -
|
33 | | - \c ADOBE_DEFINE_ARITHMETIC_OPS(E) or auto adobe_enable_arithmetic_enum(E) -> std::true_type; |
34 | | - enables the typesafe arithmetic operations <code>+, -, *, /, |
35 | | - %, +=, *=, -=, /=, \%=</code> for enumeration type \c E. |
36 | | -
|
37 | | - \section Definition Definition |
38 | | -
|
39 | | - Defined in \link enum_ops.hpp <code>adobe/enum_ops.hpp</code> \endlink |
40 | | -
|
41 | | - \section Example Example |
42 | | -
|
43 | | - The following is an example of code that will compile: |
44 | | - \dontinclude enum_ops_example.cpp |
45 | | - \skip start_of_example |
46 | | - \until end_of_example |
47 | | -
|
48 | | - The following is contains an example of code that will not compile |
49 | | - since the typesafe operators have not been defined. |
50 | | -
|
51 | | - \dontinclude enum_ops_example_fail.cpp |
52 | | - \skip start_of_example |
53 | | - \until end_of_example |
54 | | -*/ |
55 | | - |
56 | | -/**************************************************************************************************/ |
57 | | - |
58 | | -namespace adobe { |
59 | | - |
60 | | -/**************************************************************************************************/ |
61 | | - |
62 | | -auto adobe_enable_bitmask_enum(...) -> std::false_type; |
63 | | -auto adobe_enable_arithmetic_enum(...) -> std::false_type; |
| 11 | +#include <stlab/enum_ops.hpp> |
64 | 12 |
|
65 | 13 | /**************************************************************************************************/ |
66 | 14 |
|
67 | | -namespace implementation { |
| 15 | +/// \file enum_ops.hpp |
| 16 | +/// \brief Bitwise and arithmetic operator helpers for enums. |
| 17 | +/// \ingroup utility |
68 | 18 |
|
69 | 19 | /**************************************************************************************************/ |
70 | 20 |
|
71 | | -#if !defined(ADOBE_NO_DOCUMENTATION) |
72 | | -template <typename T> |
73 | | -constexpr bool has_enabled_bitmask = decltype(adobe_enable_bitmask_enum(std::declval<T>()))::value; |
74 | | -template <typename T> |
75 | | -constexpr bool has_enabled_arithmetic = |
76 | | - decltype(adobe_enable_arithmetic_enum(std::declval<T>()))::value; |
77 | | -#endif |
78 | | - |
79 | | -/**************************************************************************************************/ |
80 | | - |
81 | | -} // namespace implementation |
82 | | - |
83 | | -/**************************************************************************************************/ |
| 21 | +/// \deprecated Use stlab_enable_bitmask_enum instead. |
| 22 | +#define ADOBE_DEFINE_BITSET_OPS(EnumType) auto stlab_enable_bitmask_enum(EnumType)->std::true_type; |
84 | 23 |
|
85 | | -} // namespace adobe |
86 | | - |
87 | | -/**************************************************************************************************/ |
88 | | - |
89 | | -// this exist to mantain backwards compatability with the old ops |
90 | | -#define ADOBE_DEFINE_BITSET_OPS(EnumType) \ |
91 | | - constexpr auto adobe_enable_bitmask_enum(EnumType)->std::true_type; |
92 | | - |
93 | | - |
94 | | -template <typename T> |
95 | | -constexpr auto operator&(const T lhs, const T rhs) |
96 | | - -> std::enable_if_t<adobe::implementation::has_enabled_bitmask<T>, T> { |
97 | | - using underlying = std::underlying_type_t<T>; |
98 | | - return static_cast<T>(static_cast<underlying>(lhs) & static_cast<underlying>(rhs)); // NOLINT |
99 | | -} |
100 | | - |
101 | | -template <typename T> |
102 | | -constexpr auto operator~(const T a) |
103 | | - -> std::enable_if_t<adobe::implementation::has_enabled_bitmask<T>, T> { |
104 | | - using underlying = std::underlying_type_t<T>; |
105 | | - return static_cast<T>(~static_cast<underlying>(a)); // NOLINT |
106 | | -} |
107 | | - |
108 | | -template <typename T> |
109 | | -constexpr auto operator|(const T lhs, const T rhs) |
110 | | - -> std::enable_if_t<adobe::implementation::has_enabled_bitmask<T>, T> { |
111 | | - using underlying = std::underlying_type_t<T>; |
112 | | - return static_cast<T>(static_cast<underlying>(lhs) | static_cast<underlying>(rhs)); // NOLINT |
113 | | -} |
114 | | - |
115 | | -template <typename T> |
116 | | -constexpr auto operator^(const T lhs, const T rhs) |
117 | | - -> std::enable_if_t<adobe::implementation::has_enabled_bitmask<T>, T> { |
118 | | - using underlying = std::underlying_type_t<T>; |
119 | | - return static_cast<T>(static_cast<underlying>(lhs) ^ static_cast<underlying>(rhs)); // NOLINT |
120 | | -} |
121 | | - |
122 | | -template <typename T> |
123 | | -constexpr auto operator^=(T& lhs, const T rhs) |
124 | | - -> std::enable_if_t<adobe::implementation::has_enabled_bitmask<T>, T> { |
125 | | - return lhs = lhs ^ rhs; |
126 | | -} |
127 | | - |
128 | | -template <typename T> |
129 | | -constexpr auto operator&=(T& lhs, const T rhs) |
130 | | - -> std::enable_if_t<adobe::implementation::has_enabled_bitmask<T>, T> { |
131 | | - return lhs = lhs & rhs; |
132 | | -} |
133 | | - |
134 | | -template <typename T> |
135 | | -constexpr auto operator|=(T& lhs, const T rhs) |
136 | | - -> std::enable_if_t<adobe::implementation::has_enabled_bitmask<T>, T> { |
137 | | - return lhs = lhs | rhs; |
138 | | -} |
139 | | - |
140 | | -// this exist to mantain backwards compatability with the old ops |
| 24 | +/// \deprecated Use stlab_enable_arithmetic_enum instead. |
141 | 25 | #define ADOBE_DEFINE_ARITHMETIC_OPS(EnumType) \ |
142 | | - constexpr auto adobe_enable_arithmetic_enum(EnumType)->std::true_type; |
143 | | -template <typename T> |
144 | | -constexpr auto operator+(const T a) |
145 | | - -> std::enable_if_t<adobe::implementation::has_enabled_arithmetic<T>, T> { |
146 | | - using underlying = std::underlying_type_t<T>; |
147 | | - return static_cast<T>(+static_cast<underlying>(a)); // NOLINT |
148 | | -} |
149 | | - |
150 | | -template <typename T> |
151 | | -constexpr auto operator-(const T a) |
152 | | - -> std::enable_if_t<adobe::implementation::has_enabled_arithmetic<T>, T> { |
153 | | - using underlying = std::underlying_type_t<T>; |
154 | | - return static_cast<T>(-static_cast<underlying>(a)); // NOLINT |
155 | | -} |
156 | | - |
157 | | -template <typename T> |
158 | | -constexpr auto operator+(const T lhs, const T rhs) |
159 | | - -> std::enable_if_t<adobe::implementation::has_enabled_arithmetic<T>, T> { |
160 | | - using underlying = std::underlying_type_t<T>; |
161 | | - return static_cast<T>(static_cast<underlying>(lhs) + static_cast<underlying>(rhs)); // NOLINT |
162 | | -} |
163 | | - |
164 | | -template <typename T> |
165 | | -constexpr auto operator-(const T lhs, const T rhs) |
166 | | - -> std::enable_if_t<adobe::implementation::has_enabled_arithmetic<T>, T> { |
167 | | - using underlying = std::underlying_type_t<T>; |
168 | | - return static_cast<T>(static_cast<underlying>(lhs) - static_cast<underlying>(rhs)); // NOLINT |
169 | | -} |
170 | | - |
171 | | -template <typename T> |
172 | | -constexpr auto operator*(const T lhs, const T rhs) |
173 | | - -> std::enable_if_t<adobe::implementation::has_enabled_arithmetic<T>, T> { |
174 | | - using underlying = std::underlying_type_t<T>; |
175 | | - return static_cast<T>(static_cast<underlying>(lhs) * static_cast<underlying>(rhs)); // NOLINT |
176 | | -} |
177 | | - |
178 | | -template <typename T> |
179 | | -constexpr auto operator/(const T lhs, const T rhs) |
180 | | - -> std::enable_if_t<adobe::implementation::has_enabled_arithmetic<T>, T> { |
181 | | - using underlying = std::underlying_type_t<T>; |
182 | | - return static_cast<T>(static_cast<underlying>(lhs) / static_cast<underlying>(rhs)); // NOLINT |
183 | | -} |
184 | | - |
185 | | -template <typename T> |
186 | | -constexpr auto operator%(const T lhs, const T rhs) |
187 | | - -> std::enable_if_t<adobe::implementation::has_enabled_arithmetic<T>, T> { |
188 | | - using underlying = std::underlying_type_t<T>; |
189 | | - return static_cast<T>(static_cast<underlying>(lhs) % static_cast<underlying>(rhs)); // NOLINT |
190 | | -} |
191 | | - |
192 | | -template <typename T> |
193 | | -constexpr auto operator+=(T& lhs, const T rhs) |
194 | | - -> std::enable_if_t<adobe::implementation::has_enabled_arithmetic<T>, T> { |
195 | | - return lhs = lhs + rhs; |
196 | | -} |
197 | | - |
198 | | -template <typename T> |
199 | | -constexpr auto operator-=(T& lhs, const T rhs) |
200 | | - -> std::enable_if_t<adobe::implementation::has_enabled_arithmetic<T>, T> { |
201 | | - return lhs = lhs - rhs; |
202 | | -} |
203 | | - |
204 | | -template <typename T> |
205 | | -constexpr auto operator*=(T& lhs, const T rhs) |
206 | | - -> std::enable_if_t<adobe::implementation::has_enabled_arithmetic<T>, T> { |
207 | | - return lhs = lhs * rhs; |
208 | | -} |
209 | | - |
210 | | -template <typename T> |
211 | | -constexpr auto operator/=(T& lhs, const T rhs) |
212 | | - -> std::enable_if_t<adobe::implementation::has_enabled_arithmetic<T>, T> { |
213 | | - return lhs = lhs / rhs; |
214 | | -} |
215 | | - |
216 | | -template <typename T> |
217 | | -constexpr auto operator%=(T& lhs, const T rhs) |
218 | | - -> std::enable_if_t<adobe::implementation::has_enabled_arithmetic<T>, T> { |
219 | | - return lhs = lhs % rhs; |
220 | | -} |
221 | | - |
222 | | -template <typename T> |
223 | | -constexpr auto operator++(T& lhs) |
224 | | - -> std::enable_if_t<adobe::implementation::has_enabled_arithmetic<T>, T> { |
225 | | - return lhs += static_cast<T>(1); // NOLINT |
226 | | -} |
227 | | - |
228 | | -template <typename T> |
229 | | -constexpr auto operator++(T& lhs, int) |
230 | | - -> std::enable_if_t<adobe::implementation::has_enabled_arithmetic<T>, T> { |
231 | | - T result = lhs; |
232 | | - lhs += static_cast<T>(1); // NOLINT |
233 | | - return result; |
234 | | -} |
235 | | - |
236 | | -template <typename T> |
237 | | -constexpr auto operator--(T& lhs) |
238 | | - -> std::enable_if_t<adobe::implementation::has_enabled_arithmetic<T>, T> { |
239 | | - return lhs -= static_cast<T>(1); // NOLINT |
240 | | -} |
241 | | - |
242 | | -template <typename T> |
243 | | -constexpr auto operator--(T& lhs, int) |
244 | | - -> std::enable_if_t<adobe::implementation::has_enabled_arithmetic<T>, T> { |
245 | | - T result = lhs; |
246 | | - lhs -= static_cast<T>(1); // NOLINT |
247 | | - return result; |
248 | | -} |
| 26 | + auto stlab_enable_arithmetic_enum(EnumType)->std::true_type; |
249 | 27 |
|
250 | 28 | /**************************************************************************************************/ |
251 | 29 |
|
|
0 commit comments