From ccc7858f148f54f9bf54b2ef915d2ee03aea51c4 Mon Sep 17 00:00:00 2001 From: Anton Bachin Date: Wed, 27 May 2015 13:15:08 -0500 Subject: [PATCH] Ported to Microsoft Visual Studio. Worked around a bug with vararg macro expansion in VC++ and tested with Visual Studio 2013. This commit does not include exhaustive tests for that compiler as for clang and gcc. They are coming in a follow-on commit. https://connect.microsoft.com/VisualStudio/feedback/details/521844/variadic-macro-treating-va-args-as-a-single-parameter-for-other-macros --- README.md | 4 +- doc/CompilerSupport.md | 10 +- doc/index.md | 2 +- enum.h | 228 +++++++++++++++++++++-------------------- script/make_macros.py | 21 ++-- 5 files changed, 137 insertions(+), 128 deletions(-) diff --git a/README.md b/README.md index 132272e..916aac8 100644 --- a/README.md +++ b/README.md @@ -46,9 +46,7 @@ Simply add `enum.h` to your project. - Explicit choice of underlying representation type. - Header-only. - No dependencies besides the standard library. -- Tested on gcc 4.3+ and clang 3.3+. - -Visual C++ support coming in the next few days. I am currently porting. +- Tested on gcc 4.3 to 5.1, clang 3.3 to 3.6, and VS2013. ## Contact diff --git a/doc/CompilerSupport.md b/doc/CompilerSupport.md index c2d5319..0009554 100644 --- a/doc/CompilerSupport.md +++ b/doc/CompilerSupport.md @@ -1,16 +1,17 @@ ## Compiler support Better Enums aims to support as many compilers as is reasonable. It has been -tested with clang++ and g++, and Visual C++ support is coming in the next few -days. +tested with clang++ and g++, and Visual C++: + + - clang++ 3.3 to 3.6 + - g++ 4.3 to 5.1 + - Visual C++ 2013 In principle, Better Enums can be used with any compiler that supports either - $cxx11 - $cxx98 with the variadic macro (`__VA_ARGS__`) extension -This should make it compatible with Visual C++ 2005 and higher/ - To ensure that nothing is broken, every release of Better Enums is tested automatically with a large number of combinations of compiler and configuration. The full list is given at the end of this page. @@ -21,6 +22,7 @@ demos and tutorials, and a multiple translation unit linking test. ### Tested configurations ~~~comment +vc2013 /EHsc clang++36 -std=c++11 clang++36 -std=c++11 -DBETTER_ENUMS_STRICT_CONVERSION clang++36 -std=c++11 -DBETTER_ENUMS_CONSTEXPR_TO_STRING diff --git a/doc/index.md b/doc/index.md index 494be42..2189f61 100644 --- a/doc/index.md +++ b/doc/index.md @@ -107,7 +107,7 @@ the project on [GitHub]($repo) for updates. Extending macro limits
  • Compiler support
  • -
  • Performance
  • +
  • Performance
  • diff --git a/enum.h b/enum.h index c68a524..c46233f 100644 --- a/enum.h +++ b/enum.h @@ -59,77 +59,79 @@ #else #define _ENUM_PP_MAP(macro, data, ...) \ - _ENUM_A(_ENUM_PP_MAP_VAR_COUNT, _ENUM_PP_COUNT(__VA_ARGS__)) \ - (macro, data, __VA_ARGS__) + _ENUM_ID(_ENUM_A(_ENUM_PP_MAP_VAR_COUNT, _ENUM_PP_COUNT(__VA_ARGS__)) \ + (macro, data, __VA_ARGS__)) #define _ENUM_PP_MAP_VAR_COUNT(count) _ENUM_M ## count -#define _ENUM_A(macro, ...) macro(__VA_ARGS__) +#define _ENUM_A(macro, ...) _ENUM_ID(macro(__VA_ARGS__)) -#define _ENUM_M1(m, d, x) _ENUM_A(m, d, 0, x) -#define _ENUM_M2(m,d,x,...) _ENUM_A(m,d,1,x) _ENUM_M1(m,d,__VA_ARGS__) -#define _ENUM_M3(m,d,x,...) _ENUM_A(m,d,2,x) _ENUM_M2(m,d,__VA_ARGS__) -#define _ENUM_M4(m,d,x,...) _ENUM_A(m,d,3,x) _ENUM_M3(m,d,__VA_ARGS__) -#define _ENUM_M5(m,d,x,...) _ENUM_A(m,d,4,x) _ENUM_M4(m,d,__VA_ARGS__) -#define _ENUM_M6(m,d,x,...) _ENUM_A(m,d,5,x) _ENUM_M5(m,d,__VA_ARGS__) -#define _ENUM_M7(m,d,x,...) _ENUM_A(m,d,6,x) _ENUM_M6(m,d,__VA_ARGS__) -#define _ENUM_M8(m,d,x,...) _ENUM_A(m,d,7,x) _ENUM_M7(m,d,__VA_ARGS__) -#define _ENUM_M9(m,d,x,...) _ENUM_A(m,d,8,x) _ENUM_M8(m,d,__VA_ARGS__) -#define _ENUM_M10(m,d,x,...) _ENUM_A(m,d,9,x) _ENUM_M9(m,d,__VA_ARGS__) -#define _ENUM_M11(m,d,x,...) _ENUM_A(m,d,10,x) _ENUM_M10(m,d,__VA_ARGS__) -#define _ENUM_M12(m,d,x,...) _ENUM_A(m,d,11,x) _ENUM_M11(m,d,__VA_ARGS__) -#define _ENUM_M13(m,d,x,...) _ENUM_A(m,d,12,x) _ENUM_M12(m,d,__VA_ARGS__) -#define _ENUM_M14(m,d,x,...) _ENUM_A(m,d,13,x) _ENUM_M13(m,d,__VA_ARGS__) -#define _ENUM_M15(m,d,x,...) _ENUM_A(m,d,14,x) _ENUM_M14(m,d,__VA_ARGS__) -#define _ENUM_M16(m,d,x,...) _ENUM_A(m,d,15,x) _ENUM_M15(m,d,__VA_ARGS__) -#define _ENUM_M17(m,d,x,...) _ENUM_A(m,d,16,x) _ENUM_M16(m,d,__VA_ARGS__) -#define _ENUM_M18(m,d,x,...) _ENUM_A(m,d,17,x) _ENUM_M17(m,d,__VA_ARGS__) -#define _ENUM_M19(m,d,x,...) _ENUM_A(m,d,18,x) _ENUM_M18(m,d,__VA_ARGS__) -#define _ENUM_M20(m,d,x,...) _ENUM_A(m,d,19,x) _ENUM_M19(m,d,__VA_ARGS__) -#define _ENUM_M21(m,d,x,...) _ENUM_A(m,d,20,x) _ENUM_M20(m,d,__VA_ARGS__) -#define _ENUM_M22(m,d,x,...) _ENUM_A(m,d,21,x) _ENUM_M21(m,d,__VA_ARGS__) -#define _ENUM_M23(m,d,x,...) _ENUM_A(m,d,22,x) _ENUM_M22(m,d,__VA_ARGS__) -#define _ENUM_M24(m,d,x,...) _ENUM_A(m,d,23,x) _ENUM_M23(m,d,__VA_ARGS__) -#define _ENUM_M25(m,d,x,...) _ENUM_A(m,d,24,x) _ENUM_M24(m,d,__VA_ARGS__) -#define _ENUM_M26(m,d,x,...) _ENUM_A(m,d,25,x) _ENUM_M25(m,d,__VA_ARGS__) -#define _ENUM_M27(m,d,x,...) _ENUM_A(m,d,26,x) _ENUM_M26(m,d,__VA_ARGS__) -#define _ENUM_M28(m,d,x,...) _ENUM_A(m,d,27,x) _ENUM_M27(m,d,__VA_ARGS__) -#define _ENUM_M29(m,d,x,...) _ENUM_A(m,d,28,x) _ENUM_M28(m,d,__VA_ARGS__) -#define _ENUM_M30(m,d,x,...) _ENUM_A(m,d,29,x) _ENUM_M29(m,d,__VA_ARGS__) -#define _ENUM_M31(m,d,x,...) _ENUM_A(m,d,30,x) _ENUM_M30(m,d,__VA_ARGS__) -#define _ENUM_M32(m,d,x,...) _ENUM_A(m,d,31,x) _ENUM_M31(m,d,__VA_ARGS__) -#define _ENUM_M33(m,d,x,...) _ENUM_A(m,d,32,x) _ENUM_M32(m,d,__VA_ARGS__) -#define _ENUM_M34(m,d,x,...) _ENUM_A(m,d,33,x) _ENUM_M33(m,d,__VA_ARGS__) -#define _ENUM_M35(m,d,x,...) _ENUM_A(m,d,34,x) _ENUM_M34(m,d,__VA_ARGS__) -#define _ENUM_M36(m,d,x,...) _ENUM_A(m,d,35,x) _ENUM_M35(m,d,__VA_ARGS__) -#define _ENUM_M37(m,d,x,...) _ENUM_A(m,d,36,x) _ENUM_M36(m,d,__VA_ARGS__) -#define _ENUM_M38(m,d,x,...) _ENUM_A(m,d,37,x) _ENUM_M37(m,d,__VA_ARGS__) -#define _ENUM_M39(m,d,x,...) _ENUM_A(m,d,38,x) _ENUM_M38(m,d,__VA_ARGS__) -#define _ENUM_M40(m,d,x,...) _ENUM_A(m,d,39,x) _ENUM_M39(m,d,__VA_ARGS__) -#define _ENUM_M41(m,d,x,...) _ENUM_A(m,d,40,x) _ENUM_M40(m,d,__VA_ARGS__) -#define _ENUM_M42(m,d,x,...) _ENUM_A(m,d,41,x) _ENUM_M41(m,d,__VA_ARGS__) -#define _ENUM_M43(m,d,x,...) _ENUM_A(m,d,42,x) _ENUM_M42(m,d,__VA_ARGS__) -#define _ENUM_M44(m,d,x,...) _ENUM_A(m,d,43,x) _ENUM_M43(m,d,__VA_ARGS__) -#define _ENUM_M45(m,d,x,...) _ENUM_A(m,d,44,x) _ENUM_M44(m,d,__VA_ARGS__) -#define _ENUM_M46(m,d,x,...) _ENUM_A(m,d,45,x) _ENUM_M45(m,d,__VA_ARGS__) -#define _ENUM_M47(m,d,x,...) _ENUM_A(m,d,46,x) _ENUM_M46(m,d,__VA_ARGS__) -#define _ENUM_M48(m,d,x,...) _ENUM_A(m,d,47,x) _ENUM_M47(m,d,__VA_ARGS__) -#define _ENUM_M49(m,d,x,...) _ENUM_A(m,d,48,x) _ENUM_M48(m,d,__VA_ARGS__) -#define _ENUM_M50(m,d,x,...) _ENUM_A(m,d,49,x) _ENUM_M49(m,d,__VA_ARGS__) -#define _ENUM_M51(m,d,x,...) _ENUM_A(m,d,50,x) _ENUM_M50(m,d,__VA_ARGS__) -#define _ENUM_M52(m,d,x,...) _ENUM_A(m,d,51,x) _ENUM_M51(m,d,__VA_ARGS__) -#define _ENUM_M53(m,d,x,...) _ENUM_A(m,d,52,x) _ENUM_M52(m,d,__VA_ARGS__) -#define _ENUM_M54(m,d,x,...) _ENUM_A(m,d,53,x) _ENUM_M53(m,d,__VA_ARGS__) -#define _ENUM_M55(m,d,x,...) _ENUM_A(m,d,54,x) _ENUM_M54(m,d,__VA_ARGS__) -#define _ENUM_M56(m,d,x,...) _ENUM_A(m,d,55,x) _ENUM_M55(m,d,__VA_ARGS__) -#define _ENUM_M57(m,d,x,...) _ENUM_A(m,d,56,x) _ENUM_M56(m,d,__VA_ARGS__) -#define _ENUM_M58(m,d,x,...) _ENUM_A(m,d,57,x) _ENUM_M57(m,d,__VA_ARGS__) -#define _ENUM_M59(m,d,x,...) _ENUM_A(m,d,58,x) _ENUM_M58(m,d,__VA_ARGS__) -#define _ENUM_M60(m,d,x,...) _ENUM_A(m,d,59,x) _ENUM_M59(m,d,__VA_ARGS__) -#define _ENUM_M61(m,d,x,...) _ENUM_A(m,d,60,x) _ENUM_M60(m,d,__VA_ARGS__) -#define _ENUM_M62(m,d,x,...) _ENUM_A(m,d,61,x) _ENUM_M61(m,d,__VA_ARGS__) -#define _ENUM_M63(m,d,x,...) _ENUM_A(m,d,62,x) _ENUM_M62(m,d,__VA_ARGS__) -#define _ENUM_M64(m,d,x,...) _ENUM_A(m,d,63,x) _ENUM_M63(m,d,__VA_ARGS__) +#define _ENUM_ID(x) x + +#define _ENUM_M1(m, d, x) m(d,0,x) +#define _ENUM_M2(m,d,x,...) m(d,1,x) _ENUM_ID(_ENUM_M1(m,d,__VA_ARGS__)) +#define _ENUM_M3(m,d,x,...) m(d,2,x) _ENUM_ID(_ENUM_M2(m,d,__VA_ARGS__)) +#define _ENUM_M4(m,d,x,...) m(d,3,x) _ENUM_ID(_ENUM_M3(m,d,__VA_ARGS__)) +#define _ENUM_M5(m,d,x,...) m(d,4,x) _ENUM_ID(_ENUM_M4(m,d,__VA_ARGS__)) +#define _ENUM_M6(m,d,x,...) m(d,5,x) _ENUM_ID(_ENUM_M5(m,d,__VA_ARGS__)) +#define _ENUM_M7(m,d,x,...) m(d,6,x) _ENUM_ID(_ENUM_M6(m,d,__VA_ARGS__)) +#define _ENUM_M8(m,d,x,...) m(d,7,x) _ENUM_ID(_ENUM_M7(m,d,__VA_ARGS__)) +#define _ENUM_M9(m,d,x,...) m(d,8,x) _ENUM_ID(_ENUM_M8(m,d,__VA_ARGS__)) +#define _ENUM_M10(m,d,x,...) m(d,9,x) _ENUM_ID(_ENUM_M9(m,d,__VA_ARGS__)) +#define _ENUM_M11(m,d,x,...) m(d,10,x) _ENUM_ID(_ENUM_M10(m,d,__VA_ARGS__)) +#define _ENUM_M12(m,d,x,...) m(d,11,x) _ENUM_ID(_ENUM_M11(m,d,__VA_ARGS__)) +#define _ENUM_M13(m,d,x,...) m(d,12,x) _ENUM_ID(_ENUM_M12(m,d,__VA_ARGS__)) +#define _ENUM_M14(m,d,x,...) m(d,13,x) _ENUM_ID(_ENUM_M13(m,d,__VA_ARGS__)) +#define _ENUM_M15(m,d,x,...) m(d,14,x) _ENUM_ID(_ENUM_M14(m,d,__VA_ARGS__)) +#define _ENUM_M16(m,d,x,...) m(d,15,x) _ENUM_ID(_ENUM_M15(m,d,__VA_ARGS__)) +#define _ENUM_M17(m,d,x,...) m(d,16,x) _ENUM_ID(_ENUM_M16(m,d,__VA_ARGS__)) +#define _ENUM_M18(m,d,x,...) m(d,17,x) _ENUM_ID(_ENUM_M17(m,d,__VA_ARGS__)) +#define _ENUM_M19(m,d,x,...) m(d,18,x) _ENUM_ID(_ENUM_M18(m,d,__VA_ARGS__)) +#define _ENUM_M20(m,d,x,...) m(d,19,x) _ENUM_ID(_ENUM_M19(m,d,__VA_ARGS__)) +#define _ENUM_M21(m,d,x,...) m(d,20,x) _ENUM_ID(_ENUM_M20(m,d,__VA_ARGS__)) +#define _ENUM_M22(m,d,x,...) m(d,21,x) _ENUM_ID(_ENUM_M21(m,d,__VA_ARGS__)) +#define _ENUM_M23(m,d,x,...) m(d,22,x) _ENUM_ID(_ENUM_M22(m,d,__VA_ARGS__)) +#define _ENUM_M24(m,d,x,...) m(d,23,x) _ENUM_ID(_ENUM_M23(m,d,__VA_ARGS__)) +#define _ENUM_M25(m,d,x,...) m(d,24,x) _ENUM_ID(_ENUM_M24(m,d,__VA_ARGS__)) +#define _ENUM_M26(m,d,x,...) m(d,25,x) _ENUM_ID(_ENUM_M25(m,d,__VA_ARGS__)) +#define _ENUM_M27(m,d,x,...) m(d,26,x) _ENUM_ID(_ENUM_M26(m,d,__VA_ARGS__)) +#define _ENUM_M28(m,d,x,...) m(d,27,x) _ENUM_ID(_ENUM_M27(m,d,__VA_ARGS__)) +#define _ENUM_M29(m,d,x,...) m(d,28,x) _ENUM_ID(_ENUM_M28(m,d,__VA_ARGS__)) +#define _ENUM_M30(m,d,x,...) m(d,29,x) _ENUM_ID(_ENUM_M29(m,d,__VA_ARGS__)) +#define _ENUM_M31(m,d,x,...) m(d,30,x) _ENUM_ID(_ENUM_M30(m,d,__VA_ARGS__)) +#define _ENUM_M32(m,d,x,...) m(d,31,x) _ENUM_ID(_ENUM_M31(m,d,__VA_ARGS__)) +#define _ENUM_M33(m,d,x,...) m(d,32,x) _ENUM_ID(_ENUM_M32(m,d,__VA_ARGS__)) +#define _ENUM_M34(m,d,x,...) m(d,33,x) _ENUM_ID(_ENUM_M33(m,d,__VA_ARGS__)) +#define _ENUM_M35(m,d,x,...) m(d,34,x) _ENUM_ID(_ENUM_M34(m,d,__VA_ARGS__)) +#define _ENUM_M36(m,d,x,...) m(d,35,x) _ENUM_ID(_ENUM_M35(m,d,__VA_ARGS__)) +#define _ENUM_M37(m,d,x,...) m(d,36,x) _ENUM_ID(_ENUM_M36(m,d,__VA_ARGS__)) +#define _ENUM_M38(m,d,x,...) m(d,37,x) _ENUM_ID(_ENUM_M37(m,d,__VA_ARGS__)) +#define _ENUM_M39(m,d,x,...) m(d,38,x) _ENUM_ID(_ENUM_M38(m,d,__VA_ARGS__)) +#define _ENUM_M40(m,d,x,...) m(d,39,x) _ENUM_ID(_ENUM_M39(m,d,__VA_ARGS__)) +#define _ENUM_M41(m,d,x,...) m(d,40,x) _ENUM_ID(_ENUM_M40(m,d,__VA_ARGS__)) +#define _ENUM_M42(m,d,x,...) m(d,41,x) _ENUM_ID(_ENUM_M41(m,d,__VA_ARGS__)) +#define _ENUM_M43(m,d,x,...) m(d,42,x) _ENUM_ID(_ENUM_M42(m,d,__VA_ARGS__)) +#define _ENUM_M44(m,d,x,...) m(d,43,x) _ENUM_ID(_ENUM_M43(m,d,__VA_ARGS__)) +#define _ENUM_M45(m,d,x,...) m(d,44,x) _ENUM_ID(_ENUM_M44(m,d,__VA_ARGS__)) +#define _ENUM_M46(m,d,x,...) m(d,45,x) _ENUM_ID(_ENUM_M45(m,d,__VA_ARGS__)) +#define _ENUM_M47(m,d,x,...) m(d,46,x) _ENUM_ID(_ENUM_M46(m,d,__VA_ARGS__)) +#define _ENUM_M48(m,d,x,...) m(d,47,x) _ENUM_ID(_ENUM_M47(m,d,__VA_ARGS__)) +#define _ENUM_M49(m,d,x,...) m(d,48,x) _ENUM_ID(_ENUM_M48(m,d,__VA_ARGS__)) +#define _ENUM_M50(m,d,x,...) m(d,49,x) _ENUM_ID(_ENUM_M49(m,d,__VA_ARGS__)) +#define _ENUM_M51(m,d,x,...) m(d,50,x) _ENUM_ID(_ENUM_M50(m,d,__VA_ARGS__)) +#define _ENUM_M52(m,d,x,...) m(d,51,x) _ENUM_ID(_ENUM_M51(m,d,__VA_ARGS__)) +#define _ENUM_M53(m,d,x,...) m(d,52,x) _ENUM_ID(_ENUM_M52(m,d,__VA_ARGS__)) +#define _ENUM_M54(m,d,x,...) m(d,53,x) _ENUM_ID(_ENUM_M53(m,d,__VA_ARGS__)) +#define _ENUM_M55(m,d,x,...) m(d,54,x) _ENUM_ID(_ENUM_M54(m,d,__VA_ARGS__)) +#define _ENUM_M56(m,d,x,...) m(d,55,x) _ENUM_ID(_ENUM_M55(m,d,__VA_ARGS__)) +#define _ENUM_M57(m,d,x,...) m(d,56,x) _ENUM_ID(_ENUM_M56(m,d,__VA_ARGS__)) +#define _ENUM_M58(m,d,x,...) m(d,57,x) _ENUM_ID(_ENUM_M57(m,d,__VA_ARGS__)) +#define _ENUM_M59(m,d,x,...) m(d,58,x) _ENUM_ID(_ENUM_M58(m,d,__VA_ARGS__)) +#define _ENUM_M60(m,d,x,...) m(d,59,x) _ENUM_ID(_ENUM_M59(m,d,__VA_ARGS__)) +#define _ENUM_M61(m,d,x,...) m(d,60,x) _ENUM_ID(_ENUM_M60(m,d,__VA_ARGS__)) +#define _ENUM_M62(m,d,x,...) m(d,61,x) _ENUM_ID(_ENUM_M61(m,d,__VA_ARGS__)) +#define _ENUM_M63(m,d,x,...) m(d,62,x) _ENUM_ID(_ENUM_M62(m,d,__VA_ARGS__)) +#define _ENUM_M64(m,d,x,...) m(d,63,x) _ENUM_ID(_ENUM_M63(m,d,__VA_ARGS__)) #define _ENUM_PP_COUNT_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, \ _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, \ @@ -137,11 +139,11 @@ _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, \ _58, _59, _60, _61, _62, _63, _64, count, ...) count -#define _ENUM_PP_COUNT(...) _ENUM_PP_COUNT_IMPL(__VA_ARGS__, 64, 63, 62, 61, \ - 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42,\ - 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23,\ - 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,\ - 1) +#define _ENUM_PP_COUNT(...) _ENUM_ID(_ENUM_PP_COUNT_IMPL(__VA_ARGS__, 64, 63, \ + 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44,\ + 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25,\ + 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, \ + 4, 3, 2, 1)) #define _ENUM_ITERATE(X, f, l) X(f, l, 0) X(f, l, 1) X(f, l, 2) X(f, l, 3) \ X(f, l, 4) X(f, l, 5) X(f, l, 6) X(f, l, 7) X(f, l, 8) X(f, l, 9) \ @@ -157,7 +159,7 @@ ((better_enums::_eat_assign)EnumType::expression), #define _ENUM_EAT_ASSIGN(EnumType, ...) \ - _ENUM_PP_MAP(_ENUM_EAT_ASSIGN_SINGLE, EnumType, __VA_ARGS__) + _ENUM_ID(_ENUM_PP_MAP(_ENUM_EAT_ASSIGN_SINGLE, EnumType, __VA_ARGS__)) @@ -352,7 +354,7 @@ constexpr const char *_final_ ## index = \ _hasExplicitValue(#expression) ? _trimmed_ ## index : #expression; #define _ENUM_TRIM_STRINGS(...) \ - _ENUM_PP_MAP(_ENUM_TRIM_SINGLE_STRING, ignored, __VA_ARGS__) + _ENUM_ID(_ENUM_PP_MAP(_ENUM_TRIM_SINGLE_STRING, ignored, __VA_ARGS__)) @@ -360,7 +362,7 @@ constexpr const char *_final_ ## index = \ _final_ ## index, #define _ENUM_REFER_TO_STRINGS(...) \ - _ENUM_PP_MAP(_ENUM_REFER_TO_SINGLE_STRING, ignored, __VA_ARGS__) + _ENUM_ID(_ENUM_PP_MAP(_ENUM_REFER_TO_SINGLE_STRING, ignored, __VA_ARGS__)) @@ -371,7 +373,7 @@ constexpr const char *_final_ ## index = \ #define _ENUM_STRINGIZE_SINGLE(ignored, index, expression) #expression, #define _ENUM_STRINGIZE(...) \ - _ENUM_PP_MAP(_ENUM_STRINGIZE_SINGLE, ignored, __VA_ARGS__) + _ENUM_ID(_ENUM_PP_MAP(_ENUM_STRINGIZE_SINGLE, ignored, __VA_ARGS__)) @@ -383,7 +385,7 @@ constexpr const char *_final_ ## index = \ namespace better_enums { \ namespace _data_ ## Enum { \ \ -GenerateSwitchType(Integral, __VA_ARGS__) \ +_ENUM_ID(GenerateSwitchType(Integral, __VA_ARGS__)) \ \ } \ } \ @@ -428,7 +430,7 @@ class Enum { \ typedef _name_iterable::iterator _name_iterator; \ \ _ENUM_CONSTEXPR static const std::size_t _size = \ - _ENUM_PP_COUNT(__VA_ARGS__); \ + _ENUM_ID(_ENUM_PP_COUNT(__VA_ARGS__)); \ \ _ENUM_CONSTEXPR static const char* _name(); \ _ENUM_CONSTEXPR static _value_iterable _values(); \ @@ -455,9 +457,9 @@ namespace _data_ ## Enum { \ enum PutNamesInThisScopeAlso { __VA_ARGS__ }; \ \ _ENUM_CONSTEXPR const Enum value_array[] = \ - { _ENUM_EAT_ASSIGN(Enum, __VA_ARGS__) }; \ + { _ENUM_ID(_ENUM_EAT_ASSIGN(Enum, __VA_ARGS__)) }; \ \ -GenerateStrings(Enum, __VA_ARGS__) \ +_ENUM_ID(GenerateStrings(Enum, __VA_ARGS__)) \ \ } \ } \ @@ -635,7 +637,8 @@ _ENUM_CONSTEXPR inline bool operator >=(const Enum &a, const Enum &b) \ #define _ENUM_CXX98_TRIM_STRINGS_ARRAYS(Enum, ...) \ inline const char** raw_names() \ { \ - static const char *value[] = { _ENUM_STRINGIZE(__VA_ARGS__) }; \ + static const char *value[] = \ + { _ENUM_ID(_ENUM_STRINGIZE(__VA_ARGS__)) }; \ return value; \ } \ \ @@ -654,7 +657,7 @@ _ENUM_CONSTEXPR inline bool operator >=(const Enum &a, const Enum &b) \ // C++11 fast version #define _ENUM_CXX11_PARTIAL_CONSTEXPR_TRIM_STRINGS_ARRAYS(Enum, ...) \ constexpr const char *the_raw_names[] = \ - { _ENUM_STRINGIZE(__VA_ARGS__) }; \ + { _ENUM_ID(_ENUM_STRINGIZE(__VA_ARGS__)) }; \ \ constexpr const char * const * raw_names() \ { \ @@ -675,10 +678,10 @@ _ENUM_CONSTEXPR inline bool operator >=(const Enum &a, const Enum &b) \ // C++11 slow all-constexpr version #define _ENUM_CXX11_FULL_CONSTEXPR_TRIM_STRINGS_ARRAYS(Enum, ...) \ - _ENUM_TRIM_STRINGS(__VA_ARGS__) \ + _ENUM_ID(_ENUM_TRIM_STRINGS(__VA_ARGS__)) \ \ constexpr const char * const the_name_array[] = \ - { _ENUM_REFER_TO_STRINGS(__VA_ARGS__) }; \ + { _ENUM_ID(_ENUM_REFER_TO_STRINGS(__VA_ARGS__)) }; \ \ constexpr const char * const * name_array() \ { \ @@ -773,39 +776,42 @@ _ENUM_CONSTEXPR inline bool operator >=(const Enum &a, const Enum &b) \ #endif #define ENUM(Enum, Integral, ...) \ - _ENUM_TYPE(_ENUM_CXX11_UNDERLYING_TYPE, \ - _ENUM_DEFAULT_SWITCH_TYPE, \ - _ENUM_DEFAULT_SWITCH_TYPE_GENERATE, \ - _ENUM_DEFAULT_TRIM_STRINGS_ARRAYS, \ - _ENUM_DEFAULT_TO_STRING_KEYWORD, \ - _ENUM_DEFAULT_DECLARE_INITIALIZE, \ - _ENUM_DEFAULT_DEFINE_INITIALIZE, \ - _ENUM_DEFAULT_CALL_INITIALIZE, \ - Enum, Integral, __VA_ARGS__) + _ENUM_ID(_ENUM_TYPE( \ + _ENUM_CXX11_UNDERLYING_TYPE, \ + _ENUM_DEFAULT_SWITCH_TYPE, \ + _ENUM_DEFAULT_SWITCH_TYPE_GENERATE, \ + _ENUM_DEFAULT_TRIM_STRINGS_ARRAYS, \ + _ENUM_DEFAULT_TO_STRING_KEYWORD, \ + _ENUM_DEFAULT_DECLARE_INITIALIZE, \ + _ENUM_DEFAULT_DEFINE_INITIALIZE, \ + _ENUM_DEFAULT_CALL_INITIALIZE, \ + Enum, Integral, __VA_ARGS__)) #define SLOW_ENUM(Enum, Integral, ...) \ - _ENUM_TYPE(_ENUM_CXX11_UNDERLYING_TYPE, \ - _ENUM_DEFAULT_SWITCH_TYPE, \ - _ENUM_DEFAULT_SWITCH_TYPE_GENERATE, \ - _ENUM_CXX11_FULL_CONSTEXPR_TRIM_STRINGS_ARRAYS, \ - _ENUM_CONSTEXPR_TO_STRING_KEYWORD, \ - _ENUM_DO_NOT_DECLARE_INITIALIZE, \ - _ENUM_DO_NOT_DEFINE_INITIALIZE, \ - _ENUM_DO_NOT_CALL_INITIALIZE, \ - Enum, Integral, __VA_ARGS__) + _ENUM_ID(_ENUM_TYPE( \ + _ENUM_CXX11_UNDERLYING_TYPE, \ + _ENUM_DEFAULT_SWITCH_TYPE, \ + _ENUM_DEFAULT_SWITCH_TYPE_GENERATE, \ + _ENUM_CXX11_FULL_CONSTEXPR_TRIM_STRINGS_ARRAYS, \ + _ENUM_CONSTEXPR_TO_STRING_KEYWORD, \ + _ENUM_DO_NOT_DECLARE_INITIALIZE, \ + _ENUM_DO_NOT_DEFINE_INITIALIZE, \ + _ENUM_DO_NOT_CALL_INITIALIZE, \ + Enum, Integral, __VA_ARGS__)) #else #define ENUM(Enum, Integral, ...) \ - _ENUM_TYPE(_ENUM_CXX98_UNDERLYING_TYPE, \ - _ENUM_DEFAULT_SWITCH_TYPE, \ - _ENUM_DEFAULT_SWITCH_TYPE_GENERATE, \ - _ENUM_CXX98_TRIM_STRINGS_ARRAYS, \ - _ENUM_NO_CONSTEXPR_TO_STRING_KEYWORD, \ - _ENUM_DO_DECLARE_INITIALIZE, \ - _ENUM_DO_DEFINE_INITIALIZE, \ - _ENUM_DO_CALL_INITIALIZE, \ - Enum, Integral, __VA_ARGS__) + _ENUM_ID(_ENUM_TYPE( \ + _ENUM_CXX98_UNDERLYING_TYPE, \ + _ENUM_DEFAULT_SWITCH_TYPE, \ + _ENUM_DEFAULT_SWITCH_TYPE_GENERATE, \ + _ENUM_CXX98_TRIM_STRINGS_ARRAYS, \ + _ENUM_NO_CONSTEXPR_TO_STRING_KEYWORD, \ + _ENUM_DO_DECLARE_INITIALIZE, \ + _ENUM_DO_DEFINE_INITIALIZE, \ + _ENUM_DO_CALL_INITIALIZE, \ + Enum, Integral, __VA_ARGS__)) #endif diff --git a/script/make_macros.py b/script/make_macros.py index b08636e..0a28ecd 100755 --- a/script/make_macros.py +++ b/script/make_macros.py @@ -71,24 +71,27 @@ def generate(stream, constants, length, script): print >> stream, '' print >> stream, '#define _ENUM_PP_MAP(macro, data, ...) \\' - print >> stream, ' _ENUM_A(_ENUM_PP_MAP_VAR_COUNT, ' + \ + print >> stream, ' _ENUM_ID(_ENUM_A(_ENUM_PP_MAP_VAR_COUNT, ' + \ '_ENUM_PP_COUNT(__VA_ARGS__)) \\' - print >> stream, ' (macro, data, __VA_ARGS__)' + print >> stream, ' (macro, data, __VA_ARGS__))' print >> stream, '' print >> stream, '#define _ENUM_PP_MAP_VAR_COUNT(count) ' + \ '_ENUM_M ## count' print >> stream, '' - print >> stream, '#define _ENUM_A(macro, ...) macro(__VA_ARGS__)' + print >> stream, '#define _ENUM_A(macro, ...) _ENUM_ID(macro(__VA_ARGS__))' print >> stream, '' - print >> stream, '#define _ENUM_M1(m, d, x) _ENUM_A(m, d, 0, x)' + print >> stream, '#define _ENUM_ID(x) x' + + print >> stream, '' + print >> stream, '#define _ENUM_M1(m, d, x) m(d,0,x)' for index in range(2, constants + 1): print >> stream, '#define _ENUM_M' + str(index) + \ - '(m,d,x,...) _ENUM_A(m,d,' + str(index - 1) + \ - ',x) _ENUM_M' + str(index - 1) + \ - '(m,d,__VA_ARGS__)' + '(m,d,x,...) m(d,' + str(index - 1) + \ + ',x) _ENUM_ID(_ENUM_M' + str(index - 1) + \ + '(m,d,__VA_ARGS__))' print >> stream, '' pp_count_impl_prefix = '#define _ENUM_PP_COUNT_IMPL(_1,' @@ -104,13 +107,13 @@ def generate(stream, constants, length, script): print >> stream, '' pp_count_prefix = \ - '#define _ENUM_PP_COUNT(...) _ENUM_PP_COUNT_IMPL(__VA_ARGS__,' + '#define _ENUM_PP_COUNT(...) _ENUM_ID(_ENUM_PP_COUNT_IMPL(__VA_ARGS__,' stream.write(pp_count_prefix) pp_count = MultiLine(stream = stream, indent = 4, initial_column = len(pp_count_prefix)) for index in range(0, constants - 1): pp_count.write(' ' + str(constants - index) + ',') - pp_count.write(' 1)', last = True) + pp_count.write(' 1))', last = True) print >> stream, '' print >> stream, ''