6 #ifndef BETTER_ENUMS_ENUM_H 7 #define BETTER_ENUMS_ENUM_H 21 # define BETTER_ENUMS_IGNORE_OLD_CAST_HEADER _Pragma("clang diagnostic push") 22 # define BETTER_ENUMS_IGNORE_OLD_CAST_BEGIN _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") 23 # define BETTER_ENUMS_IGNORE_OLD_CAST_END _Pragma("clang diagnostic pop") 25 # define BETTER_ENUMS_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) 26 # if BETTER_ENUMS_GCC_VERSION > 40400 27 # define BETTER_ENUMS_IGNORE_OLD_CAST_HEADER _Pragma("GCC diagnostic push") 28 # define BETTER_ENUMS_IGNORE_OLD_CAST_BEGIN _Pragma("GCC diagnostic ignored \"-Wold-style-cast\"") 29 # define BETTER_ENUMS_IGNORE_OLD_CAST_END _Pragma("GCC diagnostic pop") 30 # if (BETTER_ENUMS_GCC_VERSION >= 70300) 31 # define BETTER_ENUMS_IGNORE_ATTRIBUTES_HEADER _Pragma("GCC diagnostic push") 32 # define BETTER_ENUMS_IGNORE_ATTRIBUTES_BEGIN _Pragma("GCC diagnostic ignored \"-Wattributes\"") 33 # define BETTER_ENUMS_IGNORE_ATTRIBUTES_END _Pragma("GCC diagnostic pop") 35 # define BETTER_ENUMS_IGNORE_ATTRIBUTES_HEADER 36 # define BETTER_ENUMS_IGNORE_ATTRIBUTES_BEGIN 37 # define BETTER_ENUMS_IGNORE_ATTRIBUTES_END 40 # define BETTER_ENUMS_IGNORE_OLD_CAST_HEADER 41 # define BETTER_ENUMS_IGNORE_OLD_CAST_BEGIN 42 # define BETTER_ENUMS_IGNORE_OLD_CAST_END 43 # define BETTER_ENUMS_IGNORE_ATTRIBUTES_HEADER 44 # define BETTER_ENUMS_IGNORE_ATTRIBUTES_BEGIN 45 # define BETTER_ENUMS_IGNORE_ATTRIBUTES_END 48 #else // empty definitions for compilers that don't support _Pragma 49 # define BETTER_ENUMS_IGNORE_OLD_CAST_HEADER 50 # define BETTER_ENUMS_IGNORE_OLD_CAST_BEGIN 51 # define BETTER_ENUMS_IGNORE_OLD_CAST_END 52 # define BETTER_ENUMS_IGNORE_ATTRIBUTES_HEADER 53 # define BETTER_ENUMS_IGNORE_ATTRIBUTES_BEGIN 54 # define BETTER_ENUMS_IGNORE_ATTRIBUTES_END 61 # if __has_feature(cxx_constexpr) 62 # define BETTER_ENUMS_HAVE_CONSTEXPR 64 # if !defined(__EXCEPTIONS) || !__has_feature(cxx_exceptions) 65 # define BETTER_ENUMS_NO_EXCEPTIONS 68 # if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L 69 # if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) 70 # define BETTER_ENUMS_HAVE_CONSTEXPR 74 # define BETTER_ENUMS_NO_EXCEPTIONS 81 # define BETTER_ENUMS_HAVE_CONSTEXPR 84 # if __has_feature(cxx_constexpr) 85 # define BETTER_ENUMS_HAVE_CONSTEXPR 89 # define BETTER_ENUMS_NO_EXCEPTIONS 92 # define BETTER_ENUMS_VC2008_WORKAROUNDS 96 #ifdef BETTER_ENUMS_CONSTEXPR 97 # define BETTER_ENUMS_HAVE_CONSTEXPR 100 #ifdef BETTER_ENUMS_NO_CONSTEXPR 101 # ifdef BETTER_ENUMS_HAVE_CONSTEXPR 102 # undef BETTER_ENUMS_HAVE_CONSTEXPR 114 #ifdef BETTER_ENUMS_HAVE_CONSTEXPR 115 # define BETTER_ENUMS_CONSTEXPR_ constexpr 116 # define BETTER_ENUMS_NULLPTR nullptr 118 # define BETTER_ENUMS_CONSTEXPR_ 119 # define BETTER_ENUMS_NULLPTR NULL 122 #ifndef BETTER_ENUMS_NO_EXCEPTIONS 123 # define BETTER_ENUMS_IF_EXCEPTIONS(x) x 125 # define BETTER_ENUMS_IF_EXCEPTIONS(x) 129 # define BETTER_ENUMS_UNUSED __attribute__((__unused__)) 131 # define BETTER_ENUMS_UNUSED 138 #ifdef BETTER_ENUMS_MACRO_FILE 139 # include BETTER_ENUMS_MACRO_FILE 142 #define BETTER_ENUMS_PP_MAP(macro, data, ...) \ 144 BETTER_ENUMS_APPLY( \ 145 BETTER_ENUMS_PP_MAP_VAR_COUNT, \ 146 BETTER_ENUMS_PP_COUNT(__VA_ARGS__)) \ 147 (macro, data, __VA_ARGS__)) 149 #define BETTER_ENUMS_PP_MAP_VAR_COUNT(count) BETTER_ENUMS_M ## count 151 #define BETTER_ENUMS_APPLY(macro, ...) BETTER_ENUMS_ID(macro(__VA_ARGS__)) 153 #define BETTER_ENUMS_ID(x) x 155 #define BETTER_ENUMS_M1(m, d, x) m(d,0,x) 156 #define BETTER_ENUMS_M2(m,d,x,...) m(d,1,x) \ 157 BETTER_ENUMS_ID(BETTER_ENUMS_M1(m,d,__VA_ARGS__)) 158 #define BETTER_ENUMS_M3(m,d,x,...) m(d,2,x) \ 159 BETTER_ENUMS_ID(BETTER_ENUMS_M2(m,d,__VA_ARGS__)) 160 #define BETTER_ENUMS_M4(m,d,x,...) m(d,3,x) \ 161 BETTER_ENUMS_ID(BETTER_ENUMS_M3(m,d,__VA_ARGS__)) 162 #define BETTER_ENUMS_M5(m,d,x,...) m(d,4,x) \ 163 BETTER_ENUMS_ID(BETTER_ENUMS_M4(m,d,__VA_ARGS__)) 164 #define BETTER_ENUMS_M6(m,d,x,...) m(d,5,x) \ 165 BETTER_ENUMS_ID(BETTER_ENUMS_M5(m,d,__VA_ARGS__)) 166 #define BETTER_ENUMS_M7(m,d,x,...) m(d,6,x) \ 167 BETTER_ENUMS_ID(BETTER_ENUMS_M6(m,d,__VA_ARGS__)) 168 #define BETTER_ENUMS_M8(m,d,x,...) m(d,7,x) \ 169 BETTER_ENUMS_ID(BETTER_ENUMS_M7(m,d,__VA_ARGS__)) 170 #define BETTER_ENUMS_M9(m,d,x,...) m(d,8,x) \ 171 BETTER_ENUMS_ID(BETTER_ENUMS_M8(m,d,__VA_ARGS__)) 172 #define BETTER_ENUMS_M10(m,d,x,...) m(d,9,x) \ 173 BETTER_ENUMS_ID(BETTER_ENUMS_M9(m,d,__VA_ARGS__)) 174 #define BETTER_ENUMS_M11(m,d,x,...) m(d,10,x) \ 175 BETTER_ENUMS_ID(BETTER_ENUMS_M10(m,d,__VA_ARGS__)) 176 #define BETTER_ENUMS_M12(m,d,x,...) m(d,11,x) \ 177 BETTER_ENUMS_ID(BETTER_ENUMS_M11(m,d,__VA_ARGS__)) 178 #define BETTER_ENUMS_M13(m,d,x,...) m(d,12,x) \ 179 BETTER_ENUMS_ID(BETTER_ENUMS_M12(m,d,__VA_ARGS__)) 180 #define BETTER_ENUMS_M14(m,d,x,...) m(d,13,x) \ 181 BETTER_ENUMS_ID(BETTER_ENUMS_M13(m,d,__VA_ARGS__)) 182 #define BETTER_ENUMS_M15(m,d,x,...) m(d,14,x) \ 183 BETTER_ENUMS_ID(BETTER_ENUMS_M14(m,d,__VA_ARGS__)) 184 #define BETTER_ENUMS_M16(m,d,x,...) m(d,15,x) \ 185 BETTER_ENUMS_ID(BETTER_ENUMS_M15(m,d,__VA_ARGS__)) 186 #define BETTER_ENUMS_M17(m,d,x,...) m(d,16,x) \ 187 BETTER_ENUMS_ID(BETTER_ENUMS_M16(m,d,__VA_ARGS__)) 188 #define BETTER_ENUMS_M18(m,d,x,...) m(d,17,x) \ 189 BETTER_ENUMS_ID(BETTER_ENUMS_M17(m,d,__VA_ARGS__)) 190 #define BETTER_ENUMS_M19(m,d,x,...) m(d,18,x) \ 191 BETTER_ENUMS_ID(BETTER_ENUMS_M18(m,d,__VA_ARGS__)) 192 #define BETTER_ENUMS_M20(m,d,x,...) m(d,19,x) \ 193 BETTER_ENUMS_ID(BETTER_ENUMS_M19(m,d,__VA_ARGS__)) 194 #define BETTER_ENUMS_M21(m,d,x,...) m(d,20,x) \ 195 BETTER_ENUMS_ID(BETTER_ENUMS_M20(m,d,__VA_ARGS__)) 196 #define BETTER_ENUMS_M22(m,d,x,...) m(d,21,x) \ 197 BETTER_ENUMS_ID(BETTER_ENUMS_M21(m,d,__VA_ARGS__)) 198 #define BETTER_ENUMS_M23(m,d,x,...) m(d,22,x) \ 199 BETTER_ENUMS_ID(BETTER_ENUMS_M22(m,d,__VA_ARGS__)) 200 #define BETTER_ENUMS_M24(m,d,x,...) m(d,23,x) \ 201 BETTER_ENUMS_ID(BETTER_ENUMS_M23(m,d,__VA_ARGS__)) 202 #define BETTER_ENUMS_M25(m,d,x,...) m(d,24,x) \ 203 BETTER_ENUMS_ID(BETTER_ENUMS_M24(m,d,__VA_ARGS__)) 204 #define BETTER_ENUMS_M26(m,d,x,...) m(d,25,x) \ 205 BETTER_ENUMS_ID(BETTER_ENUMS_M25(m,d,__VA_ARGS__)) 206 #define BETTER_ENUMS_M27(m,d,x,...) m(d,26,x) \ 207 BETTER_ENUMS_ID(BETTER_ENUMS_M26(m,d,__VA_ARGS__)) 208 #define BETTER_ENUMS_M28(m,d,x,...) m(d,27,x) \ 209 BETTER_ENUMS_ID(BETTER_ENUMS_M27(m,d,__VA_ARGS__)) 210 #define BETTER_ENUMS_M29(m,d,x,...) m(d,28,x) \ 211 BETTER_ENUMS_ID(BETTER_ENUMS_M28(m,d,__VA_ARGS__)) 212 #define BETTER_ENUMS_M30(m,d,x,...) m(d,29,x) \ 213 BETTER_ENUMS_ID(BETTER_ENUMS_M29(m,d,__VA_ARGS__)) 214 #define BETTER_ENUMS_M31(m,d,x,...) m(d,30,x) \ 215 BETTER_ENUMS_ID(BETTER_ENUMS_M30(m,d,__VA_ARGS__)) 216 #define BETTER_ENUMS_M32(m,d,x,...) m(d,31,x) \ 217 BETTER_ENUMS_ID(BETTER_ENUMS_M31(m,d,__VA_ARGS__)) 218 #define BETTER_ENUMS_M33(m,d,x,...) m(d,32,x) \ 219 BETTER_ENUMS_ID(BETTER_ENUMS_M32(m,d,__VA_ARGS__)) 220 #define BETTER_ENUMS_M34(m,d,x,...) m(d,33,x) \ 221 BETTER_ENUMS_ID(BETTER_ENUMS_M33(m,d,__VA_ARGS__)) 222 #define BETTER_ENUMS_M35(m,d,x,...) m(d,34,x) \ 223 BETTER_ENUMS_ID(BETTER_ENUMS_M34(m,d,__VA_ARGS__)) 224 #define BETTER_ENUMS_M36(m,d,x,...) m(d,35,x) \ 225 BETTER_ENUMS_ID(BETTER_ENUMS_M35(m,d,__VA_ARGS__)) 226 #define BETTER_ENUMS_M37(m,d,x,...) m(d,36,x) \ 227 BETTER_ENUMS_ID(BETTER_ENUMS_M36(m,d,__VA_ARGS__)) 228 #define BETTER_ENUMS_M38(m,d,x,...) m(d,37,x) \ 229 BETTER_ENUMS_ID(BETTER_ENUMS_M37(m,d,__VA_ARGS__)) 230 #define BETTER_ENUMS_M39(m,d,x,...) m(d,38,x) \ 231 BETTER_ENUMS_ID(BETTER_ENUMS_M38(m,d,__VA_ARGS__)) 232 #define BETTER_ENUMS_M40(m,d,x,...) m(d,39,x) \ 233 BETTER_ENUMS_ID(BETTER_ENUMS_M39(m,d,__VA_ARGS__)) 234 #define BETTER_ENUMS_M41(m,d,x,...) m(d,40,x) \ 235 BETTER_ENUMS_ID(BETTER_ENUMS_M40(m,d,__VA_ARGS__)) 236 #define BETTER_ENUMS_M42(m,d,x,...) m(d,41,x) \ 237 BETTER_ENUMS_ID(BETTER_ENUMS_M41(m,d,__VA_ARGS__)) 238 #define BETTER_ENUMS_M43(m,d,x,...) m(d,42,x) \ 239 BETTER_ENUMS_ID(BETTER_ENUMS_M42(m,d,__VA_ARGS__)) 240 #define BETTER_ENUMS_M44(m,d,x,...) m(d,43,x) \ 241 BETTER_ENUMS_ID(BETTER_ENUMS_M43(m,d,__VA_ARGS__)) 242 #define BETTER_ENUMS_M45(m,d,x,...) m(d,44,x) \ 243 BETTER_ENUMS_ID(BETTER_ENUMS_M44(m,d,__VA_ARGS__)) 244 #define BETTER_ENUMS_M46(m,d,x,...) m(d,45,x) \ 245 BETTER_ENUMS_ID(BETTER_ENUMS_M45(m,d,__VA_ARGS__)) 246 #define BETTER_ENUMS_M47(m,d,x,...) m(d,46,x) \ 247 BETTER_ENUMS_ID(BETTER_ENUMS_M46(m,d,__VA_ARGS__)) 248 #define BETTER_ENUMS_M48(m,d,x,...) m(d,47,x) \ 249 BETTER_ENUMS_ID(BETTER_ENUMS_M47(m,d,__VA_ARGS__)) 250 #define BETTER_ENUMS_M49(m,d,x,...) m(d,48,x) \ 251 BETTER_ENUMS_ID(BETTER_ENUMS_M48(m,d,__VA_ARGS__)) 252 #define BETTER_ENUMS_M50(m,d,x,...) m(d,49,x) \ 253 BETTER_ENUMS_ID(BETTER_ENUMS_M49(m,d,__VA_ARGS__)) 254 #define BETTER_ENUMS_M51(m,d,x,...) m(d,50,x) \ 255 BETTER_ENUMS_ID(BETTER_ENUMS_M50(m,d,__VA_ARGS__)) 256 #define BETTER_ENUMS_M52(m,d,x,...) m(d,51,x) \ 257 BETTER_ENUMS_ID(BETTER_ENUMS_M51(m,d,__VA_ARGS__)) 258 #define BETTER_ENUMS_M53(m,d,x,...) m(d,52,x) \ 259 BETTER_ENUMS_ID(BETTER_ENUMS_M52(m,d,__VA_ARGS__)) 260 #define BETTER_ENUMS_M54(m,d,x,...) m(d,53,x) \ 261 BETTER_ENUMS_ID(BETTER_ENUMS_M53(m,d,__VA_ARGS__)) 262 #define BETTER_ENUMS_M55(m,d,x,...) m(d,54,x) \ 263 BETTER_ENUMS_ID(BETTER_ENUMS_M54(m,d,__VA_ARGS__)) 264 #define BETTER_ENUMS_M56(m,d,x,...) m(d,55,x) \ 265 BETTER_ENUMS_ID(BETTER_ENUMS_M55(m,d,__VA_ARGS__)) 266 #define BETTER_ENUMS_M57(m,d,x,...) m(d,56,x) \ 267 BETTER_ENUMS_ID(BETTER_ENUMS_M56(m,d,__VA_ARGS__)) 268 #define BETTER_ENUMS_M58(m,d,x,...) m(d,57,x) \ 269 BETTER_ENUMS_ID(BETTER_ENUMS_M57(m,d,__VA_ARGS__)) 270 #define BETTER_ENUMS_M59(m,d,x,...) m(d,58,x) \ 271 BETTER_ENUMS_ID(BETTER_ENUMS_M58(m,d,__VA_ARGS__)) 272 #define BETTER_ENUMS_M60(m,d,x,...) m(d,59,x) \ 273 BETTER_ENUMS_ID(BETTER_ENUMS_M59(m,d,__VA_ARGS__)) 274 #define BETTER_ENUMS_M61(m,d,x,...) m(d,60,x) \ 275 BETTER_ENUMS_ID(BETTER_ENUMS_M60(m,d,__VA_ARGS__)) 276 #define BETTER_ENUMS_M62(m,d,x,...) m(d,61,x) \ 277 BETTER_ENUMS_ID(BETTER_ENUMS_M61(m,d,__VA_ARGS__)) 278 #define BETTER_ENUMS_M63(m,d,x,...) m(d,62,x) \ 279 BETTER_ENUMS_ID(BETTER_ENUMS_M62(m,d,__VA_ARGS__)) 280 #define BETTER_ENUMS_M64(m,d,x,...) m(d,63,x) \ 281 BETTER_ENUMS_ID(BETTER_ENUMS_M63(m,d,__VA_ARGS__)) 283 #define BETTER_ENUMS_PP_COUNT_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \ 284 _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, \ 285 _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \ 286 _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, \ 287 _56, _57, _58, _59, _60, _61, _62, _63, _64, count, ...) count 289 #define BETTER_ENUMS_PP_COUNT(...) \ 290 BETTER_ENUMS_ID(BETTER_ENUMS_PP_COUNT_IMPL(__VA_ARGS__, 64, 63, 62, 61, 60,\ 291 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42,\ 292 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24,\ 293 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, \ 296 #define BETTER_ENUMS_ITERATE(X, f, l) X(f, l, 0) X(f, l, 1) X(f, l, 2) \ 297 X(f, l, 3) X(f, l, 4) X(f, l, 5) X(f, l, 6) X(f, l, 7) X(f, l, 8) \ 298 X(f, l, 9) X(f, l, 10) X(f, l, 11) X(f, l, 12) X(f, l, 13) X(f, l, 14) \ 299 X(f, l, 15) X(f, l, 16) X(f, l, 17) X(f, l, 18) X(f, l, 19) X(f, l, 20) \ 300 X(f, l, 21) X(f, l, 22) X(f, l, 23) 302 #endif // #ifdef BETTER_ENUMS_MACRO_FILE else case 311 template <
typename T>
312 BETTER_ENUMS_CONSTEXPR_
inline T _default()
314 return static_cast<typename T::_enumerated
>(0);
318 BETTER_ENUMS_CONSTEXPR_
inline const char* _default<const char*>()
320 return BETTER_ENUMS_NULLPTR;
324 BETTER_ENUMS_CONSTEXPR_
inline std::size_t _default<std::size_t>()
329 template <
typename T>
331 BETTER_ENUMS_CONSTEXPR_
optional() :
332 _valid(
false), _value(_default<T>()) { }
334 BETTER_ENUMS_CONSTEXPR_ optional(T v) : _valid(
true), _value(v) { }
336 BETTER_ENUMS_CONSTEXPR_
const T& operator *()
const {
return _value; }
337 BETTER_ENUMS_CONSTEXPR_
const T* operator ->()
const {
return &_value; }
339 BETTER_ENUMS_CONSTEXPR_
operator bool()
const {
return _valid; }
341 BETTER_ENUMS_CONSTEXPR_
const T& value()
const {
return _value; }
348 template <
typename CastTo,
typename Element>
355 #ifdef BETTER_ENUMS_VC2008_WORKAROUNDS 357 #define BETTER_ENUMS_OR_THROW \ 359 throw std::runtime_error(message); \ 365 #define BETTER_ENUMS_OR_THROW \ 366 return maybe ? *maybe : throw std::runtime_error(message); 370 BETTER_ENUMS_IF_EXCEPTIONS(
371 template <typename T>
372 BETTER_ENUMS_CONSTEXPR_
static T _or_throw(
optional<T> maybe,
375 BETTER_ENUMS_OR_THROW
379 template <typename T>
380 BETTER_ENUMS_CONSTEXPR_
static T* _or_null(
optional<T*> maybe)
382 return maybe ? *maybe : BETTER_ENUMS_NULLPTR;
385 template <
typename T>
386 BETTER_ENUMS_CONSTEXPR_
static T _or_zero(
optional<T> maybe)
388 return maybe ? *maybe : T::_from_integral_unchecked(0);
398 template <
typename T,
typename U>
399 BETTER_ENUMS_CONSTEXPR_ U
400 continue_with(T, U value) {
return value; }
407 template <
typename EnumType>
409 explicit BETTER_ENUMS_CONSTEXPR_
_eat_assign(EnumType value) : _value(value)
412 template <
typename Any>
413 BETTER_ENUMS_CONSTEXPR_
const _eat_assign&
414 operator =(Any)
const {
return *
this; }
416 BETTER_ENUMS_CONSTEXPR_
operator EnumType ()
const {
return _value; }
426 template <
typename Element>
428 typedef const Element* iterator;
430 BETTER_ENUMS_CONSTEXPR_ iterator begin()
const {
return iterator(_array); }
431 BETTER_ENUMS_CONSTEXPR_ iterator end()
const 432 {
return iterator(_array + _size); }
433 BETTER_ENUMS_CONSTEXPR_ std::size_t size()
const {
return _size; }
434 BETTER_ENUMS_CONSTEXPR_
const Element& operator [](std::size_t index)
const 435 {
return _array[index]; }
437 BETTER_ENUMS_CONSTEXPR_
_iterable(
const Element *array, std::size_t s) :
438 _array(array), _size(s) { }
441 const Element *
const _array;
442 const std::size_t _size;
449 BETTER_ENUMS_CONSTEXPR_
static const char *_name_enders =
"= \t\n";
451 BETTER_ENUMS_CONSTEXPR_
inline bool _ends_name(
char c, std::size_t index = 0)
454 c == _name_enders[index] ?
true :
455 _name_enders[index] ==
'\0' ?
false :
456 _ends_name(c, index + 1);
459 BETTER_ENUMS_CONSTEXPR_
inline bool _has_initializer(
const char *s,
460 std::size_t index = 0)
463 s[index] ==
'\0' ?
false :
464 s[index] ==
'=' ?
true :
465 _has_initializer(s, index + 1);
468 BETTER_ENUMS_CONSTEXPR_
inline std::size_t
469 _constant_length(
const char *s, std::size_t index = 0)
471 return _ends_name(s[index]) ? index : _constant_length(s, index + 1);
474 BETTER_ENUMS_CONSTEXPR_
inline char 475 _select(
const char *from, std::size_t from_length, std::size_t index)
477 return index >= from_length ?
'\0' : from[index];
480 BETTER_ENUMS_CONSTEXPR_
inline char _to_lower_ascii(
char c)
482 return c >= 0x41 && c <= 0x5A ? static_cast<char>(c + 0x20) : c;
485 BETTER_ENUMS_CONSTEXPR_
inline bool _names_match(
const char *stringizedName,
486 const char *referenceName,
487 std::size_t index = 0)
490 _ends_name(stringizedName[index]) ? referenceName[index] ==
'\0' :
491 referenceName[index] ==
'\0' ?
false :
492 stringizedName[index] != referenceName[index] ?
false :
493 _names_match(stringizedName, referenceName, index + 1);
496 BETTER_ENUMS_CONSTEXPR_
inline bool 497 _names_match_nocase(
const char *stringizedName,
const char *referenceName,
498 std::size_t index = 0)
501 _ends_name(stringizedName[index]) ? referenceName[index] ==
'\0' :
502 referenceName[index] ==
'\0' ?
false :
503 _to_lower_ascii(stringizedName[index]) !=
504 _to_lower_ascii(referenceName[index]) ?
false :
505 _names_match_nocase(stringizedName, referenceName, index + 1);
508 inline void _trim_names(
const char *
const *raw_names,
509 const char **trimmed_names,
510 char *storage, std::size_t count)
512 std::size_t offset = 0;
514 for (std::size_t index = 0; index < count; ++index) {
515 trimmed_names[index] = storage + offset;
517 std::size_t trimmed_length =
518 std::strcspn(raw_names[index], _name_enders);
519 storage[offset + trimmed_length] =
'\0';
521 std::size_t raw_length = std::strlen(raw_names[index]);
522 offset += raw_length + 1;
529 template <
typename Enum>
540 #define BETTER_ENUMS_EAT_ASSIGN_SINGLE(EnumType, index, expression) \ 541 (EnumType)((::better_enums::_eat_assign<EnumType>)EnumType::expression), 543 #define BETTER_ENUMS_EAT_ASSIGN(EnumType, ...) \ 545 BETTER_ENUMS_PP_MAP( \ 546 BETTER_ENUMS_EAT_ASSIGN_SINGLE, EnumType, __VA_ARGS__)) 550 #ifdef BETTER_ENUMS_HAVE_CONSTEXPR 554 #define BETTER_ENUMS_SELECT_SINGLE_CHARACTER(from, from_length, index) \ 555 ::better_enums::_select(from, from_length, index), 557 #define BETTER_ENUMS_SELECT_CHARACTERS(from, from_length) \ 558 BETTER_ENUMS_ITERATE( \ 559 BETTER_ENUMS_SELECT_SINGLE_CHARACTER, from, from_length) 563 #define BETTER_ENUMS_TRIM_SINGLE_STRING(ignored, index, expression) \ 564 constexpr std::size_t _length_ ## index = \ 565 ::better_enums::_constant_length(#expression); \ 566 constexpr const char _trimmed_ ## index [] = \ 567 { BETTER_ENUMS_SELECT_CHARACTERS(#expression, _length_ ## index) }; \ 568 constexpr const char *_final_ ## index = \ 569 ::better_enums::_has_initializer(#expression) ? \ 570 _trimmed_ ## index : #expression; 572 #define BETTER_ENUMS_TRIM_STRINGS(...) \ 574 BETTER_ENUMS_PP_MAP( \ 575 BETTER_ENUMS_TRIM_SINGLE_STRING, ignored, __VA_ARGS__)) 579 #define BETTER_ENUMS_REFER_TO_SINGLE_STRING(ignored, index, expression) \ 582 #define BETTER_ENUMS_REFER_TO_STRINGS(...) \ 584 BETTER_ENUMS_PP_MAP( \ 585 BETTER_ENUMS_REFER_TO_SINGLE_STRING, ignored, __VA_ARGS__)) 589 #endif // #ifdef BETTER_ENUMS_HAVE_CONSTEXPR 593 #define BETTER_ENUMS_STRINGIZE_SINGLE(ignored, index, expression) #expression, 595 #define BETTER_ENUMS_STRINGIZE(...) \ 597 BETTER_ENUMS_PP_MAP( \ 598 BETTER_ENUMS_STRINGIZE_SINGLE, ignored, __VA_ARGS__)) 600 #define BETTER_ENUMS_RESERVE_STORAGE_SINGLE(ignored, index, expression) \ 603 #define BETTER_ENUMS_RESERVE_STORAGE(...) \ 605 BETTER_ENUMS_PP_MAP( \ 606 BETTER_ENUMS_RESERVE_STORAGE_SINGLE, ignored, __VA_ARGS__)) 612 #define BETTER_ENUMS_NS(EnumType) better_enums_data_ ## EnumType 614 #ifdef BETTER_ENUMS_VC2008_WORKAROUNDS 616 #define BETTER_ENUMS_COPY_CONSTRUCTOR(Enum) \ 617 BETTER_ENUMS_CONSTEXPR_ Enum(const Enum &other) : \ 618 _value(other._value) { } 622 #define BETTER_ENUMS_COPY_CONSTRUCTOR(Enum) 626 #ifndef BETTER_ENUMS_CLASS_ATTRIBUTE 627 # define BETTER_ENUMS_CLASS_ATTRIBUTE 630 #define BETTER_ENUMS_TYPE(SetUnderlyingType, SwitchType, GenerateSwitchType, \ 631 GenerateStrings, ToStringConstexpr, \ 632 DeclareInitialize, DefineInitialize, CallInitialize, \ 633 Enum, Underlying, ...) \ 635 namespace better_enums_data_ ## Enum { \ 637 BETTER_ENUMS_ID(GenerateSwitchType(Underlying, __VA_ARGS__)) \ 641 class BETTER_ENUMS_CLASS_ATTRIBUTE Enum { \ 643 typedef ::better_enums::optional<Enum> _optional; \ 644 typedef ::better_enums::optional<std::size_t> _optional_index; \ 647 typedef Underlying _integral; \ 649 enum _enumerated SetUnderlyingType(Underlying) { __VA_ARGS__ }; \ 651 BETTER_ENUMS_CONSTEXPR_ Enum(_enumerated value) : _value(value) { } \ 653 BETTER_ENUMS_COPY_CONSTRUCTOR(Enum) \ 655 BETTER_ENUMS_CONSTEXPR_ operator SwitchType(Enum)() const \ 657 return SwitchType(Enum)(_value); \ 660 BETTER_ENUMS_CONSTEXPR_ _integral _to_integral() const; \ 661 BETTER_ENUMS_IF_EXCEPTIONS( \ 662 BETTER_ENUMS_CONSTEXPR_ static Enum _from_integral(_integral value); \ 664 BETTER_ENUMS_CONSTEXPR_ static Enum \ 665 _from_integral_unchecked(_integral value); \ 666 BETTER_ENUMS_CONSTEXPR_ static _optional \ 667 _from_integral_nothrow(_integral value); \ 669 BETTER_ENUMS_CONSTEXPR_ std::size_t _to_index() const; \ 670 BETTER_ENUMS_IF_EXCEPTIONS( \ 671 BETTER_ENUMS_CONSTEXPR_ static Enum _from_index(std::size_t value); \ 673 BETTER_ENUMS_CONSTEXPR_ static Enum \ 674 _from_index_unchecked(std::size_t value); \ 675 BETTER_ENUMS_CONSTEXPR_ static _optional \ 676 _from_index_nothrow(std::size_t value); \ 678 ToStringConstexpr const char* _to_string() const; \ 679 BETTER_ENUMS_IF_EXCEPTIONS( \ 680 BETTER_ENUMS_CONSTEXPR_ static Enum _from_string(const char *name); \ 682 BETTER_ENUMS_CONSTEXPR_ static _optional \ 683 _from_string_nothrow(const char *name); \ 685 BETTER_ENUMS_IF_EXCEPTIONS( \ 686 BETTER_ENUMS_CONSTEXPR_ static Enum _from_string_nocase(const char *name); \ 688 BETTER_ENUMS_CONSTEXPR_ static _optional \ 689 _from_string_nocase_nothrow(const char *name); \ 691 BETTER_ENUMS_CONSTEXPR_ static bool _is_valid(_integral value); \ 692 BETTER_ENUMS_CONSTEXPR_ static bool _is_valid(const char *name); \ 693 BETTER_ENUMS_CONSTEXPR_ static bool _is_valid_nocase(const char *name); \ 695 typedef ::better_enums::_iterable<Enum> _value_iterable; \ 696 typedef ::better_enums::_iterable<const char*> _name_iterable; \ 698 typedef _value_iterable::iterator _value_iterator; \ 699 typedef _name_iterable::iterator _name_iterator; \ 701 BETTER_ENUMS_CONSTEXPR_ static const std::size_t _size_constant = \ 702 BETTER_ENUMS_ID(BETTER_ENUMS_PP_COUNT(__VA_ARGS__)); \ 703 BETTER_ENUMS_CONSTEXPR_ static std::size_t _size() \ 704 { return _size_constant; } \ 706 BETTER_ENUMS_CONSTEXPR_ static const char* _name(); \ 707 BETTER_ENUMS_CONSTEXPR_ static _value_iterable _values(); \ 708 ToStringConstexpr static _name_iterable _names(); \ 712 BETTER_ENUMS_DEFAULT_CONSTRUCTOR(Enum) \ 715 explicit BETTER_ENUMS_CONSTEXPR_ Enum(const _integral &value) : \ 720 BETTER_ENUMS_CONSTEXPR_ static _optional_index \ 721 _from_value_loop(_integral value, std::size_t index = 0); \ 722 BETTER_ENUMS_CONSTEXPR_ static _optional_index \ 723 _from_string_loop(const char *name, std::size_t index = 0); \ 724 BETTER_ENUMS_CONSTEXPR_ static _optional_index \ 725 _from_string_nocase_loop(const char *name, std::size_t index = 0); \ 727 friend struct ::better_enums::_initialize_at_program_start<Enum>; \ 730 namespace better_enums_data_ ## Enum { \ 732 static ::better_enums::_initialize_at_program_start<Enum> \ 733 _force_initialization; \ 735 enum _putNamesInThisScopeAlso { __VA_ARGS__ }; \ 737 BETTER_ENUMS_IGNORE_OLD_CAST_HEADER \ 738 BETTER_ENUMS_IGNORE_OLD_CAST_BEGIN \ 739 BETTER_ENUMS_CONSTEXPR_ const Enum _value_array[] = \ 740 { BETTER_ENUMS_ID(BETTER_ENUMS_EAT_ASSIGN(Enum, __VA_ARGS__)) }; \ 741 BETTER_ENUMS_IGNORE_OLD_CAST_END \ 743 BETTER_ENUMS_ID(GenerateStrings(Enum, __VA_ARGS__)) \ 747 BETTER_ENUMS_IGNORE_ATTRIBUTES_HEADER \ 748 BETTER_ENUMS_IGNORE_ATTRIBUTES_BEGIN \ 749 BETTER_ENUMS_UNUSED BETTER_ENUMS_CONSTEXPR_ \ 751 operator +(Enum::_enumerated enumerated) \ 753 return static_cast<Enum>(enumerated); \ 755 BETTER_ENUMS_IGNORE_ATTRIBUTES_END \ 757 BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional_index \ 758 Enum::_from_value_loop(Enum::_integral value, std::size_t index) \ 762 _optional_index() : \ 763 BETTER_ENUMS_NS(Enum)::_value_array[index]._value == value ? \ 764 _optional_index(index) : \ 765 _from_value_loop(value, index + 1); \ 768 BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional_index \ 769 Enum::_from_string_loop(const char *name, std::size_t index) \ 772 index == _size() ? _optional_index() : \ 773 ::better_enums::_names_match( \ 774 BETTER_ENUMS_NS(Enum)::_raw_names()[index], name) ? \ 775 _optional_index(index) : \ 776 _from_string_loop(name, index + 1); \ 779 BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional_index \ 780 Enum::_from_string_nocase_loop(const char *name, std::size_t index) \ 783 index == _size() ? _optional_index() : \ 784 ::better_enums::_names_match_nocase( \ 785 BETTER_ENUMS_NS(Enum)::_raw_names()[index], name) ? \ 786 _optional_index(index) : \ 787 _from_string_nocase_loop(name, index + 1); \ 790 BETTER_ENUMS_CONSTEXPR_ inline Enum::_integral Enum::_to_integral() const \ 792 return _integral(_value); \ 795 BETTER_ENUMS_CONSTEXPR_ inline std::size_t Enum::_to_index() const \ 797 return *_from_value_loop(_value); \ 800 BETTER_ENUMS_CONSTEXPR_ inline Enum \ 801 Enum::_from_index_unchecked(std::size_t index) \ 804 ::better_enums::_or_zero(_from_index_nothrow(index)); \ 807 BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional \ 808 Enum::_from_index_nothrow(std::size_t index) \ 813 _optional(BETTER_ENUMS_NS(Enum)::_value_array[index]); \ 816 BETTER_ENUMS_IF_EXCEPTIONS( \ 817 BETTER_ENUMS_CONSTEXPR_ inline Enum Enum::_from_index(std::size_t index) \ 820 ::better_enums::_or_throw(_from_index_nothrow(index), \ 821 #Enum "::_from_index: invalid argument"); \ 825 BETTER_ENUMS_CONSTEXPR_ inline Enum \ 826 Enum::_from_integral_unchecked(_integral value) \ 828 return static_cast<_enumerated>(value); \ 831 BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional \ 832 Enum::_from_integral_nothrow(_integral value) \ 835 ::better_enums::_map_index<Enum>(BETTER_ENUMS_NS(Enum)::_value_array, \ 836 _from_value_loop(value)); \ 839 BETTER_ENUMS_IF_EXCEPTIONS( \ 840 BETTER_ENUMS_CONSTEXPR_ inline Enum Enum::_from_integral(_integral value) \ 843 ::better_enums::_or_throw(_from_integral_nothrow(value), \ 844 #Enum "::_from_integral: invalid argument"); \ 848 ToStringConstexpr inline const char* Enum::_to_string() const \ 851 ::better_enums::_or_null( \ 852 ::better_enums::_map_index<const char*>( \ 853 BETTER_ENUMS_NS(Enum)::_name_array(), \ 854 _from_value_loop(CallInitialize(_value)))); \ 857 BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional \ 858 Enum::_from_string_nothrow(const char *name) \ 861 ::better_enums::_map_index<Enum>( \ 862 BETTER_ENUMS_NS(Enum)::_value_array, _from_string_loop(name)); \ 865 BETTER_ENUMS_IF_EXCEPTIONS( \ 866 BETTER_ENUMS_CONSTEXPR_ inline Enum Enum::_from_string(const char *name) \ 869 ::better_enums::_or_throw(_from_string_nothrow(name), \ 870 #Enum "::_from_string: invalid argument"); \ 874 BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional \ 875 Enum::_from_string_nocase_nothrow(const char *name) \ 878 ::better_enums::_map_index<Enum>(BETTER_ENUMS_NS(Enum)::_value_array, \ 879 _from_string_nocase_loop(name)); \ 882 BETTER_ENUMS_IF_EXCEPTIONS( \ 883 BETTER_ENUMS_CONSTEXPR_ inline Enum Enum::_from_string_nocase(const char *name)\ 886 ::better_enums::_or_throw( \ 887 _from_string_nocase_nothrow(name), \ 888 #Enum "::_from_string_nocase: invalid argument"); \ 892 BETTER_ENUMS_CONSTEXPR_ inline bool Enum::_is_valid(_integral value) \ 894 return _from_value_loop(value); \ 897 BETTER_ENUMS_CONSTEXPR_ inline bool Enum::_is_valid(const char *name) \ 899 return _from_string_loop(name); \ 902 BETTER_ENUMS_CONSTEXPR_ inline bool Enum::_is_valid_nocase(const char *name) \ 904 return _from_string_nocase_loop(name); \ 907 BETTER_ENUMS_CONSTEXPR_ inline const char* Enum::_name() \ 912 BETTER_ENUMS_CONSTEXPR_ inline Enum::_value_iterable Enum::_values() \ 914 return _value_iterable(BETTER_ENUMS_NS(Enum)::_value_array, _size()); \ 917 ToStringConstexpr inline Enum::_name_iterable Enum::_names() \ 920 _name_iterable(BETTER_ENUMS_NS(Enum)::_name_array(), \ 921 CallInitialize(_size())); \ 924 DefineInitialize(Enum) \ 926 BETTER_ENUMS_IGNORE_ATTRIBUTES_HEADER \ 927 BETTER_ENUMS_IGNORE_ATTRIBUTES_BEGIN \ 928 BETTER_ENUMS_UNUSED BETTER_ENUMS_CONSTEXPR_ \ 929 inline bool operator ==(const Enum &a, const Enum &b) \ 930 { return a._to_integral() == b._to_integral(); } \ 932 BETTER_ENUMS_UNUSED BETTER_ENUMS_CONSTEXPR_ \ 933 inline bool operator !=(const Enum &a, const Enum &b) \ 934 { return a._to_integral() != b._to_integral(); } \ 936 BETTER_ENUMS_UNUSED BETTER_ENUMS_CONSTEXPR_ \ 937 inline bool operator <(const Enum &a, const Enum &b) \ 938 { return a._to_integral() < b._to_integral(); } \ 940 BETTER_ENUMS_UNUSED BETTER_ENUMS_CONSTEXPR_ \ 941 inline bool operator <=(const Enum &a, const Enum &b) \ 942 { return a._to_integral() <= b._to_integral(); } \ 944 BETTER_ENUMS_UNUSED BETTER_ENUMS_CONSTEXPR_ \ 945 inline bool operator >(const Enum &a, const Enum &b) \ 946 { return a._to_integral() > b._to_integral(); } \ 948 BETTER_ENUMS_UNUSED BETTER_ENUMS_CONSTEXPR_ \ 949 inline bool operator >=(const Enum &a, const Enum &b) \ 950 { return a._to_integral() >= b._to_integral(); } \ 951 BETTER_ENUMS_IGNORE_ATTRIBUTES_END \ 954 template <typename Char, typename Traits> \ 955 std::basic_ostream<Char, Traits>& \ 956 operator <<(std::basic_ostream<Char, Traits>& stream, const Enum &value) \ 958 return stream << value._to_string(); \ 961 template <typename Char, typename Traits> \ 962 std::basic_istream<Char, Traits>& \ 963 operator >>(std::basic_istream<Char, Traits>& stream, Enum &value) \ 965 std::basic_string<Char, Traits> buffer; \ 968 ::better_enums::optional<Enum> converted = \ 969 Enum::_from_string_nothrow(buffer.c_str()); \ 972 value = *converted; \ 974 stream.setstate(std::basic_istream<Char, Traits>::failbit); \ 984 #define BETTER_ENUMS_CXX98_UNDERLYING_TYPE(Underlying) 987 #define BETTER_ENUMS_CXX11_UNDERLYING_TYPE(Underlying) \ 990 #if defined(_MSC_VER) && _MSC_VER >= 1700 993 # define BETTER_ENUMS_LEGACY_UNDERLYING_TYPE(Underlying) \ 994 BETTER_ENUMS_CXX11_UNDERLYING_TYPE(Underlying) 996 # define BETTER_ENUMS_LEGACY_UNDERLYING_TYPE(Underlying) \ 997 BETTER_ENUMS_CXX98_UNDERLYING_TYPE(Underlying) 1001 #define BETTER_ENUMS_REGULAR_ENUM_SWITCH_TYPE(Type) \ 1005 #define BETTER_ENUMS_ENUM_CLASS_SWITCH_TYPE(Type) \ 1006 BETTER_ENUMS_NS(Type)::_enumClassForSwitchStatements 1009 #define BETTER_ENUMS_REGULAR_ENUM_SWITCH_TYPE_GENERATE(Underlying, ...) 1012 #define BETTER_ENUMS_ENUM_CLASS_SWITCH_TYPE_GENERATE(Underlying, ...) \ 1013 enum class _enumClassForSwitchStatements : Underlying { __VA_ARGS__ }; 1016 #define BETTER_ENUMS_CXX98_TRIM_STRINGS_ARRAYS(Enum, ...) \ 1017 inline const char** _raw_names() \ 1019 static const char *value[] = \ 1020 { BETTER_ENUMS_ID(BETTER_ENUMS_STRINGIZE(__VA_ARGS__)) }; \ 1024 inline char* _name_storage() \ 1026 static char storage[] = \ 1027 BETTER_ENUMS_ID(BETTER_ENUMS_RESERVE_STORAGE(__VA_ARGS__)); \ 1031 inline const char** _name_array() \ 1033 static const char *value[Enum::_size_constant]; \ 1037 inline bool& _initialized() \ 1039 static bool value = false; \ 1044 #define BETTER_ENUMS_CXX11_PARTIAL_CONSTEXPR_TRIM_STRINGS_ARRAYS(Enum, ...) \ 1045 constexpr const char *_the_raw_names[] = \ 1046 { BETTER_ENUMS_ID(BETTER_ENUMS_STRINGIZE(__VA_ARGS__)) }; \ 1048 constexpr const char * const * _raw_names() \ 1050 return _the_raw_names; \ 1053 inline char* _name_storage() \ 1055 static char storage[] = \ 1056 BETTER_ENUMS_ID(BETTER_ENUMS_RESERVE_STORAGE(__VA_ARGS__)); \ 1060 inline const char** _name_array() \ 1062 static const char *value[Enum::_size_constant]; \ 1066 inline bool& _initialized() \ 1068 static bool value = false; \ 1073 #define BETTER_ENUMS_CXX11_FULL_CONSTEXPR_TRIM_STRINGS_ARRAYS(Enum, ...) \ 1074 BETTER_ENUMS_ID(BETTER_ENUMS_TRIM_STRINGS(__VA_ARGS__)) \ 1076 constexpr const char * const _the_name_array[] = \ 1077 { BETTER_ENUMS_ID(BETTER_ENUMS_REFER_TO_STRINGS(__VA_ARGS__)) }; \ 1079 constexpr const char * const * _name_array() \ 1081 return _the_name_array; \ 1084 constexpr const char * const * _raw_names() \ 1086 return _the_name_array; \ 1090 #define BETTER_ENUMS_NO_CONSTEXPR_TO_STRING_KEYWORD 1093 #define BETTER_ENUMS_CONSTEXPR_TO_STRING_KEYWORD \ 1097 #define BETTER_ENUMS_DO_DECLARE_INITIALIZE \ 1098 static int initialize(); 1101 #define BETTER_ENUMS_DECLARE_EMPTY_INITIALIZE \ 1102 static int initialize() { return 0; } 1105 #define BETTER_ENUMS_DO_DEFINE_INITIALIZE(Enum) \ 1106 inline int Enum::initialize() \ 1108 if (BETTER_ENUMS_NS(Enum)::_initialized()) \ 1111 ::better_enums::_trim_names(BETTER_ENUMS_NS(Enum)::_raw_names(), \ 1112 BETTER_ENUMS_NS(Enum)::_name_array(), \ 1113 BETTER_ENUMS_NS(Enum)::_name_storage(), \ 1116 BETTER_ENUMS_NS(Enum)::_initialized() = true; \ 1122 #define BETTER_ENUMS_DO_NOT_DEFINE_INITIALIZE(Enum) 1125 #define BETTER_ENUMS_DO_CALL_INITIALIZE(value) \ 1126 ::better_enums::continue_with(initialize(), value) 1129 #define BETTER_ENUMS_DO_NOT_CALL_INITIALIZE(value) \ 1136 #ifdef BETTER_ENUMS_STRICT_CONVERSION 1137 # define BETTER_ENUMS_DEFAULT_SWITCH_TYPE \ 1138 BETTER_ENUMS_ENUM_CLASS_SWITCH_TYPE 1139 # define BETTER_ENUMS_DEFAULT_SWITCH_TYPE_GENERATE \ 1140 BETTER_ENUMS_ENUM_CLASS_SWITCH_TYPE_GENERATE 1142 # define BETTER_ENUMS_DEFAULT_SWITCH_TYPE \ 1143 BETTER_ENUMS_REGULAR_ENUM_SWITCH_TYPE 1144 # define BETTER_ENUMS_DEFAULT_SWITCH_TYPE_GENERATE \ 1145 BETTER_ENUMS_REGULAR_ENUM_SWITCH_TYPE_GENERATE 1150 #ifndef BETTER_ENUMS_DEFAULT_CONSTRUCTOR 1151 # define BETTER_ENUMS_DEFAULT_CONSTRUCTOR(Enum) \ 1153 Enum() : _value(0) { } 1158 #ifdef BETTER_ENUMS_HAVE_CONSTEXPR 1160 #ifdef BETTER_ENUMS_CONSTEXPR_TO_STRING 1161 # define BETTER_ENUMS_DEFAULT_TRIM_STRINGS_ARRAYS \ 1162 BETTER_ENUMS_CXX11_FULL_CONSTEXPR_TRIM_STRINGS_ARRAYS 1163 # define BETTER_ENUMS_DEFAULT_TO_STRING_KEYWORD \ 1164 BETTER_ENUMS_CONSTEXPR_TO_STRING_KEYWORD 1165 # define BETTER_ENUMS_DEFAULT_DECLARE_INITIALIZE \ 1166 BETTER_ENUMS_DECLARE_EMPTY_INITIALIZE 1167 # define BETTER_ENUMS_DEFAULT_DEFINE_INITIALIZE \ 1168 BETTER_ENUMS_DO_NOT_DEFINE_INITIALIZE 1169 # define BETTER_ENUMS_DEFAULT_CALL_INITIALIZE \ 1170 BETTER_ENUMS_DO_NOT_CALL_INITIALIZE 1172 # define BETTER_ENUMS_DEFAULT_TRIM_STRINGS_ARRAYS \ 1173 BETTER_ENUMS_CXX11_PARTIAL_CONSTEXPR_TRIM_STRINGS_ARRAYS 1174 # define BETTER_ENUMS_DEFAULT_TO_STRING_KEYWORD \ 1175 BETTER_ENUMS_NO_CONSTEXPR_TO_STRING_KEYWORD 1176 # define BETTER_ENUMS_DEFAULT_DECLARE_INITIALIZE \ 1177 BETTER_ENUMS_DO_DECLARE_INITIALIZE 1178 # define BETTER_ENUMS_DEFAULT_DEFINE_INITIALIZE \ 1179 BETTER_ENUMS_DO_DEFINE_INITIALIZE 1180 # define BETTER_ENUMS_DEFAULT_CALL_INITIALIZE \ 1181 BETTER_ENUMS_DO_CALL_INITIALIZE 1188 #define BETTER_ENUM(Enum, Underlying, ...) \ 1189 BETTER_ENUMS_ID(BETTER_ENUMS_TYPE( \ 1190 BETTER_ENUMS_CXX11_UNDERLYING_TYPE, \ 1191 BETTER_ENUMS_DEFAULT_SWITCH_TYPE, \ 1192 BETTER_ENUMS_DEFAULT_SWITCH_TYPE_GENERATE, \ 1193 BETTER_ENUMS_DEFAULT_TRIM_STRINGS_ARRAYS, \ 1194 BETTER_ENUMS_DEFAULT_TO_STRING_KEYWORD, \ 1195 BETTER_ENUMS_DEFAULT_DECLARE_INITIALIZE, \ 1196 BETTER_ENUMS_DEFAULT_DEFINE_INITIALIZE, \ 1197 BETTER_ENUMS_DEFAULT_CALL_INITIALIZE, \ 1198 Enum, Underlying, __VA_ARGS__)) 1200 #define SLOW_ENUM(Enum, Underlying, ...) \ 1201 BETTER_ENUMS_ID(BETTER_ENUMS_TYPE( \ 1202 BETTER_ENUMS_CXX11_UNDERLYING_TYPE, \ 1203 BETTER_ENUMS_DEFAULT_SWITCH_TYPE, \ 1204 BETTER_ENUMS_DEFAULT_SWITCH_TYPE_GENERATE, \ 1205 BETTER_ENUMS_CXX11_FULL_CONSTEXPR_TRIM_STRINGS_ARRAYS, \ 1206 BETTER_ENUMS_CONSTEXPR_TO_STRING_KEYWORD, \ 1207 BETTER_ENUMS_DECLARE_EMPTY_INITIALIZE, \ 1208 BETTER_ENUMS_DO_NOT_DEFINE_INITIALIZE, \ 1209 BETTER_ENUMS_DO_NOT_CALL_INITIALIZE, \ 1210 Enum, Underlying, __VA_ARGS__)) 1214 #define BETTER_ENUM(Enum, Underlying, ...) \ 1215 BETTER_ENUMS_ID(BETTER_ENUMS_TYPE( \ 1216 BETTER_ENUMS_LEGACY_UNDERLYING_TYPE, \ 1217 BETTER_ENUMS_DEFAULT_SWITCH_TYPE, \ 1218 BETTER_ENUMS_DEFAULT_SWITCH_TYPE_GENERATE, \ 1219 BETTER_ENUMS_CXX98_TRIM_STRINGS_ARRAYS, \ 1220 BETTER_ENUMS_NO_CONSTEXPR_TO_STRING_KEYWORD, \ 1221 BETTER_ENUMS_DO_DECLARE_INITIALIZE, \ 1222 BETTER_ENUMS_DO_DEFINE_INITIALIZE, \ 1223 BETTER_ENUMS_DO_CALL_INITIALIZE, \ 1224 Enum, Underlying, __VA_ARGS__)) 1234 template <
typename T>
1236 BETTER_ENUMS_CONSTEXPR_
static bool less(
const T& a,
const T& b)
1242 BETTER_ENUMS_CONSTEXPR_
static bool less(
const char *a,
const char *b)
1243 {
return less_loop(a, b); }
1246 BETTER_ENUMS_CONSTEXPR_
static bool 1247 less_loop(
const char *a,
const char *b,
size_t index = 0)
1250 a[index] != b[index] ? a[index] < b[index] :
1251 a[index] ==
'\0' ?
false :
1252 less_loop(a, b, index + 1);
1258 BETTER_ENUMS_CONSTEXPR_
static bool less(
const wchar_t *a,
const wchar_t *b)
1259 {
return less_loop(a, b); }
1262 BETTER_ENUMS_CONSTEXPR_
static bool 1263 less_loop(
const wchar_t *a,
const wchar_t *b,
size_t index = 0)
1266 a[index] != b[index] ? a[index] < b[index] :
1267 a[index] == L
'\0' ?
false :
1268 less_loop(a, b, index + 1);
1272 template <
typename Enum,
typename T,
typename Compare = map_compare<T> >
1274 typedef T (*
function)(Enum);
1276 BETTER_ENUMS_CONSTEXPR_
explicit map(
function f) : _f(f) { }
1278 BETTER_ENUMS_CONSTEXPR_ T from_enum(Enum value)
const {
return _f(value); }
1279 BETTER_ENUMS_CONSTEXPR_ T operator [](Enum value)
const 1280 {
return _f(value); }
1282 BETTER_ENUMS_CONSTEXPR_ Enum to_enum(T value)
const 1285 _or_throw(to_enum_nothrow(value),
"map::to_enum: invalid argument");
1289 to_enum_nothrow(T value,
size_t index = 0)
const 1293 Compare::less(_f(Enum::_values()[index]), value) ||
1294 Compare::less(value, _f(Enum::_values()[index])) ?
1295 to_enum_nothrow(value, index + 1) :
1296 Enum::_values()[index];
1303 template <
typename Enum,
typename T>
1304 BETTER_ENUMS_CONSTEXPR_
map<Enum, T> make_map(T (*f)(Enum))
1311 #define BETTER_ENUMS_DECLARE_STD_HASH(type) \ 1313 template <> struct hash<type> \ 1315 size_t operator()(const type &x) const \ 1317 return std::hash<size_t>()(x._to_integral()); \ 1322 #endif // #ifndef BETTER_ENUMS_ENUM_H struct to keep a message from a sender
Definition: defTypes.h:24
Get intrinsic value of an (Enum::value) by taking advantage of C-conversion's parentheses priority...
Definition: enum.h:408