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")
24# define BETTER_ENUMS_IGNORE_ATTRIBUTES_HEADER
25# define BETTER_ENUMS_IGNORE_ATTRIBUTES_BEGIN
26# define BETTER_ENUMS_IGNORE_ATTRIBUTES_END
28# define BETTER_ENUMS_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100)
29# if BETTER_ENUMS_GCC_VERSION > 40400
30# define BETTER_ENUMS_IGNORE_OLD_CAST_HEADER _Pragma("GCC diagnostic push")
31# define BETTER_ENUMS_IGNORE_OLD_CAST_BEGIN _Pragma("GCC diagnostic ignored \"-Wold-style-cast\"")
32# define BETTER_ENUMS_IGNORE_OLD_CAST_END _Pragma("GCC diagnostic pop")
33# if (BETTER_ENUMS_GCC_VERSION >= 70300)
34# define BETTER_ENUMS_IGNORE_ATTRIBUTES_HEADER _Pragma("GCC diagnostic push")
35# define BETTER_ENUMS_IGNORE_ATTRIBUTES_BEGIN _Pragma("GCC diagnostic ignored \"-Wattributes\"")
36# define BETTER_ENUMS_IGNORE_ATTRIBUTES_END _Pragma("GCC diagnostic pop")
38# define BETTER_ENUMS_IGNORE_ATTRIBUTES_HEADER
39# define BETTER_ENUMS_IGNORE_ATTRIBUTES_BEGIN
40# define BETTER_ENUMS_IGNORE_ATTRIBUTES_END
43# define BETTER_ENUMS_IGNORE_OLD_CAST_HEADER
44# define BETTER_ENUMS_IGNORE_OLD_CAST_BEGIN
45# define BETTER_ENUMS_IGNORE_OLD_CAST_END
46# define BETTER_ENUMS_IGNORE_ATTRIBUTES_HEADER
47# define BETTER_ENUMS_IGNORE_ATTRIBUTES_BEGIN
48# define BETTER_ENUMS_IGNORE_ATTRIBUTES_END
52# define BETTER_ENUMS_IGNORE_OLD_CAST_HEADER
53# define BETTER_ENUMS_IGNORE_OLD_CAST_BEGIN
54# define BETTER_ENUMS_IGNORE_OLD_CAST_END
55# define BETTER_ENUMS_IGNORE_ATTRIBUTES_HEADER
56# define BETTER_ENUMS_IGNORE_ATTRIBUTES_BEGIN
57# define BETTER_ENUMS_IGNORE_ATTRIBUTES_END
64# if __has_feature(cxx_constexpr)
65# define BETTER_ENUMS_HAVE_CONSTEXPR
67# if !defined(__EXCEPTIONS) || !__has_feature(cxx_exceptions)
68# define BETTER_ENUMS_NO_EXCEPTIONS
71# if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
72# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6))
73# define BETTER_ENUMS_HAVE_CONSTEXPR
77# define BETTER_ENUMS_NO_EXCEPTIONS
84# define BETTER_ENUMS_HAVE_CONSTEXPR
87# if __has_feature(cxx_constexpr)
88# define BETTER_ENUMS_HAVE_CONSTEXPR
92# define BETTER_ENUMS_NO_EXCEPTIONS
95# define BETTER_ENUMS_VC2008_WORKAROUNDS
99#ifdef BETTER_ENUMS_CONSTEXPR
100# define BETTER_ENUMS_HAVE_CONSTEXPR
103#ifdef BETTER_ENUMS_NO_CONSTEXPR
104# ifdef BETTER_ENUMS_HAVE_CONSTEXPR
105# undef BETTER_ENUMS_HAVE_CONSTEXPR
117#ifdef BETTER_ENUMS_HAVE_CONSTEXPR
118# define BETTER_ENUMS_CONSTEXPR_ constexpr
119# define BETTER_ENUMS_NULLPTR nullptr
121# define BETTER_ENUMS_CONSTEXPR_
122# define BETTER_ENUMS_NULLPTR NULL
125#ifndef BETTER_ENUMS_NO_EXCEPTIONS
126# define BETTER_ENUMS_IF_EXCEPTIONS(x) x
128# define BETTER_ENUMS_IF_EXCEPTIONS(x)
132# define BETTER_ENUMS_UNUSED __attribute__((__unused__))
134# define BETTER_ENUMS_UNUSED
141#ifdef BETTER_ENUMS_MACRO_FILE
142# include BETTER_ENUMS_MACRO_FILE
145#define BETTER_ENUMS_PP_MAP(macro, data, ...) \
147 BETTER_ENUMS_APPLY( \
148 BETTER_ENUMS_PP_MAP_VAR_COUNT, \
149 BETTER_ENUMS_PP_COUNT(__VA_ARGS__)) \
150 (macro, data, __VA_ARGS__))
152#define BETTER_ENUMS_PP_MAP_VAR_COUNT(count) BETTER_ENUMS_M ## count
154#define BETTER_ENUMS_APPLY(macro, ...) BETTER_ENUMS_ID(macro(__VA_ARGS__))
156#define BETTER_ENUMS_ID(x) x
158#define BETTER_ENUMS_M1(m, d, x) m(d,0,x)
159#define BETTER_ENUMS_M2(m,d,x,...) m(d,1,x) \
160 BETTER_ENUMS_ID(BETTER_ENUMS_M1(m,d,__VA_ARGS__))
161#define BETTER_ENUMS_M3(m,d,x,...) m(d,2,x) \
162 BETTER_ENUMS_ID(BETTER_ENUMS_M2(m,d,__VA_ARGS__))
163#define BETTER_ENUMS_M4(m,d,x,...) m(d,3,x) \
164 BETTER_ENUMS_ID(BETTER_ENUMS_M3(m,d,__VA_ARGS__))
165#define BETTER_ENUMS_M5(m,d,x,...) m(d,4,x) \
166 BETTER_ENUMS_ID(BETTER_ENUMS_M4(m,d,__VA_ARGS__))
167#define BETTER_ENUMS_M6(m,d,x,...) m(d,5,x) \
168 BETTER_ENUMS_ID(BETTER_ENUMS_M5(m,d,__VA_ARGS__))
169#define BETTER_ENUMS_M7(m,d,x,...) m(d,6,x) \
170 BETTER_ENUMS_ID(BETTER_ENUMS_M6(m,d,__VA_ARGS__))
171#define BETTER_ENUMS_M8(m,d,x,...) m(d,7,x) \
172 BETTER_ENUMS_ID(BETTER_ENUMS_M7(m,d,__VA_ARGS__))
173#define BETTER_ENUMS_M9(m,d,x,...) m(d,8,x) \
174 BETTER_ENUMS_ID(BETTER_ENUMS_M8(m,d,__VA_ARGS__))
175#define BETTER_ENUMS_M10(m,d,x,...) m(d,9,x) \
176 BETTER_ENUMS_ID(BETTER_ENUMS_M9(m,d,__VA_ARGS__))
177#define BETTER_ENUMS_M11(m,d,x,...) m(d,10,x) \
178 BETTER_ENUMS_ID(BETTER_ENUMS_M10(m,d,__VA_ARGS__))
179#define BETTER_ENUMS_M12(m,d,x,...) m(d,11,x) \
180 BETTER_ENUMS_ID(BETTER_ENUMS_M11(m,d,__VA_ARGS__))
181#define BETTER_ENUMS_M13(m,d,x,...) m(d,12,x) \
182 BETTER_ENUMS_ID(BETTER_ENUMS_M12(m,d,__VA_ARGS__))
183#define BETTER_ENUMS_M14(m,d,x,...) m(d,13,x) \
184 BETTER_ENUMS_ID(BETTER_ENUMS_M13(m,d,__VA_ARGS__))
185#define BETTER_ENUMS_M15(m,d,x,...) m(d,14,x) \
186 BETTER_ENUMS_ID(BETTER_ENUMS_M14(m,d,__VA_ARGS__))
187#define BETTER_ENUMS_M16(m,d,x,...) m(d,15,x) \
188 BETTER_ENUMS_ID(BETTER_ENUMS_M15(m,d,__VA_ARGS__))
189#define BETTER_ENUMS_M17(m,d,x,...) m(d,16,x) \
190 BETTER_ENUMS_ID(BETTER_ENUMS_M16(m,d,__VA_ARGS__))
191#define BETTER_ENUMS_M18(m,d,x,...) m(d,17,x) \
192 BETTER_ENUMS_ID(BETTER_ENUMS_M17(m,d,__VA_ARGS__))
193#define BETTER_ENUMS_M19(m,d,x,...) m(d,18,x) \
194 BETTER_ENUMS_ID(BETTER_ENUMS_M18(m,d,__VA_ARGS__))
195#define BETTER_ENUMS_M20(m,d,x,...) m(d,19,x) \
196 BETTER_ENUMS_ID(BETTER_ENUMS_M19(m,d,__VA_ARGS__))
197#define BETTER_ENUMS_M21(m,d,x,...) m(d,20,x) \
198 BETTER_ENUMS_ID(BETTER_ENUMS_M20(m,d,__VA_ARGS__))
199#define BETTER_ENUMS_M22(m,d,x,...) m(d,21,x) \
200 BETTER_ENUMS_ID(BETTER_ENUMS_M21(m,d,__VA_ARGS__))
201#define BETTER_ENUMS_M23(m,d,x,...) m(d,22,x) \
202 BETTER_ENUMS_ID(BETTER_ENUMS_M22(m,d,__VA_ARGS__))
203#define BETTER_ENUMS_M24(m,d,x,...) m(d,23,x) \
204 BETTER_ENUMS_ID(BETTER_ENUMS_M23(m,d,__VA_ARGS__))
205#define BETTER_ENUMS_M25(m,d,x,...) m(d,24,x) \
206 BETTER_ENUMS_ID(BETTER_ENUMS_M24(m,d,__VA_ARGS__))
207#define BETTER_ENUMS_M26(m,d,x,...) m(d,25,x) \
208 BETTER_ENUMS_ID(BETTER_ENUMS_M25(m,d,__VA_ARGS__))
209#define BETTER_ENUMS_M27(m,d,x,...) m(d,26,x) \
210 BETTER_ENUMS_ID(BETTER_ENUMS_M26(m,d,__VA_ARGS__))
211#define BETTER_ENUMS_M28(m,d,x,...) m(d,27,x) \
212 BETTER_ENUMS_ID(BETTER_ENUMS_M27(m,d,__VA_ARGS__))
213#define BETTER_ENUMS_M29(m,d,x,...) m(d,28,x) \
214 BETTER_ENUMS_ID(BETTER_ENUMS_M28(m,d,__VA_ARGS__))
215#define BETTER_ENUMS_M30(m,d,x,...) m(d,29,x) \
216 BETTER_ENUMS_ID(BETTER_ENUMS_M29(m,d,__VA_ARGS__))
217#define BETTER_ENUMS_M31(m,d,x,...) m(d,30,x) \
218 BETTER_ENUMS_ID(BETTER_ENUMS_M30(m,d,__VA_ARGS__))
219#define BETTER_ENUMS_M32(m,d,x,...) m(d,31,x) \
220 BETTER_ENUMS_ID(BETTER_ENUMS_M31(m,d,__VA_ARGS__))
221#define BETTER_ENUMS_M33(m,d,x,...) m(d,32,x) \
222 BETTER_ENUMS_ID(BETTER_ENUMS_M32(m,d,__VA_ARGS__))
223#define BETTER_ENUMS_M34(m,d,x,...) m(d,33,x) \
224 BETTER_ENUMS_ID(BETTER_ENUMS_M33(m,d,__VA_ARGS__))
225#define BETTER_ENUMS_M35(m,d,x,...) m(d,34,x) \
226 BETTER_ENUMS_ID(BETTER_ENUMS_M34(m,d,__VA_ARGS__))
227#define BETTER_ENUMS_M36(m,d,x,...) m(d,35,x) \
228 BETTER_ENUMS_ID(BETTER_ENUMS_M35(m,d,__VA_ARGS__))
229#define BETTER_ENUMS_M37(m,d,x,...) m(d,36,x) \
230 BETTER_ENUMS_ID(BETTER_ENUMS_M36(m,d,__VA_ARGS__))
231#define BETTER_ENUMS_M38(m,d,x,...) m(d,37,x) \
232 BETTER_ENUMS_ID(BETTER_ENUMS_M37(m,d,__VA_ARGS__))
233#define BETTER_ENUMS_M39(m,d,x,...) m(d,38,x) \
234 BETTER_ENUMS_ID(BETTER_ENUMS_M38(m,d,__VA_ARGS__))
235#define BETTER_ENUMS_M40(m,d,x,...) m(d,39,x) \
236 BETTER_ENUMS_ID(BETTER_ENUMS_M39(m,d,__VA_ARGS__))
237#define BETTER_ENUMS_M41(m,d,x,...) m(d,40,x) \
238 BETTER_ENUMS_ID(BETTER_ENUMS_M40(m,d,__VA_ARGS__))
239#define BETTER_ENUMS_M42(m,d,x,...) m(d,41,x) \
240 BETTER_ENUMS_ID(BETTER_ENUMS_M41(m,d,__VA_ARGS__))
241#define BETTER_ENUMS_M43(m,d,x,...) m(d,42,x) \
242 BETTER_ENUMS_ID(BETTER_ENUMS_M42(m,d,__VA_ARGS__))
243#define BETTER_ENUMS_M44(m,d,x,...) m(d,43,x) \
244 BETTER_ENUMS_ID(BETTER_ENUMS_M43(m,d,__VA_ARGS__))
245#define BETTER_ENUMS_M45(m,d,x,...) m(d,44,x) \
246 BETTER_ENUMS_ID(BETTER_ENUMS_M44(m,d,__VA_ARGS__))
247#define BETTER_ENUMS_M46(m,d,x,...) m(d,45,x) \
248 BETTER_ENUMS_ID(BETTER_ENUMS_M45(m,d,__VA_ARGS__))
249#define BETTER_ENUMS_M47(m,d,x,...) m(d,46,x) \
250 BETTER_ENUMS_ID(BETTER_ENUMS_M46(m,d,__VA_ARGS__))
251#define BETTER_ENUMS_M48(m,d,x,...) m(d,47,x) \
252 BETTER_ENUMS_ID(BETTER_ENUMS_M47(m,d,__VA_ARGS__))
253#define BETTER_ENUMS_M49(m,d,x,...) m(d,48,x) \
254 BETTER_ENUMS_ID(BETTER_ENUMS_M48(m,d,__VA_ARGS__))
255#define BETTER_ENUMS_M50(m,d,x,...) m(d,49,x) \
256 BETTER_ENUMS_ID(BETTER_ENUMS_M49(m,d,__VA_ARGS__))
257#define BETTER_ENUMS_M51(m,d,x,...) m(d,50,x) \
258 BETTER_ENUMS_ID(BETTER_ENUMS_M50(m,d,__VA_ARGS__))
259#define BETTER_ENUMS_M52(m,d,x,...) m(d,51,x) \
260 BETTER_ENUMS_ID(BETTER_ENUMS_M51(m,d,__VA_ARGS__))
261#define BETTER_ENUMS_M53(m,d,x,...) m(d,52,x) \
262 BETTER_ENUMS_ID(BETTER_ENUMS_M52(m,d,__VA_ARGS__))
263#define BETTER_ENUMS_M54(m,d,x,...) m(d,53,x) \
264 BETTER_ENUMS_ID(BETTER_ENUMS_M53(m,d,__VA_ARGS__))
265#define BETTER_ENUMS_M55(m,d,x,...) m(d,54,x) \
266 BETTER_ENUMS_ID(BETTER_ENUMS_M54(m,d,__VA_ARGS__))
267#define BETTER_ENUMS_M56(m,d,x,...) m(d,55,x) \
268 BETTER_ENUMS_ID(BETTER_ENUMS_M55(m,d,__VA_ARGS__))
269#define BETTER_ENUMS_M57(m,d,x,...) m(d,56,x) \
270 BETTER_ENUMS_ID(BETTER_ENUMS_M56(m,d,__VA_ARGS__))
271#define BETTER_ENUMS_M58(m,d,x,...) m(d,57,x) \
272 BETTER_ENUMS_ID(BETTER_ENUMS_M57(m,d,__VA_ARGS__))
273#define BETTER_ENUMS_M59(m,d,x,...) m(d,58,x) \
274 BETTER_ENUMS_ID(BETTER_ENUMS_M58(m,d,__VA_ARGS__))
275#define BETTER_ENUMS_M60(m,d,x,...) m(d,59,x) \
276 BETTER_ENUMS_ID(BETTER_ENUMS_M59(m,d,__VA_ARGS__))
277#define BETTER_ENUMS_M61(m,d,x,...) m(d,60,x) \
278 BETTER_ENUMS_ID(BETTER_ENUMS_M60(m,d,__VA_ARGS__))
279#define BETTER_ENUMS_M62(m,d,x,...) m(d,61,x) \
280 BETTER_ENUMS_ID(BETTER_ENUMS_M61(m,d,__VA_ARGS__))
281#define BETTER_ENUMS_M63(m,d,x,...) m(d,62,x) \
282 BETTER_ENUMS_ID(BETTER_ENUMS_M62(m,d,__VA_ARGS__))
283#define BETTER_ENUMS_M64(m,d,x,...) m(d,63,x) \
284 BETTER_ENUMS_ID(BETTER_ENUMS_M63(m,d,__VA_ARGS__))
286#define BETTER_ENUMS_PP_COUNT_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
287 _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, \
288 _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
289 _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, \
290 _56, _57, _58, _59, _60, _61, _62, _63, _64, count, ...) count
292#define BETTER_ENUMS_PP_COUNT(...) \
293 BETTER_ENUMS_ID(BETTER_ENUMS_PP_COUNT_IMPL(__VA_ARGS__, 64, 63, 62, 61, 60,\
294 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42,\
295 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24,\
296 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, \
299#define BETTER_ENUMS_ITERATE(X, f, l) X(f, l, 0) X(f, l, 1) X(f, l, 2) \
300 X(f, l, 3) X(f, l, 4) X(f, l, 5) X(f, l, 6) X(f, l, 7) X(f, l, 8) \
301 X(f, l, 9) X(f, l, 10) X(f, l, 11) X(f, l, 12) X(f, l, 13) X(f, l, 14) \
302 X(f, l, 15) X(f, l, 16) X(f, l, 17) X(f, l, 18) X(f, l, 19) X(f, l, 20) \
303 X(f, l, 21) X(f, l, 22) X(f, l, 23)
317 return static_cast<typename T::_enumerated
>(0);
335 _valid(false), _value(
_default<T>()) { }
351template <
typename CastTo,
typename Element>
358#ifdef BETTER_ENUMS_VC2008_WORKAROUNDS
360#define BETTER_ENUMS_OR_THROW \
362 throw std::runtime_error(message); \
368#define BETTER_ENUMS_OR_THROW \
369 return maybe ? *maybe : throw std::runtime_error(message);
391 return maybe ? *maybe : T::_from_integral_unchecked(0);
401template <
typename T,
typename U>
411template <
typename EnumType>
416 template <
typename Any>
430template <
typename Element>
436 {
return iterator(_array + _size); }
439 {
return _array[index]; }
442 _array(array), _size(s) { }
445 const Element *
const _array;
446 const std::size_t _size;
464 std::size_t index = 0)
467 s[index] ==
'\0' ? false :
468 s[index] ==
'=' ? true :
479_select(
const char *from, std::size_t from_length, std::size_t index)
481 return index >= from_length ?
'\0' : from[index];
486 return c >= 0x41 && c <= 0x5A ? static_cast<char>(c + 0x20) : c;
490 const char *referenceName,
491 std::size_t index = 0)
494 _ends_name(stringizedName[index]) ? referenceName[index] ==
'\0' :
495 referenceName[index] ==
'\0' ? false :
496 stringizedName[index] != referenceName[index] ? false :
502 std::size_t index = 0)
505 _ends_name(stringizedName[index]) ? referenceName[index] ==
'\0' :
506 referenceName[index] ==
'\0' ? false :
513 const char **trimmed_names,
514 char *storage, std::size_t count)
516 std::size_t offset = 0;
518 for (std::size_t index = 0; index < count; ++index) {
519 trimmed_names[index] = storage + offset;
521 std::size_t trimmed_length =
523 storage[offset + trimmed_length] =
'\0';
525 std::size_t raw_length = std::strlen(raw_names[index]);
526 offset += raw_length + 1;
533template <
typename Enum>
544#define BETTER_ENUMS_EAT_ASSIGN_SINGLE(EnumType, index, expression) \
545 (EnumType)((::better_enums::_eat_assign<EnumType>)EnumType::expression),
547#define BETTER_ENUMS_EAT_ASSIGN(EnumType, ...) \
549 BETTER_ENUMS_PP_MAP( \
550 BETTER_ENUMS_EAT_ASSIGN_SINGLE, EnumType, __VA_ARGS__))
554#ifdef BETTER_ENUMS_HAVE_CONSTEXPR
558#define BETTER_ENUMS_SELECT_SINGLE_CHARACTER(from, from_length, index) \
559 ::better_enums::_select(from, from_length, index),
561#define BETTER_ENUMS_SELECT_CHARACTERS(from, from_length) \
562 BETTER_ENUMS_ITERATE( \
563 BETTER_ENUMS_SELECT_SINGLE_CHARACTER, from, from_length)
567#define BETTER_ENUMS_TRIM_SINGLE_STRING(ignored, index, expression) \
568constexpr std::size_t _length_ ## index = \
569 ::better_enums::_constant_length(#expression); \
570constexpr const char _trimmed_ ## index [] = \
571 { BETTER_ENUMS_SELECT_CHARACTERS(#expression, _length_ ## index) }; \
572constexpr const char *_final_ ## index = \
573 ::better_enums::_has_initializer(#expression) ? \
574 _trimmed_ ## index : #expression;
576#define BETTER_ENUMS_TRIM_STRINGS(...) \
578 BETTER_ENUMS_PP_MAP( \
579 BETTER_ENUMS_TRIM_SINGLE_STRING, ignored, __VA_ARGS__))
583#define BETTER_ENUMS_REFER_TO_SINGLE_STRING(ignored, index, expression) \
586#define BETTER_ENUMS_REFER_TO_STRINGS(...) \
588 BETTER_ENUMS_PP_MAP( \
589 BETTER_ENUMS_REFER_TO_SINGLE_STRING, ignored, __VA_ARGS__))
597#define BETTER_ENUMS_STRINGIZE_SINGLE(ignored, index, expression) #expression,
599#define BETTER_ENUMS_STRINGIZE(...) \
601 BETTER_ENUMS_PP_MAP( \
602 BETTER_ENUMS_STRINGIZE_SINGLE, ignored, __VA_ARGS__))
604#define BETTER_ENUMS_RESERVE_STORAGE_SINGLE(ignored, index, expression) \
607#define BETTER_ENUMS_RESERVE_STORAGE(...) \
609 BETTER_ENUMS_PP_MAP( \
610 BETTER_ENUMS_RESERVE_STORAGE_SINGLE, ignored, __VA_ARGS__))
616#define BETTER_ENUMS_NS(EnumType) better_enums_data_ ## EnumType
618#ifdef BETTER_ENUMS_VC2008_WORKAROUNDS
620#define BETTER_ENUMS_COPY_CONSTRUCTOR(Enum) \
621 BETTER_ENUMS_CONSTEXPR_ Enum(const Enum &other) : \
622 _value(other._value) { }
626#define BETTER_ENUMS_COPY_CONSTRUCTOR(Enum)
630#ifndef BETTER_ENUMS_CLASS_ATTRIBUTE
631# define BETTER_ENUMS_CLASS_ATTRIBUTE
634#define BETTER_ENUMS_TYPE(SetUnderlyingType, SwitchType, GenerateSwitchType, \
635 GenerateStrings, ToStringConstexpr, \
636 DeclareInitialize, DefineInitialize, CallInitialize, \
637 Enum, Underlying, ...) \
639namespace better_enums_data_ ## Enum { \
641BETTER_ENUMS_ID(GenerateSwitchType(Underlying, __VA_ARGS__)) \
645class BETTER_ENUMS_CLASS_ATTRIBUTE Enum { \
647 typedef ::better_enums::optional<Enum> _optional; \
648 typedef ::better_enums::optional<std::size_t> _optional_index; \
651 typedef Underlying _integral; \
653 enum _enumerated SetUnderlyingType(Underlying) { __VA_ARGS__ }; \
655 BETTER_ENUMS_CONSTEXPR_ Enum(_enumerated value) : _value(value) { } \
657 BETTER_ENUMS_COPY_CONSTRUCTOR(Enum) \
659 BETTER_ENUMS_CONSTEXPR_ operator SwitchType(Enum)() const \
661 return SwitchType(Enum)(_value); \
664 BETTER_ENUMS_CONSTEXPR_ _integral _to_integral() const; \
665 BETTER_ENUMS_IF_EXCEPTIONS( \
666 BETTER_ENUMS_CONSTEXPR_ static Enum _from_integral(_integral value); \
668 BETTER_ENUMS_CONSTEXPR_ static Enum \
669 _from_integral_unchecked(_integral value); \
670 BETTER_ENUMS_CONSTEXPR_ static _optional \
671 _from_integral_nothrow(_integral value); \
673 BETTER_ENUMS_CONSTEXPR_ std::size_t _to_index() const; \
674 BETTER_ENUMS_IF_EXCEPTIONS( \
675 BETTER_ENUMS_CONSTEXPR_ static Enum _from_index(std::size_t index); \
677 BETTER_ENUMS_CONSTEXPR_ static Enum \
678 _from_index_unchecked(std::size_t index); \
679 BETTER_ENUMS_CONSTEXPR_ static _optional \
680 _from_index_nothrow(std::size_t index); \
682 ToStringConstexpr const char* _to_string() const; \
683 BETTER_ENUMS_IF_EXCEPTIONS( \
684 BETTER_ENUMS_CONSTEXPR_ static Enum _from_string(const char *name); \
686 BETTER_ENUMS_CONSTEXPR_ static _optional \
687 _from_string_nothrow(const char *name); \
689 BETTER_ENUMS_IF_EXCEPTIONS( \
690 BETTER_ENUMS_CONSTEXPR_ static Enum _from_string_nocase(const char *name); \
692 BETTER_ENUMS_CONSTEXPR_ static _optional \
693 _from_string_nocase_nothrow(const char *name); \
695 BETTER_ENUMS_CONSTEXPR_ static bool _is_valid(_integral value); \
696 BETTER_ENUMS_CONSTEXPR_ static bool _is_valid(const char *name); \
697 BETTER_ENUMS_CONSTEXPR_ static bool _is_valid_nocase(const char *name); \
699 typedef ::better_enums::_iterable<Enum> _value_iterable; \
700 typedef ::better_enums::_iterable<const char*> _name_iterable; \
702 typedef _value_iterable::iterator _value_iterator; \
703 typedef _name_iterable::iterator _name_iterator; \
705 BETTER_ENUMS_CONSTEXPR_ static const std::size_t _size_constant = \
706 BETTER_ENUMS_ID(BETTER_ENUMS_PP_COUNT(__VA_ARGS__)); \
707 BETTER_ENUMS_CONSTEXPR_ static std::size_t _size() \
708 { return _size_constant; } \
710 BETTER_ENUMS_CONSTEXPR_ static const char* _name(); \
711 BETTER_ENUMS_CONSTEXPR_ static _value_iterable _values(); \
712 ToStringConstexpr static _name_iterable _names(); \
716 BETTER_ENUMS_DEFAULT_CONSTRUCTOR(Enum) \
719 explicit BETTER_ENUMS_CONSTEXPR_ Enum(const _integral &value) : \
724 BETTER_ENUMS_CONSTEXPR_ static _optional_index \
725 _from_value_loop(_integral value, std::size_t index = 0); \
726 BETTER_ENUMS_CONSTEXPR_ static _optional_index \
727 _from_string_loop(const char *name, std::size_t index = 0); \
728 BETTER_ENUMS_CONSTEXPR_ static _optional_index \
729 _from_string_nocase_loop(const char *name, std::size_t index = 0); \
731 friend struct ::better_enums::_initialize_at_program_start<Enum>; \
734namespace better_enums_data_ ## Enum { \
736static ::better_enums::_initialize_at_program_start<Enum> \
737 _force_initialization; \
739enum _putNamesInThisScopeAlso { __VA_ARGS__ }; \
741BETTER_ENUMS_IGNORE_OLD_CAST_HEADER \
742BETTER_ENUMS_IGNORE_OLD_CAST_BEGIN \
743BETTER_ENUMS_CONSTEXPR_ const Enum _value_array[] = \
744 { BETTER_ENUMS_ID(BETTER_ENUMS_EAT_ASSIGN(Enum, __VA_ARGS__)) }; \
745BETTER_ENUMS_IGNORE_OLD_CAST_END \
747BETTER_ENUMS_ID(GenerateStrings(Enum, __VA_ARGS__)) \
751BETTER_ENUMS_IGNORE_ATTRIBUTES_HEADER \
752BETTER_ENUMS_IGNORE_ATTRIBUTES_BEGIN \
753BETTER_ENUMS_UNUSED BETTER_ENUMS_CONSTEXPR_ \
755operator +(Enum::_enumerated enumerated) \
757 return static_cast<Enum>(enumerated); \
759BETTER_ENUMS_IGNORE_ATTRIBUTES_END \
761BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional_index \
762Enum::_from_value_loop(Enum::_integral value, std::size_t index) \
766 _optional_index() : \
767 BETTER_ENUMS_NS(Enum)::_value_array[index]._value == value ? \
768 _optional_index(index) : \
769 _from_value_loop(value, index + 1); \
772BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional_index \
773Enum::_from_string_loop(const char *name, std::size_t index) \
776 index == _size() ? _optional_index() : \
777 ::better_enums::_names_match( \
778 BETTER_ENUMS_NS(Enum)::_raw_names()[index], name) ? \
779 _optional_index(index) : \
780 _from_string_loop(name, index + 1); \
783BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional_index \
784Enum::_from_string_nocase_loop(const char *name, std::size_t index) \
787 index == _size() ? _optional_index() : \
788 ::better_enums::_names_match_nocase( \
789 BETTER_ENUMS_NS(Enum)::_raw_names()[index], name) ? \
790 _optional_index(index) : \
791 _from_string_nocase_loop(name, index + 1); \
794BETTER_ENUMS_CONSTEXPR_ inline Enum::_integral Enum::_to_integral() const \
796 return _integral(_value); \
799BETTER_ENUMS_CONSTEXPR_ inline std::size_t Enum::_to_index() const \
801 return *_from_value_loop(_value); \
804BETTER_ENUMS_CONSTEXPR_ inline Enum \
805Enum::_from_index_unchecked(std::size_t index) \
808 ::better_enums::_or_zero(_from_index_nothrow(index)); \
811BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional \
812Enum::_from_index_nothrow(std::size_t index) \
817 _optional(BETTER_ENUMS_NS(Enum)::_value_array[index]); \
820BETTER_ENUMS_IF_EXCEPTIONS( \
821BETTER_ENUMS_CONSTEXPR_ inline Enum Enum::_from_index(std::size_t index) \
824 ::better_enums::_or_throw(_from_index_nothrow(index), \
825 #Enum "::_from_index: invalid argument"); \
829BETTER_ENUMS_CONSTEXPR_ inline Enum \
830Enum::_from_integral_unchecked(_integral value) \
832 return static_cast<_enumerated>(value); \
835BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional \
836Enum::_from_integral_nothrow(_integral value) \
839 ::better_enums::_map_index<Enum>(BETTER_ENUMS_NS(Enum)::_value_array, \
840 _from_value_loop(value)); \
843BETTER_ENUMS_IF_EXCEPTIONS( \
844BETTER_ENUMS_CONSTEXPR_ inline Enum Enum::_from_integral(_integral value) \
847 ::better_enums::_or_throw(_from_integral_nothrow(value), \
848 #Enum "::_from_integral: invalid argument"); \
852ToStringConstexpr inline const char* Enum::_to_string() const \
855 ::better_enums::_or_null( \
856 ::better_enums::_map_index<const char*>( \
857 BETTER_ENUMS_NS(Enum)::_name_array(), \
858 _from_value_loop(CallInitialize(_value)))); \
861BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional \
862Enum::_from_string_nothrow(const char *name) \
865 ::better_enums::_map_index<Enum>( \
866 BETTER_ENUMS_NS(Enum)::_value_array, _from_string_loop(name)); \
869BETTER_ENUMS_IF_EXCEPTIONS( \
870BETTER_ENUMS_CONSTEXPR_ inline Enum Enum::_from_string(const char *name) \
873 ::better_enums::_or_throw(_from_string_nothrow(name), \
874 #Enum "::_from_string: invalid argument"); \
878BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional \
879Enum::_from_string_nocase_nothrow(const char *name) \
882 ::better_enums::_map_index<Enum>(BETTER_ENUMS_NS(Enum)::_value_array, \
883 _from_string_nocase_loop(name)); \
886BETTER_ENUMS_IF_EXCEPTIONS( \
887BETTER_ENUMS_CONSTEXPR_ inline Enum Enum::_from_string_nocase(const char *name)\
890 ::better_enums::_or_throw( \
891 _from_string_nocase_nothrow(name), \
892 #Enum "::_from_string_nocase: invalid argument"); \
896BETTER_ENUMS_CONSTEXPR_ inline bool Enum::_is_valid(_integral value) \
898 return _from_value_loop(value); \
901BETTER_ENUMS_CONSTEXPR_ inline bool Enum::_is_valid(const char *name) \
903 return _from_string_loop(name); \
906BETTER_ENUMS_CONSTEXPR_ inline bool Enum::_is_valid_nocase(const char *name) \
908 return _from_string_nocase_loop(name); \
911BETTER_ENUMS_CONSTEXPR_ inline const char* Enum::_name() \
916BETTER_ENUMS_CONSTEXPR_ inline Enum::_value_iterable Enum::_values() \
918 return _value_iterable(BETTER_ENUMS_NS(Enum)::_value_array, _size()); \
921ToStringConstexpr inline Enum::_name_iterable Enum::_names() \
924 _name_iterable(BETTER_ENUMS_NS(Enum)::_name_array(), \
925 CallInitialize(_size())); \
928DefineInitialize(Enum) \
930BETTER_ENUMS_IGNORE_ATTRIBUTES_HEADER \
931BETTER_ENUMS_IGNORE_ATTRIBUTES_BEGIN \
932BETTER_ENUMS_UNUSED BETTER_ENUMS_CONSTEXPR_ \
933inline bool operator ==(const Enum &a, const Enum &b) \
934 { return a._to_integral() == b._to_integral(); } \
936BETTER_ENUMS_UNUSED BETTER_ENUMS_CONSTEXPR_ \
937inline bool operator !=(const Enum &a, const Enum &b) \
938 { return a._to_integral() != b._to_integral(); } \
940BETTER_ENUMS_UNUSED BETTER_ENUMS_CONSTEXPR_ \
941inline bool operator <(const Enum &a, const Enum &b) \
942 { return a._to_integral() < b._to_integral(); } \
944BETTER_ENUMS_UNUSED BETTER_ENUMS_CONSTEXPR_ \
945inline bool operator <=(const Enum &a, const Enum &b) \
946 { return a._to_integral() <= b._to_integral(); } \
948BETTER_ENUMS_UNUSED BETTER_ENUMS_CONSTEXPR_ \
949inline bool operator >(const Enum &a, const Enum &b) \
950 { return a._to_integral() > b._to_integral(); } \
952BETTER_ENUMS_UNUSED BETTER_ENUMS_CONSTEXPR_ \
953inline bool operator >=(const Enum &a, const Enum &b) \
954 { return a._to_integral() >= b._to_integral(); } \
955BETTER_ENUMS_IGNORE_ATTRIBUTES_END \
958template <typename Char, typename Traits> \
959std::basic_ostream<Char, Traits>& \
960operator <<(std::basic_ostream<Char, Traits>& stream, const Enum &value) \
962 return stream << value._to_string(); \
965template <typename Char, typename Traits> \
966std::basic_istream<Char, Traits>& \
967operator >>(std::basic_istream<Char, Traits>& stream, Enum &value) \
969 std::basic_string<Char, Traits> buffer; \
972 ::better_enums::optional<Enum> converted = \
973 Enum::_from_string_nothrow(buffer.c_str()); \
976 value = *converted; \
978 stream.setstate(std::basic_istream<Char, Traits>::failbit); \
988#define BETTER_ENUMS_CXX98_UNDERLYING_TYPE(Underlying)
991#define BETTER_ENUMS_CXX11_UNDERLYING_TYPE(Underlying) \
994#if defined(_MSC_VER) && _MSC_VER >= 1700
997# define BETTER_ENUMS_LEGACY_UNDERLYING_TYPE(Underlying) \
998 BETTER_ENUMS_CXX11_UNDERLYING_TYPE(Underlying)
1000# define BETTER_ENUMS_LEGACY_UNDERLYING_TYPE(Underlying) \
1001 BETTER_ENUMS_CXX98_UNDERLYING_TYPE(Underlying)
1005#define BETTER_ENUMS_REGULAR_ENUM_SWITCH_TYPE(Type) \
1009#define BETTER_ENUMS_ENUM_CLASS_SWITCH_TYPE(Type) \
1010 BETTER_ENUMS_NS(Type)::_enumClassForSwitchStatements
1013#define BETTER_ENUMS_REGULAR_ENUM_SWITCH_TYPE_GENERATE(Underlying, ...)
1016#define BETTER_ENUMS_ENUM_CLASS_SWITCH_TYPE_GENERATE(Underlying, ...) \
1017 enum class _enumClassForSwitchStatements : Underlying { __VA_ARGS__ };
1020#define BETTER_ENUMS_CXX98_TRIM_STRINGS_ARRAYS(Enum, ...) \
1021 inline const char** _raw_names() \
1023 static const char *value[] = \
1024 { BETTER_ENUMS_ID(BETTER_ENUMS_STRINGIZE(__VA_ARGS__)) }; \
1028 inline char* _name_storage() \
1030 static char storage[] = \
1031 BETTER_ENUMS_ID(BETTER_ENUMS_RESERVE_STORAGE(__VA_ARGS__)); \
1035 inline const char** _name_array() \
1037 static const char *value[Enum::_size_constant]; \
1041 inline bool& _initialized() \
1043 static bool value = false; \
1048#define BETTER_ENUMS_CXX11_PARTIAL_CONSTEXPR_TRIM_STRINGS_ARRAYS(Enum, ...) \
1049 constexpr const char *_the_raw_names[] = \
1050 { BETTER_ENUMS_ID(BETTER_ENUMS_STRINGIZE(__VA_ARGS__)) }; \
1052 constexpr const char * const * _raw_names() \
1054 return _the_raw_names; \
1057 inline char* _name_storage() \
1059 static char storage[] = \
1060 BETTER_ENUMS_ID(BETTER_ENUMS_RESERVE_STORAGE(__VA_ARGS__)); \
1064 inline const char** _name_array() \
1066 static const char *value[Enum::_size_constant]; \
1070 inline bool& _initialized() \
1072 static bool value = false; \
1077#define BETTER_ENUMS_CXX11_FULL_CONSTEXPR_TRIM_STRINGS_ARRAYS(Enum, ...) \
1078 BETTER_ENUMS_ID(BETTER_ENUMS_TRIM_STRINGS(__VA_ARGS__)) \
1080 constexpr const char * const _the_name_array[] = \
1081 { BETTER_ENUMS_ID(BETTER_ENUMS_REFER_TO_STRINGS(__VA_ARGS__)) }; \
1083 constexpr const char * const * _name_array() \
1085 return _the_name_array; \
1088 constexpr const char * const * _raw_names() \
1090 return _the_name_array; \
1094#define BETTER_ENUMS_NO_CONSTEXPR_TO_STRING_KEYWORD
1097#define BETTER_ENUMS_CONSTEXPR_TO_STRING_KEYWORD \
1101#define BETTER_ENUMS_DO_DECLARE_INITIALIZE \
1102 static int initialize();
1105#define BETTER_ENUMS_DECLARE_EMPTY_INITIALIZE \
1106 static int initialize() { return 0; }
1109#define BETTER_ENUMS_DO_DEFINE_INITIALIZE(Enum) \
1110 inline int Enum::initialize() \
1112 if (BETTER_ENUMS_NS(Enum)::_initialized()) \
1115 ::better_enums::_trim_names(BETTER_ENUMS_NS(Enum)::_raw_names(), \
1116 BETTER_ENUMS_NS(Enum)::_name_array(), \
1117 BETTER_ENUMS_NS(Enum)::_name_storage(), \
1120 BETTER_ENUMS_NS(Enum)::_initialized() = true; \
1126#define BETTER_ENUMS_DO_NOT_DEFINE_INITIALIZE(Enum)
1129#define BETTER_ENUMS_DO_CALL_INITIALIZE(value) \
1130 ::better_enums::continue_with(initialize(), value)
1133#define BETTER_ENUMS_DO_NOT_CALL_INITIALIZE(value) \
1140#ifdef BETTER_ENUMS_STRICT_CONVERSION
1141# define BETTER_ENUMS_DEFAULT_SWITCH_TYPE \
1142 BETTER_ENUMS_ENUM_CLASS_SWITCH_TYPE
1143# define BETTER_ENUMS_DEFAULT_SWITCH_TYPE_GENERATE \
1144 BETTER_ENUMS_ENUM_CLASS_SWITCH_TYPE_GENERATE
1146# define BETTER_ENUMS_DEFAULT_SWITCH_TYPE \
1147 BETTER_ENUMS_REGULAR_ENUM_SWITCH_TYPE
1148# define BETTER_ENUMS_DEFAULT_SWITCH_TYPE_GENERATE \
1149 BETTER_ENUMS_REGULAR_ENUM_SWITCH_TYPE_GENERATE
1154#ifndef BETTER_ENUMS_DEFAULT_CONSTRUCTOR
1155# define BETTER_ENUMS_DEFAULT_CONSTRUCTOR(Enum) \
1157 Enum() : _value(0) { }
1162#ifdef BETTER_ENUMS_HAVE_CONSTEXPR
1164#ifdef BETTER_ENUMS_CONSTEXPR_TO_STRING
1165# define BETTER_ENUMS_DEFAULT_TRIM_STRINGS_ARRAYS \
1166 BETTER_ENUMS_CXX11_FULL_CONSTEXPR_TRIM_STRINGS_ARRAYS
1167# define BETTER_ENUMS_DEFAULT_TO_STRING_KEYWORD \
1168 BETTER_ENUMS_CONSTEXPR_TO_STRING_KEYWORD
1169# define BETTER_ENUMS_DEFAULT_DECLARE_INITIALIZE \
1170 BETTER_ENUMS_DECLARE_EMPTY_INITIALIZE
1171# define BETTER_ENUMS_DEFAULT_DEFINE_INITIALIZE \
1172 BETTER_ENUMS_DO_NOT_DEFINE_INITIALIZE
1173# define BETTER_ENUMS_DEFAULT_CALL_INITIALIZE \
1174 BETTER_ENUMS_DO_NOT_CALL_INITIALIZE
1176# define BETTER_ENUMS_DEFAULT_TRIM_STRINGS_ARRAYS \
1177 BETTER_ENUMS_CXX11_PARTIAL_CONSTEXPR_TRIM_STRINGS_ARRAYS
1178# define BETTER_ENUMS_DEFAULT_TO_STRING_KEYWORD \
1179 BETTER_ENUMS_NO_CONSTEXPR_TO_STRING_KEYWORD
1180# define BETTER_ENUMS_DEFAULT_DECLARE_INITIALIZE \
1181 BETTER_ENUMS_DO_DECLARE_INITIALIZE
1182# define BETTER_ENUMS_DEFAULT_DEFINE_INITIALIZE \
1183 BETTER_ENUMS_DO_DEFINE_INITIALIZE
1184# define BETTER_ENUMS_DEFAULT_CALL_INITIALIZE \
1185 BETTER_ENUMS_DO_CALL_INITIALIZE
1192#define BETTER_ENUM(Enum, Underlying, ...) \
1193 BETTER_ENUMS_ID(BETTER_ENUMS_TYPE( \
1194 BETTER_ENUMS_CXX11_UNDERLYING_TYPE, \
1195 BETTER_ENUMS_DEFAULT_SWITCH_TYPE, \
1196 BETTER_ENUMS_DEFAULT_SWITCH_TYPE_GENERATE, \
1197 BETTER_ENUMS_DEFAULT_TRIM_STRINGS_ARRAYS, \
1198 BETTER_ENUMS_DEFAULT_TO_STRING_KEYWORD, \
1199 BETTER_ENUMS_DEFAULT_DECLARE_INITIALIZE, \
1200 BETTER_ENUMS_DEFAULT_DEFINE_INITIALIZE, \
1201 BETTER_ENUMS_DEFAULT_CALL_INITIALIZE, \
1202 Enum, Underlying, __VA_ARGS__))
1204#define SLOW_ENUM(Enum, Underlying, ...) \
1205 BETTER_ENUMS_ID(BETTER_ENUMS_TYPE( \
1206 BETTER_ENUMS_CXX11_UNDERLYING_TYPE, \
1207 BETTER_ENUMS_DEFAULT_SWITCH_TYPE, \
1208 BETTER_ENUMS_DEFAULT_SWITCH_TYPE_GENERATE, \
1209 BETTER_ENUMS_CXX11_FULL_CONSTEXPR_TRIM_STRINGS_ARRAYS, \
1210 BETTER_ENUMS_CONSTEXPR_TO_STRING_KEYWORD, \
1211 BETTER_ENUMS_DECLARE_EMPTY_INITIALIZE, \
1212 BETTER_ENUMS_DO_NOT_DEFINE_INITIALIZE, \
1213 BETTER_ENUMS_DO_NOT_CALL_INITIALIZE, \
1214 Enum, Underlying, __VA_ARGS__))
1218#define BETTER_ENUM(Enum, Underlying, ...) \
1219 BETTER_ENUMS_ID(BETTER_ENUMS_TYPE( \
1220 BETTER_ENUMS_LEGACY_UNDERLYING_TYPE, \
1221 BETTER_ENUMS_DEFAULT_SWITCH_TYPE, \
1222 BETTER_ENUMS_DEFAULT_SWITCH_TYPE_GENERATE, \
1223 BETTER_ENUMS_CXX98_TRIM_STRINGS_ARRAYS, \
1224 BETTER_ENUMS_NO_CONSTEXPR_TO_STRING_KEYWORD, \
1225 BETTER_ENUMS_DO_DECLARE_INITIALIZE, \
1226 BETTER_ENUMS_DO_DEFINE_INITIALIZE, \
1227 BETTER_ENUMS_DO_CALL_INITIALIZE, \
1228 Enum, Underlying, __VA_ARGS__))
1238template <
typename T>
1247 {
return less_loop(a, b); }
1251 less_loop(
const char *a,
const char *b,
size_t index = 0)
1254 a[index] != b[index] ? a[index] < b[index] :
1255 a[index] ==
'\0' ? false :
1256 less_loop(a, b, index + 1);
1263 {
return less_loop(a, b); }
1267 less_loop(
const wchar_t *a,
const wchar_t *b,
size_t index = 0)
1270 a[index] != b[index] ? a[index] < b[index] :
1271 a[index] == L
'\0' ? false :
1272 less_loop(a, b, index + 1);
1276template <
typename Enum,
typename T,
typename Compare = map_compare<T> >
1284 {
return _f(value); }
1297 Compare::less(_f(Enum::_values()[index]), value) ||
1298 Compare::less(value, _f(Enum::_values()[index])) ?
1300 Enum::_values()[index];
1307template <
typename Enum,
typename T>
1315#define BETTER_ENUMS_DECLARE_STD_HASH(type) \
1317 template <> struct hash<type> \
1319 size_t operator()(const type &x) const \
1321 return std::hash<size_t>()(x._to_integral()); \
#define BETTER_ENUMS_NULLPTR
#define BETTER_ENUMS_IF_EXCEPTIONS(x)
#define BETTER_ENUMS_OR_THROW
#define BETTER_ENUMS_CONSTEXPR_
BETTER_ENUMS_CONSTEXPR_ bool _names_match_nocase(const char *stringizedName, const char *referenceName, std::size_t index=0)
BETTER_ENUMS_CONSTEXPR_ map< Enum, T > make_map(T(*f)(Enum))
BETTER_ENUMS_CONSTEXPR_ char _to_lower_ascii(char c)
BETTER_ENUMS_CONSTEXPR_ bool _ends_name(char c, std::size_t index=0)
BETTER_ENUMS_CONSTEXPR_ std::size_t _default< std::size_t >()
BETTER_ENUMS_CONSTEXPR_ T _default()
BETTER_ENUMS_CONSTEXPR_ bool _names_match(const char *stringizedName, const char *referenceName, std::size_t index=0)
BETTER_ENUMS_CONSTEXPR_ const char * _default< const char * >()
static BETTER_ENUMS_CONSTEXPR_ T _or_zero(optional< T > maybe)
void _trim_names(const char *const *raw_names, const char **trimmed_names, char *storage, std::size_t count)
static BETTER_ENUMS_CONSTEXPR_ const char * _name_enders
BETTER_ENUMS_CONSTEXPR_ char _select(const char *from, std::size_t from_length, std::size_t index)
BETTER_ENUMS_CONSTEXPR_ bool _has_initializer(const char *s, std::size_t index=0)
BETTER_ENUMS_CONSTEXPR_ std::size_t _constant_length(const char *s, std::size_t index=0)
BETTER_ENUMS_CONSTEXPR_ U continue_with(T, U value)
static BETTER_ENUMS_CONSTEXPR_ optional< CastTo > _map_index(const Element *array, optional< std::size_t > index)
Get intrinsic value of an (Enum::value) by taking advantage of.
BETTER_ENUMS_CONSTEXPR_ _eat_assign(EnumType value)
BETTER_ENUMS_CONSTEXPR_ const _eat_assign & operator=(Any) const
_initialize_at_program_start()
BETTER_ENUMS_CONSTEXPR_ _iterable(const Element *array, std::size_t s)
BETTER_ENUMS_CONSTEXPR_ iterator begin() const
BETTER_ENUMS_CONSTEXPR_ iterator end() const
BETTER_ENUMS_CONSTEXPR_ const Element & operator[](std::size_t index) const
BETTER_ENUMS_CONSTEXPR_ std::size_t size() const
static BETTER_ENUMS_CONSTEXPR_ bool less(const char *a, const char *b)
static BETTER_ENUMS_CONSTEXPR_ bool less(const wchar_t *a, const wchar_t *b)
static BETTER_ENUMS_CONSTEXPR_ bool less(const T &a, const T &b)
BETTER_ENUMS_CONSTEXPR_ T operator[](Enum value) const
BETTER_ENUMS_CONSTEXPR_ Enum to_enum(T value) const
BETTER_ENUMS_CONSTEXPR_ map(function f)
BETTER_ENUMS_CONSTEXPR_ optional< Enum > to_enum_nothrow(T value, size_t index=0) const
BETTER_ENUMS_CONSTEXPR_ T from_enum(Enum value) const
BETTER_ENUMS_CONSTEXPR_ const T & operator*() const
BETTER_ENUMS_CONSTEXPR_ const T & value() const
BETTER_ENUMS_CONSTEXPR_ optional()
BETTER_ENUMS_CONSTEXPR_ optional(T v)
BETTER_ENUMS_CONSTEXPR_ const T * operator->() const