Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/detail/scoped_enum_emulation.hpp @ 101:c530137014c0
Update Boost headers (1.58.0)
author | Chris Cannam |
---|---|
date | Mon, 07 Sep 2015 11:12:49 +0100 |
parents | 2665513ce2d3 |
children |
comparison
equal
deleted
inserted
replaced
100:793467b5e61c | 101:c530137014c0 |
---|---|
1 // scoped_enum_emulation.hpp ---------------------------------------------------------// | 1 /* |
2 * Copyright (c) 2014 Andrey Semashev | |
3 * | |
4 * Distributed under the Boost Software License, Version 1.0. (See | |
5 * accompanying file LICENSE_1_0.txt or copy at | |
6 * http://www.boost.org/LICENSE_1_0.txt) | |
7 */ | |
2 | 8 |
3 // Copyright Beman Dawes, 2009 | 9 #ifndef BOOST_DETAIL_SCOPED_ENUM_EMULATION_HPP |
4 // Copyright (C) 2011-2012 Vicente J. Botet Escriba | 10 #define BOOST_DETAIL_SCOPED_ENUM_EMULATION_HPP |
5 // Copyright (C) 2012 Anthony Williams | |
6 | 11 |
7 // Distributed under the Boost Software License, Version 1.0. | 12 // The header file at this path is deprecated; |
8 // See http://www.boost.org/LICENSE_1_0.txt | 13 // use boost/core/scoped_enum.hpp instead. |
9 | 14 |
10 /* | 15 #include <boost/core/scoped_enum.hpp> |
11 [section:scoped_enums Scoped Enums] | |
12 | |
13 Generates C++0x scoped enums if the feature is present, otherwise emulates C++0x | |
14 scoped enums with C++03 namespaces and enums. The Boost.Config BOOST_NO_CXX11_SCOPED_ENUMS | |
15 macro is used to detect feature support. | |
16 | |
17 See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf for a | |
18 description of the scoped enum feature. Note that the committee changed the name | |
19 from strongly typed enum to scoped enum. | |
20 | |
21 Some of the enumerations defined in the standard library are scoped enums. | |
22 | |
23 enum class future_errc | |
24 { | |
25 broken_promise, | |
26 future_already_retrieved, | |
27 promise_already_satisfied, | |
28 no_state | |
29 }; | |
30 | |
31 On compilers that don't support them, the library provides two emulations: | |
32 | |
33 [heading Strict] | |
34 | |
35 * Able to specify the underlying type. | |
36 * explicit conversion to/from underlying type. | |
37 * The wrapper is not a C++03 enum type. | |
38 | |
39 The user can declare declare these types as | |
40 | |
41 BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_errc) | |
42 { | |
43 broken_promise, | |
44 future_already_retrieved, | |
45 promise_already_satisfied, | |
46 no_state | |
47 } | |
48 BOOST_SCOPED_ENUM_DECLARE_END(future_errc) | |
49 | |
50 These macros allows to use 'future_errc' in almost all the cases as an scoped enum. | |
51 | |
52 future_errc err = future_errc::no_state; | |
53 | |
54 There are however some limitations: | |
55 | |
56 * The type is not a C++ enum, so 'is_enum<future_errc>' will be false_type. | |
57 * The emulated scoped enum can not be used in switch nor in template arguments. For these cases the user needs to use some macros. | |
58 | |
59 Instead of | |
60 | |
61 switch (ev) | |
62 { | |
63 case future_errc::broken_promise: | |
64 // ... | |
65 | |
66 use | |
67 | |
68 switch (boost::native_value(ev)) | |
69 { | |
70 case future_errc::broken_promise: | |
71 | |
72 And instead of | |
73 | |
74 #ifdef BOOST_NO_CXX11_SCOPED_ENUMS | |
75 template <> | |
76 struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc> : public true_type { }; | |
77 #endif | |
78 | |
79 use | |
80 | |
81 #ifdef BOOST_NO_CXX11_SCOPED_ENUMS | |
82 template <> | |
83 struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc::enum_type > : public true_type { }; | |
84 #endif | |
85 | |
86 | |
87 Sample usage: | |
88 | |
89 BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(algae, char) { green, red, cyan }; BOOST_SCOPED_ENUM_DECLARE_END(algae) | |
90 ... | |
91 algae sample( algae::red ); | |
92 void foo( algae color ); | |
93 ... | |
94 sample = algae::green; | |
95 foo( algae::cyan ); | |
96 | |
97 Light | |
98 Caution: only the syntax is emulated; the semantics are not emulated and | |
99 the syntax emulation doesn't include being able to specify the underlying | |
100 representation type. | |
101 | |
102 The literal scoped emulation is via struct rather than namespace to allow use within classes. | |
103 Thanks to Andrey Semashev for pointing that out. | |
104 However the type is an real C++03 enum and so convertible implicitly to an int. | |
105 | |
106 Sample usage: | |
107 | |
108 BOOST_SCOPED_ENUM_START(algae) { green, red, cyan }; BOOST_SCOPED_ENUM_END | |
109 ... | |
110 BOOST_SCOPED_ENUM(algae) sample( algae::red ); | |
111 void foo( BOOST_SCOPED_ENUM(algae) color ); | |
112 ... | |
113 sample = algae::green; | |
114 foo( algae::cyan ); | |
115 | |
116 Helpful comments and suggestions were also made by Kjell Elster, Phil Endecott, | |
117 Joel Falcou, Mathias Gaunard, Felipe Magno de Almeida, Matt Calabrese, Vicente | |
118 Botet, and Daniel James. | |
119 | |
120 [endsect] | |
121 */ | |
122 | |
123 | |
124 #ifndef BOOST_SCOPED_ENUM_EMULATION_HPP | |
125 #define BOOST_SCOPED_ENUM_EMULATION_HPP | |
126 | |
127 #include <boost/config.hpp> | |
128 #include <boost/detail/workaround.hpp> | |
129 | |
130 namespace boost | |
131 { | |
132 | |
133 #ifdef BOOST_NO_CXX11_SCOPED_ENUMS | |
134 /** | |
135 * Meta-function to get the underlying type of a scoped enum. | |
136 * | |
137 * Requires EnumType must be an enum type or the emulation of a scoped enum | |
138 */ | |
139 template <typename EnumType> | |
140 struct underlying_type | |
141 { | |
142 /** | |
143 * The member typedef type names the underlying type of EnumType. It is EnumType::underlying_type when the EnumType is an emulated scoped enum, | |
144 * std::underlying_type<EnumType>::type when the standard library std::underlying_type is provided. | |
145 * | |
146 * The user will need to specialize it when the compiler supports scoped enums but don't provides std::underlying_type. | |
147 */ | |
148 typedef typename EnumType::underlying_type type; | |
149 }; | |
150 | |
151 /** | |
152 * Meta-function to get the native enum type associated to an enum class or its emulation. | |
153 */ | |
154 template <typename EnumType> | |
155 struct native_type | |
156 { | |
157 /** | |
158 * The member typedef type names the native enum type associated to the scoped enum, | |
159 * which is it self if the compiler supports scoped enums or EnumType::enum_type if it is an emulated scoped enum. | |
160 */ | |
161 typedef typename EnumType::enum_type type; | |
162 }; | |
163 | |
164 /** | |
165 * Casts a scoped enum to its underlying type. | |
166 * | |
167 * This function is useful when working with scoped enum classes, which doens't implicitly convert to the underlying type. | |
168 * @param v A scoped enum. | |
169 * @returns The underlying type. | |
170 * @throws No-throws. | |
171 */ | |
172 template <typename UnderlyingType, typename EnumType> | |
173 UnderlyingType underlying_cast(EnumType v) | |
174 { | |
175 return v.get_underlying_value_(); | |
176 } | |
177 | |
178 /** | |
179 * Casts a scoped enum to its native enum type. | |
180 * | |
181 * This function is useful to make programs portable when the scoped enum emulation can not be use where native enums can. | |
182 * | |
183 * EnumType the scoped enum type | |
184 * | |
185 * @param v A scoped enum. | |
186 * @returns The native enum value. | |
187 * @throws No-throws. | |
188 */ | |
189 template <typename EnumType> | |
190 inline | |
191 typename EnumType::enum_type native_value(EnumType e) | |
192 { | |
193 return e.native_value_(); | |
194 } | |
195 | |
196 #else // BOOST_NO_CXX11_SCOPED_ENUMS | |
197 | |
198 template <typename EnumType> | |
199 struct underlying_type | |
200 { | |
201 //typedef typename std::underlying_type<EnumType>::type type; | |
202 }; | |
203 | |
204 template <typename EnumType> | |
205 struct native_type | |
206 { | |
207 typedef EnumType type; | |
208 }; | |
209 | |
210 template <typename UnderlyingType, typename EnumType> | |
211 UnderlyingType underlying_cast(EnumType v) | |
212 { | |
213 return static_cast<UnderlyingType>(v); | |
214 } | |
215 | |
216 template <typename EnumType> | |
217 inline | |
218 EnumType native_value(EnumType e) | |
219 { | |
220 return e; | |
221 } | |
222 | 16 |
223 #endif | 17 #endif |
224 } | |
225 | |
226 | |
227 #ifdef BOOST_NO_CXX11_SCOPED_ENUMS | |
228 | |
229 #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS | |
230 | |
231 #define BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR \ | |
232 explicit operator underlying_type() const { return get_underlying_value_(); } | |
233 | |
234 #else | |
235 | |
236 #define BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR | |
237 | |
238 #endif | |
239 | |
240 /** | |
241 * Start a declaration of a scoped enum. | |
242 * | |
243 * @param EnumType The new scoped enum. | |
244 * @param UnderlyingType The underlying type. | |
245 */ | |
246 #define BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType, UnderlyingType) \ | |
247 struct EnumType { \ | |
248 typedef UnderlyingType underlying_type; \ | |
249 EnumType() BOOST_NOEXCEPT {} \ | |
250 explicit EnumType(underlying_type v) : v_(v) {} \ | |
251 underlying_type get_underlying_value_() const { return v_; } \ | |
252 BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR \ | |
253 private: \ | |
254 underlying_type v_; \ | |
255 typedef EnumType self_type; \ | |
256 public: \ | |
257 enum enum_type | |
258 | |
259 #define BOOST_SCOPED_ENUM_DECLARE_END2() \ | |
260 enum_type get_native_value_() const BOOST_NOEXCEPT { return enum_type(v_); } \ | |
261 operator enum_type() const BOOST_NOEXCEPT { return get_native_value_(); } \ | |
262 friend bool operator ==(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)==enum_type(rhs.v_); } \ | |
263 friend bool operator ==(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)==rhs; } \ | |
264 friend bool operator ==(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs==enum_type(rhs.v_); } \ | |
265 friend bool operator !=(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)!=enum_type(rhs.v_); } \ | |
266 friend bool operator !=(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)!=rhs; } \ | |
267 friend bool operator !=(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs!=enum_type(rhs.v_); } \ | |
268 friend bool operator <(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<enum_type(rhs.v_); } \ | |
269 friend bool operator <(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<rhs; } \ | |
270 friend bool operator <(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs<enum_type(rhs.v_); } \ | |
271 friend bool operator <=(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<=enum_type(rhs.v_); } \ | |
272 friend bool operator <=(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<=rhs; } \ | |
273 friend bool operator <=(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs<=enum_type(rhs.v_); } \ | |
274 friend bool operator >(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>enum_type(rhs.v_); } \ | |
275 friend bool operator >(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>rhs; } \ | |
276 friend bool operator >(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs>enum_type(rhs.v_); } \ | |
277 friend bool operator >=(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>=enum_type(rhs.v_); } \ | |
278 friend bool operator >=(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>=rhs; } \ | |
279 friend bool operator >=(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs>=enum_type(rhs.v_); } \ | |
280 }; | |
281 | |
282 #define BOOST_SCOPED_ENUM_DECLARE_END(EnumType) \ | |
283 ; \ | |
284 EnumType(enum_type v) BOOST_NOEXCEPT : v_(v) {} \ | |
285 BOOST_SCOPED_ENUM_DECLARE_END2() | |
286 | |
287 /** | |
288 * Starts a declaration of a scoped enum with the default int underlying type. | |
289 * | |
290 * @param EnumType The new scoped enum. | |
291 */ | |
292 #define BOOST_SCOPED_ENUM_DECLARE_BEGIN(EnumType) \ | |
293 BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType,int) | |
294 | |
295 /** | |
296 * Name of the native enum type. | |
297 * | |
298 * @param NT The new scoped enum. | |
299 */ | |
300 #define BOOST_SCOPED_ENUM_NATIVE(EnumType) EnumType::enum_type | |
301 /** | |
302 * Forward declares an scoped enum. | |
303 * | |
304 * @param NT The scoped enum. | |
305 */ | |
306 #define BOOST_SCOPED_ENUM_FORWARD_DECLARE(EnumType) struct EnumType | |
307 | |
308 #else // BOOST_NO_CXX11_SCOPED_ENUMS | |
309 | |
310 #define BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType,UnderlyingType) enum class EnumType:UnderlyingType | |
311 #define BOOST_SCOPED_ENUM_DECLARE_BEGIN(EnumType) enum class EnumType | |
312 #define BOOST_SCOPED_ENUM_DECLARE_END2() | |
313 #define BOOST_SCOPED_ENUM_DECLARE_END(EnumType) ; | |
314 | |
315 #define BOOST_SCOPED_ENUM_NATIVE(EnumType) EnumType | |
316 #define BOOST_SCOPED_ENUM_FORWARD_DECLARE(EnumType) enum class EnumType | |
317 | |
318 #endif // BOOST_NO_CXX11_SCOPED_ENUMS | |
319 | |
320 #define BOOST_SCOPED_ENUM_START(name) BOOST_SCOPED_ENUM_DECLARE_BEGIN(name) | |
321 #define BOOST_SCOPED_ENUM_END BOOST_SCOPED_ENUM_DECLARE_END2() | |
322 #define BOOST_SCOPED_ENUM(name) BOOST_SCOPED_ENUM_NATIVE(name) | |
323 | |
324 //#ifdef BOOST_NO_CXX11_SCOPED_ENUMS | |
325 // | |
326 //# define BOOST_SCOPED_ENUM_START(name) struct name { enum enum_type | |
327 //# define BOOST_SCOPED_ENUM_END }; | |
328 //# define BOOST_SCOPED_ENUM(name) name::enum_type | |
329 // | |
330 //#else | |
331 // | |
332 //# define BOOST_SCOPED_ENUM_START(name) enum class name | |
333 //# define BOOST_SCOPED_ENUM_END | |
334 //# define BOOST_SCOPED_ENUM(name) name | |
335 // | |
336 //#endif | |
337 #endif // BOOST_SCOPED_ENUM_EMULATION_HPP |