annotate DEPENDENCIES/generic/include/boost/detail/scoped_enum_emulation.hpp @ 16:2665513ce2d3

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