6 #ifndef BETTER_ENUMS_ENUM_H 7 #define BETTER_ENUMS_ENUM_H 22 # if __has_feature(cxx_constexpr) 23 # define BETTER_ENUMS_HAVE_CONSTEXPR 25 # if !defined(__EXCEPTIONS) || !__has_feature(cxx_exceptions) 26 # define BETTER_ENUMS_NO_EXCEPTIONS 29 # if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L 30 # if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) 31 # define BETTER_ENUMS_HAVE_CONSTEXPR 35 # define BETTER_ENUMS_NO_EXCEPTIONS 42 # if __has_feature(cxx_constexpr) 43 # define BETTER_ENUMS_HAVE_CONSTEXPR 47 # define BETTER_ENUMS_NO_EXCEPTIONS 50 # define BETTER_ENUMS_VC2008_WORKAROUNDS 54 #ifdef BETTER_ENUMS_CONSTEXPR 55 # define BETTER_ENUMS_HAVE_CONSTEXPR 58 #ifdef BETTER_ENUMS_NO_CONSTEXPR 59 # ifdef BETTER_ENUMS_HAVE_CONSTEXPR 60 # undef BETTER_ENUMS_HAVE_CONSTEXPR 72 #ifdef BETTER_ENUMS_HAVE_CONSTEXPR 73 # define BETTER_ENUMS_CONSTEXPR_ constexpr 74 # define BETTER_ENUMS_NULLPTR nullptr 76 # define BETTER_ENUMS_CONSTEXPR_ 77 # define BETTER_ENUMS_NULLPTR NULL 80 #ifndef BETTER_ENUMS_NO_EXCEPTIONS 81 # define BETTER_ENUMS_IF_EXCEPTIONS(x) x 83 # define BETTER_ENUMS_IF_EXCEPTIONS(x) 87 # define BETTER_ENUMS_UNUSED __attribute__((__unused__)) 89 # define BETTER_ENUMS_UNUSED 96 #ifdef BETTER_ENUMS_MACRO_FILE 97 # include BETTER_ENUMS_MACRO_FILE 100 #define BETTER_ENUMS_PP_MAP(macro, data, ...) \ 102 BETTER_ENUMS_APPLY( \ 103 BETTER_ENUMS_PP_MAP_VAR_COUNT, \ 104 BETTER_ENUMS_PP_COUNT(__VA_ARGS__)) \ 105 (macro, data, __VA_ARGS__)) 107 #define BETTER_ENUMS_PP_MAP_VAR_COUNT(count) BETTER_ENUMS_M ## count 109 #define BETTER_ENUMS_APPLY(macro, ...) BETTER_ENUMS_ID(macro(__VA_ARGS__)) 111 #define BETTER_ENUMS_ID(x) x 113 #define BETTER_ENUMS_M1(m, d, x) m(d,0,x) 114 #define BETTER_ENUMS_M2(m,d,x,...) m(d,1,x) \ 115 BETTER_ENUMS_ID(BETTER_ENUMS_M1(m,d,__VA_ARGS__)) 116 #define BETTER_ENUMS_M3(m,d,x,...) m(d,2,x) \ 117 BETTER_ENUMS_ID(BETTER_ENUMS_M2(m,d,__VA_ARGS__)) 118 #define BETTER_ENUMS_M4(m,d,x,...) m(d,3,x) \ 119 BETTER_ENUMS_ID(BETTER_ENUMS_M3(m,d,__VA_ARGS__)) 120 #define BETTER_ENUMS_M5(m,d,x,...) m(d,4,x) \ 121 BETTER_ENUMS_ID(BETTER_ENUMS_M4(m,d,__VA_ARGS__)) 122 #define BETTER_ENUMS_M6(m,d,x,...) m(d,5,x) \ 123 BETTER_ENUMS_ID(BETTER_ENUMS_M5(m,d,__VA_ARGS__)) 124 #define BETTER_ENUMS_M7(m,d,x,...) m(d,6,x) \ 125 BETTER_ENUMS_ID(BETTER_ENUMS_M6(m,d,__VA_ARGS__)) 126 #define BETTER_ENUMS_M8(m,d,x,...) m(d,7,x) \ 127 BETTER_ENUMS_ID(BETTER_ENUMS_M7(m,d,__VA_ARGS__)) 128 #define BETTER_ENUMS_M9(m,d,x,...) m(d,8,x) \ 129 BETTER_ENUMS_ID(BETTER_ENUMS_M8(m,d,__VA_ARGS__)) 130 #define BETTER_ENUMS_M10(m,d,x,...) m(d,9,x) \ 131 BETTER_ENUMS_ID(BETTER_ENUMS_M9(m,d,__VA_ARGS__)) 132 #define BETTER_ENUMS_M11(m,d,x,...) m(d,10,x) \ 133 BETTER_ENUMS_ID(BETTER_ENUMS_M10(m,d,__VA_ARGS__)) 134 #define BETTER_ENUMS_M12(m,d,x,...) m(d,11,x) \ 135 BETTER_ENUMS_ID(BETTER_ENUMS_M11(m,d,__VA_ARGS__)) 136 #define BETTER_ENUMS_M13(m,d,x,...) m(d,12,x) \ 137 BETTER_ENUMS_ID(BETTER_ENUMS_M12(m,d,__VA_ARGS__)) 138 #define BETTER_ENUMS_M14(m,d,x,...) m(d,13,x) \ 139 BETTER_ENUMS_ID(BETTER_ENUMS_M13(m,d,__VA_ARGS__)) 140 #define BETTER_ENUMS_M15(m,d,x,...) m(d,14,x) \ 141 BETTER_ENUMS_ID(BETTER_ENUMS_M14(m,d,__VA_ARGS__)) 142 #define BETTER_ENUMS_M16(m,d,x,...) m(d,15,x) \ 143 BETTER_ENUMS_ID(BETTER_ENUMS_M15(m,d,__VA_ARGS__)) 144 #define BETTER_ENUMS_M17(m,d,x,...) m(d,16,x) \ 145 BETTER_ENUMS_ID(BETTER_ENUMS_M16(m,d,__VA_ARGS__)) 146 #define BETTER_ENUMS_M18(m,d,x,...) m(d,17,x) \ 147 BETTER_ENUMS_ID(BETTER_ENUMS_M17(m,d,__VA_ARGS__)) 148 #define BETTER_ENUMS_M19(m,d,x,...) m(d,18,x) \ 149 BETTER_ENUMS_ID(BETTER_ENUMS_M18(m,d,__VA_ARGS__)) 150 #define BETTER_ENUMS_M20(m,d,x,...) m(d,19,x) \ 151 BETTER_ENUMS_ID(BETTER_ENUMS_M19(m,d,__VA_ARGS__)) 152 #define BETTER_ENUMS_M21(m,d,x,...) m(d,20,x) \ 153 BETTER_ENUMS_ID(BETTER_ENUMS_M20(m,d,__VA_ARGS__)) 154 #define BETTER_ENUMS_M22(m,d,x,...) m(d,21,x) \ 155 BETTER_ENUMS_ID(BETTER_ENUMS_M21(m,d,__VA_ARGS__)) 156 #define BETTER_ENUMS_M23(m,d,x,...) m(d,22,x) \ 157 BETTER_ENUMS_ID(BETTER_ENUMS_M22(m,d,__VA_ARGS__)) 158 #define BETTER_ENUMS_M24(m,d,x,...) m(d,23,x) \ 159 BETTER_ENUMS_ID(BETTER_ENUMS_M23(m,d,__VA_ARGS__)) 160 #define BETTER_ENUMS_M25(m,d,x,...) m(d,24,x) \ 161 BETTER_ENUMS_ID(BETTER_ENUMS_M24(m,d,__VA_ARGS__)) 162 #define BETTER_ENUMS_M26(m,d,x,...) m(d,25,x) \ 163 BETTER_ENUMS_ID(BETTER_ENUMS_M25(m,d,__VA_ARGS__)) 164 #define BETTER_ENUMS_M27(m,d,x,...) m(d,26,x) \ 165 BETTER_ENUMS_ID(BETTER_ENUMS_M26(m,d,__VA_ARGS__)) 166 #define BETTER_ENUMS_M28(m,d,x,...) m(d,27,x) \ 167 BETTER_ENUMS_ID(BETTER_ENUMS_M27(m,d,__VA_ARGS__)) 168 #define BETTER_ENUMS_M29(m,d,x,...) m(d,28,x) \ 169 BETTER_ENUMS_ID(BETTER_ENUMS_M28(m,d,__VA_ARGS__)) 170 #define BETTER_ENUMS_M30(m,d,x,...) m(d,29,x) \ 171 BETTER_ENUMS_ID(BETTER_ENUMS_M29(m,d,__VA_ARGS__)) 172 #define BETTER_ENUMS_M31(m,d,x,...) m(d,30,x) \ 173 BETTER_ENUMS_ID(BETTER_ENUMS_M30(m,d,__VA_ARGS__)) 174 #define BETTER_ENUMS_M32(m,d,x,...) m(d,31,x) \ 175 BETTER_ENUMS_ID(BETTER_ENUMS_M31(m,d,__VA_ARGS__)) 176 #define BETTER_ENUMS_M33(m,d,x,...) m(d,32,x) \ 177 BETTER_ENUMS_ID(BETTER_ENUMS_M32(m,d,__VA_ARGS__)) 178 #define BETTER_ENUMS_M34(m,d,x,...) m(d,33,x) \ 179 BETTER_ENUMS_ID(BETTER_ENUMS_M33(m,d,__VA_ARGS__)) 180 #define BETTER_ENUMS_M35(m,d,x,...) m(d,34,x) \ 181 BETTER_ENUMS_ID(BETTER_ENUMS_M34(m,d,__VA_ARGS__)) 182 #define BETTER_ENUMS_M36(m,d,x,...) m(d,35,x) \ 183 BETTER_ENUMS_ID(BETTER_ENUMS_M35(m,d,__VA_ARGS__)) 184 #define BETTER_ENUMS_M37(m,d,x,...) m(d,36,x) \ 185 BETTER_ENUMS_ID(BETTER_ENUMS_M36(m,d,__VA_ARGS__)) 186 #define BETTER_ENUMS_M38(m,d,x,...) m(d,37,x) \ 187 BETTER_ENUMS_ID(BETTER_ENUMS_M37(m,d,__VA_ARGS__)) 188 #define BETTER_ENUMS_M39(m,d,x,...) m(d,38,x) \ 189 BETTER_ENUMS_ID(BETTER_ENUMS_M38(m,d,__VA_ARGS__)) 190 #define BETTER_ENUMS_M40(m,d,x,...) m(d,39,x) \ 191 BETTER_ENUMS_ID(BETTER_ENUMS_M39(m,d,__VA_ARGS__)) 192 #define BETTER_ENUMS_M41(m,d,x,...) m(d,40,x) \ 193 BETTER_ENUMS_ID(BETTER_ENUMS_M40(m,d,__VA_ARGS__)) 194 #define BETTER_ENUMS_M42(m,d,x,...) m(d,41,x) \ 195 BETTER_ENUMS_ID(BETTER_ENUMS_M41(m,d,__VA_ARGS__)) 196 #define BETTER_ENUMS_M43(m,d,x,...) m(d,42,x) \ 197 BETTER_ENUMS_ID(BETTER_ENUMS_M42(m,d,__VA_ARGS__)) 198 #define BETTER_ENUMS_M44(m,d,x,...) m(d,43,x) \ 199 BETTER_ENUMS_ID(BETTER_ENUMS_M43(m,d,__VA_ARGS__)) 200 #define BETTER_ENUMS_M45(m,d,x,...) m(d,44,x) \ 201 BETTER_ENUMS_ID(BETTER_ENUMS_M44(m,d,__VA_ARGS__)) 202 #define BETTER_ENUMS_M46(m,d,x,...) m(d,45,x) \ 203 BETTER_ENUMS_ID(BETTER_ENUMS_M45(m,d,__VA_ARGS__)) 204 #define BETTER_ENUMS_M47(m,d,x,...) m(d,46,x) \ 205 BETTER_ENUMS_ID(BETTER_ENUMS_M46(m,d,__VA_ARGS__)) 206 #define BETTER_ENUMS_M48(m,d,x,...) m(d,47,x) \ 207 BETTER_ENUMS_ID(BETTER_ENUMS_M47(m,d,__VA_ARGS__)) 208 #define BETTER_ENUMS_M49(m,d,x,...) m(d,48,x) \ 209 BETTER_ENUMS_ID(BETTER_ENUMS_M48(m,d,__VA_ARGS__)) 210 #define BETTER_ENUMS_M50(m,d,x,...) m(d,49,x) \ 211 BETTER_ENUMS_ID(BETTER_ENUMS_M49(m,d,__VA_ARGS__)) 212 #define BETTER_ENUMS_M51(m,d,x,...) m(d,50,x) \ 213 BETTER_ENUMS_ID(BETTER_ENUMS_M50(m,d,__VA_ARGS__)) 214 #define BETTER_ENUMS_M52(m,d,x,...) m(d,51,x) \ 215 BETTER_ENUMS_ID(BETTER_ENUMS_M51(m,d,__VA_ARGS__)) 216 #define BETTER_ENUMS_M53(m,d,x,...) m(d,52,x) \ 217 BETTER_ENUMS_ID(BETTER_ENUMS_M52(m,d,__VA_ARGS__)) 218 #define BETTER_ENUMS_M54(m,d,x,...) m(d,53,x) \ 219 BETTER_ENUMS_ID(BETTER_ENUMS_M53(m,d,__VA_ARGS__)) 220 #define BETTER_ENUMS_M55(m,d,x,...) m(d,54,x) \ 221 BETTER_ENUMS_ID(BETTER_ENUMS_M54(m,d,__VA_ARGS__)) 222 #define BETTER_ENUMS_M56(m,d,x,...) m(d,55,x) \ 223 BETTER_ENUMS_ID(BETTER_ENUMS_M55(m,d,__VA_ARGS__)) 224 #define BETTER_ENUMS_M57(m,d,x,...) m(d,56,x) \ 225 BETTER_ENUMS_ID(BETTER_ENUMS_M56(m,d,__VA_ARGS__)) 226 #define BETTER_ENUMS_M58(m,d,x,...) m(d,57,x) \ 227 BETTER_ENUMS_ID(BETTER_ENUMS_M57(m,d,__VA_ARGS__)) 228 #define BETTER_ENUMS_M59(m,d,x,...) m(d,58,x) \ 229 BETTER_ENUMS_ID(BETTER_ENUMS_M58(m,d,__VA_ARGS__)) 230 #define BETTER_ENUMS_M60(m,d,x,...) m(d,59,x) \ 231 BETTER_ENUMS_ID(BETTER_ENUMS_M59(m,d,__VA_ARGS__)) 232 #define BETTER_ENUMS_M61(m,d,x,...) m(d,60,x) \ 233 BETTER_ENUMS_ID(BETTER_ENUMS_M60(m,d,__VA_ARGS__)) 234 #define BETTER_ENUMS_M62(m,d,x,...) m(d,61,x) \ 235 BETTER_ENUMS_ID(BETTER_ENUMS_M61(m,d,__VA_ARGS__)) 236 #define BETTER_ENUMS_M63(m,d,x,...) m(d,62,x) \ 237 BETTER_ENUMS_ID(BETTER_ENUMS_M62(m,d,__VA_ARGS__)) 238 #define BETTER_ENUMS_M64(m,d,x,...) m(d,63,x) \ 239 BETTER_ENUMS_ID(BETTER_ENUMS_M63(m,d,__VA_ARGS__)) 241 #define BETTER_ENUMS_PP_COUNT_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \ 242 _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, \ 243 _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \ 244 _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, \ 245 _56, _57, _58, _59, _60, _61, _62, _63, _64, count, ...) count 247 #define BETTER_ENUMS_PP_COUNT(...) \ 248 BETTER_ENUMS_ID(BETTER_ENUMS_PP_COUNT_IMPL(__VA_ARGS__, 64, 63, 62, 61, 60,\ 249 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42,\ 250 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24,\ 251 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, \ 254 #define BETTER_ENUMS_ITERATE(X, f, l) X(f, l, 0) X(f, l, 1) X(f, l, 2) \ 255 X(f, l, 3) X(f, l, 4) X(f, l, 5) X(f, l, 6) X(f, l, 7) X(f, l, 8) \ 256 X(f, l, 9) X(f, l, 10) X(f, l, 11) X(f, l, 12) X(f, l, 13) X(f, l, 14) \ 257 X(f, l, 15) X(f, l, 16) X(f, l, 17) X(f, l, 18) X(f, l, 19) X(f, l, 20) \ 258 X(f, l, 21) X(f, l, 22) X(f, l, 23) 260 #endif // #ifdef BETTER_ENUMS_MACRO_FILE else case 269 template <
typename T>
270 BETTER_ENUMS_CONSTEXPR_
inline T _default()
272 return static_cast<typename T::_enumerated
>(0);
276 BETTER_ENUMS_CONSTEXPR_
inline const char* _default<const char*>()
278 return BETTER_ENUMS_NULLPTR;
282 BETTER_ENUMS_CONSTEXPR_
inline std::size_t _default<std::size_t>()
287 template <
typename T>
289 BETTER_ENUMS_CONSTEXPR_ optional() :
290 _valid(false), _value(_default<T>()) { }
292 BETTER_ENUMS_CONSTEXPR_ optional(T v) : _valid(true), _value(v) { }
294 BETTER_ENUMS_CONSTEXPR_
const T& operator *()
const {
return _value; }
295 BETTER_ENUMS_CONSTEXPR_
const T* operator ->()
const {
return &_value; }
297 BETTER_ENUMS_CONSTEXPR_
operator bool()
const {
return _valid; }
299 BETTER_ENUMS_CONSTEXPR_
const T& value()
const {
return _value; }
306 template <
typename CastTo,
typename Element>
307 BETTER_ENUMS_CONSTEXPR_
static optional<CastTo>
308 _map_index(
const Element *array, optional<std::size_t> index)
310 return index ?
static_cast<CastTo
>(array[*index]) : optional<CastTo>();
313 #ifdef BETTER_ENUMS_VC2008_WORKAROUNDS 315 #define BETTER_ENUMS_OR_THROW \ 317 throw std::runtime_error(message); \ 323 #define BETTER_ENUMS_OR_THROW \ 324 return maybe ? *maybe : throw std::runtime_error(message); 328 BETTER_ENUMS_IF_EXCEPTIONS(
329 template <typename T>
330 BETTER_ENUMS_CONSTEXPR_
static T _or_throw(optional<T> maybe,
333 BETTER_ENUMS_OR_THROW
337 template <typename T>
338 BETTER_ENUMS_CONSTEXPR_
static T* _or_null(optional<T*> maybe)
340 return maybe ? *maybe : BETTER_ENUMS_NULLPTR;
350 template <
typename T,
typename U>
351 BETTER_ENUMS_CONSTEXPR_ U
352 continue_with(T ignored BETTER_ENUMS_UNUSED, U value) {
return value; }
358 template <
typename EnumType>
360 explicit BETTER_ENUMS_CONSTEXPR_ _eat_assign(EnumType value) : _value(value)
363 template <
typename Any>
364 BETTER_ENUMS_CONSTEXPR_
const _eat_assign&
365 operator =(Any dummy BETTER_ENUMS_UNUSED)
const {
return *
this; }
367 BETTER_ENUMS_CONSTEXPR_
operator EnumType ()
const {
return _value; }
377 template <
typename Element>
379 typedef const Element* iterator;
381 BETTER_ENUMS_CONSTEXPR_ iterator begin()
const {
return iterator(_array); }
382 BETTER_ENUMS_CONSTEXPR_ iterator end()
const 383 {
return iterator(_array + _size); }
384 BETTER_ENUMS_CONSTEXPR_ std::size_t
size()
const {
return _size; }
385 BETTER_ENUMS_CONSTEXPR_
const Element& operator [](std::size_t index)
const 386 {
return _array[index]; }
388 BETTER_ENUMS_CONSTEXPR_ _Iterable(
const Element *array, std::size_t s) :
389 _array(array), _size(s) { }
392 const Element *
const _array;
393 const std::size_t _size;
400 BETTER_ENUMS_CONSTEXPR_
static const char *_name_enders =
"= \t\n";
402 BETTER_ENUMS_CONSTEXPR_
inline bool _ends_name(
char c, std::size_t index = 0)
405 c == _name_enders[index] ?
true :
406 _name_enders[index] ==
'\0' ?
false :
407 _ends_name(c, index + 1);
410 BETTER_ENUMS_CONSTEXPR_
inline bool _has_initializer(
const char *s,
411 std::size_t index = 0)
414 s[index] ==
'\0' ?
false :
415 s[index] ==
'=' ?
true :
416 _has_initializer(s, index + 1);
419 BETTER_ENUMS_CONSTEXPR_
inline std::size_t
420 _constant_length(
const char *s, std::size_t index = 0)
422 return _ends_name(s[index]) ? index : _constant_length(s, index + 1);
425 BETTER_ENUMS_CONSTEXPR_
inline char 426 _select(
const char *from, std::size_t from_length, std::size_t index)
428 return index >= from_length ?
'\0' : from[index];
431 BETTER_ENUMS_CONSTEXPR_
inline char _to_lower_ascii(
char c)
433 return c >= 0x41 && c <= 0x5A ? static_cast<char>(c + 0x20) : c;
436 BETTER_ENUMS_CONSTEXPR_
inline bool _names_match(
const char *stringizedName,
437 const char *referenceName,
438 std::size_t index = 0)
441 _ends_name(stringizedName[index]) ? referenceName[index] ==
'\0' :
442 referenceName[index] ==
'\0' ?
false :
443 stringizedName[index] != referenceName[index] ?
false :
444 _names_match(stringizedName, referenceName, index + 1);
447 BETTER_ENUMS_CONSTEXPR_
inline bool 448 _names_match_nocase(
const char *stringizedName,
const char *referenceName,
449 std::size_t index = 0)
452 _ends_name(stringizedName[index]) ? referenceName[index] ==
'\0' :
453 referenceName[index] ==
'\0' ?
false :
454 _to_lower_ascii(stringizedName[index]) !=
455 _to_lower_ascii(referenceName[index]) ?
false :
456 _names_match_nocase(stringizedName, referenceName, index + 1);
459 inline void _trim_names(
const char *
const *raw_names,
460 const char **trimmed_names,
461 char *storage, std::size_t count)
463 std::size_t offset = 0;
465 for (std::size_t index = 0; index < count; ++index) {
466 trimmed_names[index] = storage + offset;
468 std::size_t trimmed_length =
469 std::strcspn(raw_names[index], _name_enders);
470 storage[offset + trimmed_length] =
'\0';
472 std::size_t raw_length = std::strlen(raw_names[index]);
473 offset += raw_length + 1;
480 template <
typename Enum>
481 struct _initialize_at_program_start {
482 _initialize_at_program_start() { Enum::initialize(); }
491 #define BETTER_ENUMS_EAT_ASSIGN_SINGLE(EnumType, index, expression) \ 492 ((::better_enums::_eat_assign<EnumType>)EnumType::expression), 494 #define BETTER_ENUMS_EAT_ASSIGN(EnumType, ...) \ 496 BETTER_ENUMS_PP_MAP( \ 497 BETTER_ENUMS_EAT_ASSIGN_SINGLE, EnumType, __VA_ARGS__)) 501 #ifdef BETTER_ENUMS_HAVE_CONSTEXPR 505 #define BETTER_ENUMS_SELECT_SINGLE_CHARACTER(from, from_length, index) \ 506 ::better_enums::_select(from, from_length, index), 508 #define BETTER_ENUMS_SELECT_CHARACTERS(from, from_length) \ 509 BETTER_ENUMS_ITERATE( \ 510 BETTER_ENUMS_SELECT_SINGLE_CHARACTER, from, from_length) 514 #define BETTER_ENUMS_TRIM_SINGLE_STRING(ignored, index, expression) \ 515 constexpr std::size_t _length_ ## index = \ 516 ::better_enums::_constant_length(#expression); \ 517 constexpr const char _trimmed_ ## index [] = \ 518 { BETTER_ENUMS_SELECT_CHARACTERS(#expression, _length_ ## index) }; \ 519 constexpr const char *_final_ ## index = \ 520 ::better_enums::_has_initializer(#expression) ? \ 521 _trimmed_ ## index : #expression; 523 #define BETTER_ENUMS_TRIM_STRINGS(...) \ 525 BETTER_ENUMS_PP_MAP( \ 526 BETTER_ENUMS_TRIM_SINGLE_STRING, ignored, __VA_ARGS__)) 530 #define BETTER_ENUMS_REFER_TO_SINGLE_STRING(ignored, index, expression) \ 533 #define BETTER_ENUMS_REFER_TO_STRINGS(...) \ 535 BETTER_ENUMS_PP_MAP( \ 536 BETTER_ENUMS_REFER_TO_SINGLE_STRING, ignored, __VA_ARGS__)) 540 #endif // #ifdef BETTER_ENUMS_HAVE_CONSTEXPR 544 #define BETTER_ENUMS_STRINGIZE_SINGLE(ignored, index, expression) #expression, 546 #define BETTER_ENUMS_STRINGIZE(...) \ 548 BETTER_ENUMS_PP_MAP( \ 549 BETTER_ENUMS_STRINGIZE_SINGLE, ignored, __VA_ARGS__)) 551 #define BETTER_ENUMS_RESERVE_STORAGE_SINGLE(ignored, index, expression) \ 554 #define BETTER_ENUMS_RESERVE_STORAGE(...) \ 556 BETTER_ENUMS_PP_MAP( \ 557 BETTER_ENUMS_RESERVE_STORAGE_SINGLE, ignored, __VA_ARGS__)) 563 #define BETTER_ENUMS_NS(EnumType) better_enums_data_ ## EnumType 565 #ifdef BETTER_ENUMS_VC2008_WORKAROUNDS 567 #define BETTER_ENUMS_COPY_CONSTRUCTOR(Enum) \ 568 BETTER_ENUMS_CONSTEXPR_ Enum(const Enum &other) : \ 569 _value(other._value) { } 573 #define BETTER_ENUMS_COPY_CONSTRUCTOR(Enum) 577 #define BETTER_ENUMS_TYPE(SetUnderlyingType, SwitchType, GenerateSwitchType, \ 578 GenerateStrings, ToStringConstexpr, \ 579 DeclareInitialize, DefineInitialize, CallInitialize, \ 580 Enum, Underlying, ...) \ 582 namespace better_enums_data_ ## Enum { \ 584 BETTER_ENUMS_ID(GenerateSwitchType(Underlying, __VA_ARGS__)) \ 590 typedef ::better_enums::optional<Enum> _optional; \ 591 typedef ::better_enums::optional<std::size_t> _optional_index; \ 594 typedef Underlying _integral; \ 596 enum _enumerated SetUnderlyingType(Underlying) { __VA_ARGS__ }; \ 598 BETTER_ENUMS_CONSTEXPR_ Enum(_enumerated value) : _value(value) { } \ 600 BETTER_ENUMS_COPY_CONSTRUCTOR(Enum) \ 602 BETTER_ENUMS_CONSTEXPR_ operator SwitchType(Enum)() const \ 604 return SwitchType(Enum)(_value); \ 607 BETTER_ENUMS_CONSTEXPR_ _integral _to_integral() const; \ 608 BETTER_ENUMS_IF_EXCEPTIONS( \ 609 BETTER_ENUMS_CONSTEXPR_ static Enum _from_integral(_integral value); \ 611 BETTER_ENUMS_CONSTEXPR_ static Enum \ 612 _from_integral_unchecked(_integral value); \ 613 BETTER_ENUMS_CONSTEXPR_ static _optional \ 614 _from_integral_nothrow(_integral value); \ 616 ToStringConstexpr const char* _to_string() const; \ 617 BETTER_ENUMS_IF_EXCEPTIONS( \ 618 BETTER_ENUMS_CONSTEXPR_ static Enum _from_string(const char *name); \ 620 BETTER_ENUMS_CONSTEXPR_ static _optional \ 621 _from_string_nothrow(const char *name); \ 623 BETTER_ENUMS_IF_EXCEPTIONS( \ 624 BETTER_ENUMS_CONSTEXPR_ static Enum _from_string_nocase(const char *name); \ 626 BETTER_ENUMS_CONSTEXPR_ static _optional \ 627 _from_string_nocase_nothrow(const char *name); \ 629 BETTER_ENUMS_CONSTEXPR_ static bool _is_valid(_integral value); \ 630 BETTER_ENUMS_CONSTEXPR_ static bool _is_valid(const char *name); \ 631 BETTER_ENUMS_CONSTEXPR_ static bool _is_valid_nocase(const char *name); \ 633 typedef ::better_enums::_Iterable<Enum> _value_iterable; \ 634 typedef ::better_enums::_Iterable<const char*> _name_iterable; \ 636 typedef _value_iterable::iterator _value_iterator; \ 637 typedef _name_iterable::iterator _name_iterator; \ 639 BETTER_ENUMS_CONSTEXPR_ static const std::size_t _size_constant = \ 640 BETTER_ENUMS_ID(BETTER_ENUMS_PP_COUNT(__VA_ARGS__)); \ 641 BETTER_ENUMS_CONSTEXPR_ static std::size_t _size() \ 642 { return _size_constant; } \ 644 BETTER_ENUMS_CONSTEXPR_ static const char* _name(); \ 645 BETTER_ENUMS_CONSTEXPR_ static _value_iterable _values(); \ 646 ToStringConstexpr static _name_iterable _names(); \ 650 BETTER_ENUMS_DEFAULT_CONSTRUCTOR(Enum) \ 653 explicit BETTER_ENUMS_CONSTEXPR_ Enum(const _integral &value) : \ 658 BETTER_ENUMS_CONSTEXPR_ static _optional_index \ 659 _from_value_loop(_integral value, std::size_t index = 0); \ 660 BETTER_ENUMS_CONSTEXPR_ static _optional_index \ 661 _from_string_loop(const char *name, std::size_t index = 0); \ 662 BETTER_ENUMS_CONSTEXPR_ static _optional_index \ 663 _from_string_nocase_loop(const char *name, std::size_t index = 0); \ 665 friend struct ::better_enums::_initialize_at_program_start<Enum>; \ 668 namespace better_enums_data_ ## Enum { \ 670 static ::better_enums::_initialize_at_program_start<Enum> \ 671 _force_initialization; \ 673 enum _PutNamesInThisScopeAlso { __VA_ARGS__ }; \ 675 BETTER_ENUMS_CONSTEXPR_ const Enum _value_array[] = \ 676 { BETTER_ENUMS_ID(BETTER_ENUMS_EAT_ASSIGN(Enum, __VA_ARGS__)) }; \ 678 BETTER_ENUMS_ID(GenerateStrings(Enum, __VA_ARGS__)) \ 682 BETTER_ENUMS_UNUSED BETTER_ENUMS_CONSTEXPR_ \ 684 operator +(Enum::_enumerated enumerated) \ 686 return static_cast<Enum>(enumerated); \ 689 BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional_index \ 690 Enum::_from_value_loop(Enum::_integral value, std::size_t index) \ 694 _optional_index() : \ 695 BETTER_ENUMS_NS(Enum)::_value_array[index]._value == value ? \ 696 _optional_index(index) : \ 697 _from_value_loop(value, index + 1); \ 700 BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional_index \ 701 Enum::_from_string_loop(const char *name, std::size_t index) \ 704 index == _size() ? _optional_index() : \ 705 ::better_enums::_names_match( \ 706 BETTER_ENUMS_NS(Enum)::_raw_names()[index], name) ? \ 707 _optional_index(index) : \ 708 _from_string_loop(name, index + 1); \ 711 BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional_index \ 712 Enum::_from_string_nocase_loop(const char *name, std::size_t index) \ 715 index == _size() ? _optional_index() : \ 716 ::better_enums::_names_match_nocase( \ 717 BETTER_ENUMS_NS(Enum)::_raw_names()[index], name) ? \ 718 _optional_index(index) : \ 719 _from_string_nocase_loop(name, index + 1); \ 722 BETTER_ENUMS_CONSTEXPR_ inline Enum::_integral Enum::_to_integral() const \ 724 return _integral(_value); \ 727 BETTER_ENUMS_CONSTEXPR_ inline Enum \ 728 Enum::_from_integral_unchecked(_integral value) \ 730 return static_cast<_enumerated>(value); \ 733 BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional \ 734 Enum::_from_integral_nothrow(_integral value) \ 737 ::better_enums::_map_index<Enum>(BETTER_ENUMS_NS(Enum)::_value_array, \ 738 _from_value_loop(value)); \ 741 BETTER_ENUMS_IF_EXCEPTIONS( \ 742 BETTER_ENUMS_CONSTEXPR_ inline Enum Enum::_from_integral(_integral value) \ 745 ::better_enums::_or_throw(_from_integral_nothrow(value), \ 746 #Enum "::_from_integral: invalid argument"); \ 750 ToStringConstexpr inline const char* Enum::_to_string() const \ 753 ::better_enums::_or_null( \ 754 ::better_enums::_map_index<const char*>( \ 755 BETTER_ENUMS_NS(Enum)::_name_array(), \ 756 _from_value_loop(CallInitialize(_value)))); \ 759 BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional \ 760 Enum::_from_string_nothrow(const char *name) \ 763 ::better_enums::_map_index<Enum>( \ 764 BETTER_ENUMS_NS(Enum)::_value_array, _from_string_loop(name)); \ 767 BETTER_ENUMS_IF_EXCEPTIONS( \ 768 BETTER_ENUMS_CONSTEXPR_ inline Enum Enum::_from_string(const char *name) \ 771 ::better_enums::_or_throw(_from_string_nothrow(name), \ 772 #Enum "::_from_string: invalid argument"); \ 776 BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional \ 777 Enum::_from_string_nocase_nothrow(const char *name) \ 780 ::better_enums::_map_index<Enum>(BETTER_ENUMS_NS(Enum)::_value_array, \ 781 _from_string_nocase_loop(name)); \ 784 BETTER_ENUMS_IF_EXCEPTIONS( \ 785 BETTER_ENUMS_CONSTEXPR_ inline Enum Enum::_from_string_nocase(const char *name)\ 788 ::better_enums::_or_throw( \ 789 _from_string_nocase_nothrow(name), \ 790 #Enum "::_from_string_nocase: invalid argument"); \ 794 BETTER_ENUMS_CONSTEXPR_ inline bool Enum::_is_valid(_integral value) \ 796 return _from_value_loop(value); \ 799 BETTER_ENUMS_CONSTEXPR_ inline bool Enum::_is_valid(const char *name) \ 801 return _from_string_loop(name); \ 804 BETTER_ENUMS_CONSTEXPR_ inline bool Enum::_is_valid_nocase(const char *name) \ 806 return _from_string_nocase_loop(name); \ 809 BETTER_ENUMS_CONSTEXPR_ inline const char* Enum::_name() \ 814 BETTER_ENUMS_CONSTEXPR_ inline Enum::_value_iterable Enum::_values() \ 816 return _value_iterable(BETTER_ENUMS_NS(Enum)::_value_array, _size()); \ 819 ToStringConstexpr inline Enum::_name_iterable Enum::_names() \ 822 _name_iterable(BETTER_ENUMS_NS(Enum)::_name_array(), \ 823 CallInitialize(_size())); \ 826 DefineInitialize(Enum) \ 828 BETTER_ENUMS_UNUSED BETTER_ENUMS_CONSTEXPR_ \ 829 inline bool operator ==(const Enum &a, const Enum &b) \ 830 { return a._to_integral() == b._to_integral(); } \ 832 BETTER_ENUMS_UNUSED BETTER_ENUMS_CONSTEXPR_ \ 833 inline bool operator !=(const Enum &a, const Enum &b) \ 834 { return a._to_integral() != b._to_integral(); } \ 836 BETTER_ENUMS_UNUSED BETTER_ENUMS_CONSTEXPR_ \ 837 inline bool operator <(const Enum &a, const Enum &b) \ 838 { return a._to_integral() < b._to_integral(); } \ 840 BETTER_ENUMS_UNUSED BETTER_ENUMS_CONSTEXPR_ \ 841 inline bool operator <=(const Enum &a, const Enum &b) \ 842 { return a._to_integral() <= b._to_integral(); } \ 844 BETTER_ENUMS_UNUSED BETTER_ENUMS_CONSTEXPR_ \ 845 inline bool operator >(const Enum &a, const Enum &b) \ 846 { return a._to_integral() > b._to_integral(); } \ 848 BETTER_ENUMS_UNUSED BETTER_ENUMS_CONSTEXPR_ \ 849 inline bool operator >=(const Enum &a, const Enum &b) \ 850 { return a._to_integral() >= b._to_integral(); } \ 853 template <typename Char, typename Traits> \ 854 std::basic_ostream<Char, Traits>& \ 855 operator <<(std::basic_ostream<Char, Traits>& stream, const Enum &value) \ 857 return stream << value._to_string(); \ 860 template <typename Char, typename Traits> \ 861 std::basic_istream<Char, Traits>& \ 862 operator >>(std::basic_istream<Char, Traits>& stream, Enum &value) \ 864 std::basic_string<Char, Traits> buffer; \ 867 ::better_enums::optional<Enum> converted = \ 868 Enum::_from_string_nothrow(buffer.c_str()); \ 871 value = *converted; \ 873 stream.setstate(std::basic_istream<Char, Traits>::failbit); \ 883 #define BETTER_ENUMS_CXX98_UNDERLYING_TYPE(Underlying) 886 #define BETTER_ENUMS_CXX11_UNDERLYING_TYPE(Underlying) \ 890 #define BETTER_ENUMS_REGULAR_ENUM_SWITCH_TYPE(Type) \ 894 #define BETTER_ENUMS_ENUM_CLASS_SWITCH_TYPE(Type) \ 895 BETTER_ENUMS_NS(Type)::_EnumClassForSwitchStatements 898 #define BETTER_ENUMS_REGULAR_ENUM_SWITCH_TYPE_GENERATE(Underlying, ...) 901 #define BETTER_ENUMS_ENUM_CLASS_SWITCH_TYPE_GENERATE(Underlying, ...) \ 902 enum class _EnumClassForSwitchStatements : Underlying { __VA_ARGS__ }; 905 #define BETTER_ENUMS_CXX98_TRIM_STRINGS_ARRAYS(Enum, ...) \ 906 inline const char** _raw_names() \ 908 static const char *value[] = \ 909 { BETTER_ENUMS_ID(BETTER_ENUMS_STRINGIZE(__VA_ARGS__)) }; \ 913 inline char* _name_storage() \ 915 static char storage[] = \ 916 BETTER_ENUMS_ID(BETTER_ENUMS_RESERVE_STORAGE(__VA_ARGS__)); \ 920 inline const char** _name_array() \ 922 static const char *value[Enum::_size_constant]; \ 926 inline bool& _initialized() \ 928 static bool value = false; \ 933 #define BETTER_ENUMS_CXX11_PARTIAL_CONSTEXPR_TRIM_STRINGS_ARRAYS(Enum, ...) \ 934 constexpr const char *_the_raw_names[] = \ 935 { BETTER_ENUMS_ID(BETTER_ENUMS_STRINGIZE(__VA_ARGS__)) }; \ 937 constexpr const char * const * _raw_names() \ 939 return _the_raw_names; \ 942 inline char* _name_storage() \ 944 static char storage[] = \ 945 BETTER_ENUMS_ID(BETTER_ENUMS_RESERVE_STORAGE(__VA_ARGS__)); \ 949 inline const char** _name_array() \ 951 static const char *value[Enum::_size_constant]; \ 955 inline bool& _initialized() \ 957 static bool value = false; \ 962 #define BETTER_ENUMS_CXX11_FULL_CONSTEXPR_TRIM_STRINGS_ARRAYS(Enum, ...) \ 963 BETTER_ENUMS_ID(BETTER_ENUMS_TRIM_STRINGS(__VA_ARGS__)) \ 965 constexpr const char * const _the_name_array[] = \ 966 { BETTER_ENUMS_ID(BETTER_ENUMS_REFER_TO_STRINGS(__VA_ARGS__)) }; \ 968 constexpr const char * const * _name_array() \ 970 return _the_name_array; \ 973 constexpr const char * const * _raw_names() \ 975 return _the_name_array; \ 979 #define BETTER_ENUMS_NO_CONSTEXPR_TO_STRING_KEYWORD 982 #define BETTER_ENUMS_CONSTEXPR_TO_STRING_KEYWORD \ 986 #define BETTER_ENUMS_DO_DECLARE_INITIALIZE \ 987 static int initialize(); 990 #define BETTER_ENUMS_DECLARE_EMPTY_INITIALIZE \ 991 static int initialize() { return 0; } 994 #define BETTER_ENUMS_DO_DEFINE_INITIALIZE(Enum) \ 995 inline int Enum::initialize() \ 997 if (BETTER_ENUMS_NS(Enum)::_initialized()) \ 1000 ::better_enums::_trim_names(BETTER_ENUMS_NS(Enum)::_raw_names(), \ 1001 BETTER_ENUMS_NS(Enum)::_name_array(), \ 1002 BETTER_ENUMS_NS(Enum)::_name_storage(), \ 1005 BETTER_ENUMS_NS(Enum)::_initialized() = true; \ 1011 #define BETTER_ENUMS_DO_NOT_DEFINE_INITIALIZE(Enum) 1014 #define BETTER_ENUMS_DO_CALL_INITIALIZE(value) \ 1015 ::better_enums::continue_with(initialize(), value) 1018 #define BETTER_ENUMS_DO_NOT_CALL_INITIALIZE(value) \ 1025 #ifdef BETTER_ENUMS_STRICT_CONVERSION 1026 # define BETTER_ENUMS_DEFAULT_SWITCH_TYPE \ 1027 BETTER_ENUMS_ENUM_CLASS_SWITCH_TYPE 1028 # define BETTER_ENUMS_DEFAULT_SWITCH_TYPE_GENERATE \ 1029 BETTER_ENUMS_ENUM_CLASS_SWITCH_TYPE_GENERATE 1031 # define BETTER_ENUMS_DEFAULT_SWITCH_TYPE \ 1032 BETTER_ENUMS_REGULAR_ENUM_SWITCH_TYPE 1033 # define BETTER_ENUMS_DEFAULT_SWITCH_TYPE_GENERATE \ 1034 BETTER_ENUMS_REGULAR_ENUM_SWITCH_TYPE_GENERATE 1039 #ifndef BETTER_ENUMS_DEFAULT_CONSTRUCTOR 1040 # define BETTER_ENUMS_DEFAULT_CONSTRUCTOR(Enum) \ 1042 Enum() : _value(0) { } 1047 #ifdef BETTER_ENUMS_HAVE_CONSTEXPR 1049 #ifdef BETTER_ENUMS_CONSTEXPR_TO_STRING 1050 # define BETTER_ENUMS_DEFAULT_TRIM_STRINGS_ARRAYS \ 1051 BETTER_ENUMS_CXX11_FULL_CONSTEXPR_TRIM_STRINGS_ARRAYS 1052 # define BETTER_ENUMS_DEFAULT_TO_STRING_KEYWORD \ 1053 BETTER_ENUMS_CONSTEXPR_TO_STRING_KEYWORD 1054 # define BETTER_ENUMS_DEFAULT_DECLARE_INITIALIZE \ 1055 BETTER_ENUMS_DECLARE_EMPTY_INITIALIZE 1056 # define BETTER_ENUMS_DEFAULT_DEFINE_INITIALIZE \ 1057 BETTER_ENUMS_DO_NOT_DEFINE_INITIALIZE 1058 # define BETTER_ENUMS_DEFAULT_CALL_INITIALIZE \ 1059 BETTER_ENUMS_DO_NOT_CALL_INITIALIZE 1061 # define BETTER_ENUMS_DEFAULT_TRIM_STRINGS_ARRAYS \ 1062 BETTER_ENUMS_CXX11_PARTIAL_CONSTEXPR_TRIM_STRINGS_ARRAYS 1063 # define BETTER_ENUMS_DEFAULT_TO_STRING_KEYWORD \ 1064 BETTER_ENUMS_NO_CONSTEXPR_TO_STRING_KEYWORD 1065 # define BETTER_ENUMS_DEFAULT_DECLARE_INITIALIZE \ 1066 BETTER_ENUMS_DO_DECLARE_INITIALIZE 1067 # define BETTER_ENUMS_DEFAULT_DEFINE_INITIALIZE \ 1068 BETTER_ENUMS_DO_DEFINE_INITIALIZE 1069 # define BETTER_ENUMS_DEFAULT_CALL_INITIALIZE \ 1070 BETTER_ENUMS_DO_CALL_INITIALIZE 1077 #define BETTER_ENUM(Enum, Underlying, ...) \ 1078 BETTER_ENUMS_ID(BETTER_ENUMS_TYPE( \ 1079 BETTER_ENUMS_CXX11_UNDERLYING_TYPE, \ 1080 BETTER_ENUMS_DEFAULT_SWITCH_TYPE, \ 1081 BETTER_ENUMS_DEFAULT_SWITCH_TYPE_GENERATE, \ 1082 BETTER_ENUMS_DEFAULT_TRIM_STRINGS_ARRAYS, \ 1083 BETTER_ENUMS_DEFAULT_TO_STRING_KEYWORD, \ 1084 BETTER_ENUMS_DEFAULT_DECLARE_INITIALIZE, \ 1085 BETTER_ENUMS_DEFAULT_DEFINE_INITIALIZE, \ 1086 BETTER_ENUMS_DEFAULT_CALL_INITIALIZE, \ 1087 Enum, Underlying, __VA_ARGS__)) 1089 #define SLOW_ENUM(Enum, Underlying, ...) \ 1090 BETTER_ENUMS_ID(BETTER_ENUMS_TYPE( \ 1091 BETTER_ENUMS_CXX11_UNDERLYING_TYPE, \ 1092 BETTER_ENUMS_DEFAULT_SWITCH_TYPE, \ 1093 BETTER_ENUMS_DEFAULT_SWITCH_TYPE_GENERATE, \ 1094 BETTER_ENUMS_CXX11_FULL_CONSTEXPR_TRIM_STRINGS_ARRAYS, \ 1095 BETTER_ENUMS_CONSTEXPR_TO_STRING_KEYWORD, \ 1096 BETTER_ENUMS_DECLARE_EMPTY_INITIALIZE, \ 1097 BETTER_ENUMS_DO_NOT_DEFINE_INITIALIZE, \ 1098 BETTER_ENUMS_DO_NOT_CALL_INITIALIZE, \ 1099 Enum, Underlying, __VA_ARGS__)) 1103 #define BETTER_ENUM(Enum, Underlying, ...) \ 1104 BETTER_ENUMS_ID(BETTER_ENUMS_TYPE( \ 1105 BETTER_ENUMS_CXX98_UNDERLYING_TYPE, \ 1106 BETTER_ENUMS_DEFAULT_SWITCH_TYPE, \ 1107 BETTER_ENUMS_DEFAULT_SWITCH_TYPE_GENERATE, \ 1108 BETTER_ENUMS_CXX98_TRIM_STRINGS_ARRAYS, \ 1109 BETTER_ENUMS_NO_CONSTEXPR_TO_STRING_KEYWORD, \ 1110 BETTER_ENUMS_DO_DECLARE_INITIALIZE, \ 1111 BETTER_ENUMS_DO_DEFINE_INITIALIZE, \ 1112 BETTER_ENUMS_DO_CALL_INITIALIZE, \ 1113 Enum, Underlying, __VA_ARGS__)) 1123 template <
typename T>
1124 struct map_compare {
1125 BETTER_ENUMS_CONSTEXPR_
static bool less(
const T& a,
const T& b)
1130 struct map_compare<const char*> {
1131 BETTER_ENUMS_CONSTEXPR_
static bool less(
const char *a,
const char *b)
1132 {
return less_loop(a, b); }
1135 BETTER_ENUMS_CONSTEXPR_
static bool 1136 less_loop(
const char *a,
const char *b,
size_t index = 0)
1139 a[index] != b[index] ? a[index] < b[index] :
1140 a[index] ==
'\0' ?
false :
1141 less_loop(a, b, index + 1);
1145 template <
typename Enum,
typename T,
typename Compare = map_compare<T> >
1147 typedef T (*
function)(Enum);
1149 BETTER_ENUMS_CONSTEXPR_
explicit map(
function f) : _f(f) { }
1151 BETTER_ENUMS_CONSTEXPR_ T from_enum(Enum value)
const {
return _f(value); }
1152 BETTER_ENUMS_CONSTEXPR_ T operator [](Enum value)
const 1153 {
return _f(value); }
1155 BETTER_ENUMS_CONSTEXPR_ Enum to_enum(T value)
const 1158 _or_throw(to_enum_nothrow(value),
"map::to_enum: invalid argument");
1161 BETTER_ENUMS_CONSTEXPR_ optional<Enum>
1162 to_enum_nothrow(T value,
size_t index = 0)
const 1165 index >= Enum::_size() ? optional<Enum>() :
1166 Compare::less(_f(Enum::_values()[index]), value) ||
1167 Compare::less(value, _f(Enum::_values()[index])) ?
1168 to_enum_nothrow(value, index + 1) :
1169 Enum::_values()[index];
1176 template <
typename Enum,
typename T>
1177 BETTER_ENUMS_CONSTEXPR_ map<Enum, T> make_map(T (*f)(Enum))
1179 return map<Enum, T>(f);
1184 #endif // #ifndef BETTER_ENUMS_ENUM_H size_t size(std::string const &path)
Get the size of the file in bytes.
Definition: fsutils.cpp:475