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
This commit is contained in:
Anton Bachin 2015-05-27 13:15:08 -05:00
parent 2acb5743fa
commit ccc7858f14
5 changed files with 137 additions and 128 deletions

View File

@ -46,9 +46,7 @@ Simply add `enum.h` to your project.
- Explicit choice of underlying representation type. - Explicit choice of underlying representation type.
- Header-only. - Header-only.
- No dependencies besides the standard library. - No dependencies besides the standard library.
- Tested on gcc 4.3+ and clang 3.3+. - Tested on gcc 4.3 to 5.1, clang 3.3 to 3.6, and VS2013.
Visual C++ support coming in the next few days. I am currently porting.
## Contact ## Contact

View File

@ -1,16 +1,17 @@
## Compiler support ## Compiler support
Better Enums aims to support as many compilers as is reasonable. It has been 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 tested with clang++ and g++, and Visual C++:
days.
- 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 In principle, Better Enums can be used with any compiler that supports either
- $cxx11 - $cxx11
- $cxx98 with the variadic macro (`__VA_ARGS__`) extension - $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 To ensure that nothing is broken, every release of Better Enums is tested
automatically with a large number of combinations of compiler and configuration. automatically with a large number of combinations of compiler and configuration.
The full list is given at the end of this page. 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 ### Tested configurations
~~~comment ~~~comment
vc2013 /EHsc
clang++36 -std=c++11 clang++36 -std=c++11
clang++36 -std=c++11 -DBETTER_ENUMS_STRICT_CONVERSION clang++36 -std=c++11 -DBETTER_ENUMS_STRICT_CONVERSION
clang++36 -std=c++11 -DBETTER_ENUMS_CONSTEXPR_TO_STRING clang++36 -std=c++11 -DBETTER_ENUMS_CONSTEXPR_TO_STRING

View File

@ -107,7 +107,7 @@ the project on [GitHub]($repo) for updates.
<a href="${prefix}ExtendingMacroLimits.html">Extending macro limits</a> <a href="${prefix}ExtendingMacroLimits.html">Extending macro limits</a>
</li> </li>
<li><a href="${prefix}CompilerSupport.html">Compiler support</a></li> <li><a href="${prefix}CompilerSupport.html">Compiler support</a></li>
<li><a href="${prefix}Performance.html">Performance</a></li> <li><a href="${prefix}performance.html">Performance</a></li>
</ul> </ul>
</div> </div>
</div> </div>

186
enum.h
View File

@ -59,77 +59,79 @@
#else #else
#define _ENUM_PP_MAP(macro, data, ...) \ #define _ENUM_PP_MAP(macro, data, ...) \
_ENUM_A(_ENUM_PP_MAP_VAR_COUNT, _ENUM_PP_COUNT(__VA_ARGS__)) \ _ENUM_ID(_ENUM_A(_ENUM_PP_MAP_VAR_COUNT, _ENUM_PP_COUNT(__VA_ARGS__)) \
(macro, data, __VA_ARGS__) (macro, data, __VA_ARGS__))
#define _ENUM_PP_MAP_VAR_COUNT(count) _ENUM_M ## count #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_ID(x) 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_M1(m, d, x) m(d,0,x)
#define _ENUM_M4(m,d,x,...) _ENUM_A(m,d,3,x) _ENUM_M3(m,d,__VA_ARGS__) #define _ENUM_M2(m,d,x,...) m(d,1,x) _ENUM_ID(_ENUM_M1(m,d,__VA_ARGS__))
#define _ENUM_M5(m,d,x,...) _ENUM_A(m,d,4,x) _ENUM_M4(m,d,__VA_ARGS__) #define _ENUM_M3(m,d,x,...) m(d,2,x) _ENUM_ID(_ENUM_M2(m,d,__VA_ARGS__))
#define _ENUM_M6(m,d,x,...) _ENUM_A(m,d,5,x) _ENUM_M5(m,d,__VA_ARGS__) #define _ENUM_M4(m,d,x,...) m(d,3,x) _ENUM_ID(_ENUM_M3(m,d,__VA_ARGS__))
#define _ENUM_M7(m,d,x,...) _ENUM_A(m,d,6,x) _ENUM_M6(m,d,__VA_ARGS__) #define _ENUM_M5(m,d,x,...) m(d,4,x) _ENUM_ID(_ENUM_M4(m,d,__VA_ARGS__))
#define _ENUM_M8(m,d,x,...) _ENUM_A(m,d,7,x) _ENUM_M7(m,d,__VA_ARGS__) #define _ENUM_M6(m,d,x,...) m(d,5,x) _ENUM_ID(_ENUM_M5(m,d,__VA_ARGS__))
#define _ENUM_M9(m,d,x,...) _ENUM_A(m,d,8,x) _ENUM_M8(m,d,__VA_ARGS__) #define _ENUM_M7(m,d,x,...) m(d,6,x) _ENUM_ID(_ENUM_M6(m,d,__VA_ARGS__))
#define _ENUM_M10(m,d,x,...) _ENUM_A(m,d,9,x) _ENUM_M9(m,d,__VA_ARGS__) #define _ENUM_M8(m,d,x,...) m(d,7,x) _ENUM_ID(_ENUM_M7(m,d,__VA_ARGS__))
#define _ENUM_M11(m,d,x,...) _ENUM_A(m,d,10,x) _ENUM_M10(m,d,__VA_ARGS__) #define _ENUM_M9(m,d,x,...) m(d,8,x) _ENUM_ID(_ENUM_M8(m,d,__VA_ARGS__))
#define _ENUM_M12(m,d,x,...) _ENUM_A(m,d,11,x) _ENUM_M11(m,d,__VA_ARGS__) #define _ENUM_M10(m,d,x,...) m(d,9,x) _ENUM_ID(_ENUM_M9(m,d,__VA_ARGS__))
#define _ENUM_M13(m,d,x,...) _ENUM_A(m,d,12,x) _ENUM_M12(m,d,__VA_ARGS__) #define _ENUM_M11(m,d,x,...) m(d,10,x) _ENUM_ID(_ENUM_M10(m,d,__VA_ARGS__))
#define _ENUM_M14(m,d,x,...) _ENUM_A(m,d,13,x) _ENUM_M13(m,d,__VA_ARGS__) #define _ENUM_M12(m,d,x,...) m(d,11,x) _ENUM_ID(_ENUM_M11(m,d,__VA_ARGS__))
#define _ENUM_M15(m,d,x,...) _ENUM_A(m,d,14,x) _ENUM_M14(m,d,__VA_ARGS__) #define _ENUM_M13(m,d,x,...) m(d,12,x) _ENUM_ID(_ENUM_M12(m,d,__VA_ARGS__))
#define _ENUM_M16(m,d,x,...) _ENUM_A(m,d,15,x) _ENUM_M15(m,d,__VA_ARGS__) #define _ENUM_M14(m,d,x,...) m(d,13,x) _ENUM_ID(_ENUM_M13(m,d,__VA_ARGS__))
#define _ENUM_M17(m,d,x,...) _ENUM_A(m,d,16,x) _ENUM_M16(m,d,__VA_ARGS__) #define _ENUM_M15(m,d,x,...) m(d,14,x) _ENUM_ID(_ENUM_M14(m,d,__VA_ARGS__))
#define _ENUM_M18(m,d,x,...) _ENUM_A(m,d,17,x) _ENUM_M17(m,d,__VA_ARGS__) #define _ENUM_M16(m,d,x,...) m(d,15,x) _ENUM_ID(_ENUM_M15(m,d,__VA_ARGS__))
#define _ENUM_M19(m,d,x,...) _ENUM_A(m,d,18,x) _ENUM_M18(m,d,__VA_ARGS__) #define _ENUM_M17(m,d,x,...) m(d,16,x) _ENUM_ID(_ENUM_M16(m,d,__VA_ARGS__))
#define _ENUM_M20(m,d,x,...) _ENUM_A(m,d,19,x) _ENUM_M19(m,d,__VA_ARGS__) #define _ENUM_M18(m,d,x,...) m(d,17,x) _ENUM_ID(_ENUM_M17(m,d,__VA_ARGS__))
#define _ENUM_M21(m,d,x,...) _ENUM_A(m,d,20,x) _ENUM_M20(m,d,__VA_ARGS__) #define _ENUM_M19(m,d,x,...) m(d,18,x) _ENUM_ID(_ENUM_M18(m,d,__VA_ARGS__))
#define _ENUM_M22(m,d,x,...) _ENUM_A(m,d,21,x) _ENUM_M21(m,d,__VA_ARGS__) #define _ENUM_M20(m,d,x,...) m(d,19,x) _ENUM_ID(_ENUM_M19(m,d,__VA_ARGS__))
#define _ENUM_M23(m,d,x,...) _ENUM_A(m,d,22,x) _ENUM_M22(m,d,__VA_ARGS__) #define _ENUM_M21(m,d,x,...) m(d,20,x) _ENUM_ID(_ENUM_M20(m,d,__VA_ARGS__))
#define _ENUM_M24(m,d,x,...) _ENUM_A(m,d,23,x) _ENUM_M23(m,d,__VA_ARGS__) #define _ENUM_M22(m,d,x,...) m(d,21,x) _ENUM_ID(_ENUM_M21(m,d,__VA_ARGS__))
#define _ENUM_M25(m,d,x,...) _ENUM_A(m,d,24,x) _ENUM_M24(m,d,__VA_ARGS__) #define _ENUM_M23(m,d,x,...) m(d,22,x) _ENUM_ID(_ENUM_M22(m,d,__VA_ARGS__))
#define _ENUM_M26(m,d,x,...) _ENUM_A(m,d,25,x) _ENUM_M25(m,d,__VA_ARGS__) #define _ENUM_M24(m,d,x,...) m(d,23,x) _ENUM_ID(_ENUM_M23(m,d,__VA_ARGS__))
#define _ENUM_M27(m,d,x,...) _ENUM_A(m,d,26,x) _ENUM_M26(m,d,__VA_ARGS__) #define _ENUM_M25(m,d,x,...) m(d,24,x) _ENUM_ID(_ENUM_M24(m,d,__VA_ARGS__))
#define _ENUM_M28(m,d,x,...) _ENUM_A(m,d,27,x) _ENUM_M27(m,d,__VA_ARGS__) #define _ENUM_M26(m,d,x,...) m(d,25,x) _ENUM_ID(_ENUM_M25(m,d,__VA_ARGS__))
#define _ENUM_M29(m,d,x,...) _ENUM_A(m,d,28,x) _ENUM_M28(m,d,__VA_ARGS__) #define _ENUM_M27(m,d,x,...) m(d,26,x) _ENUM_ID(_ENUM_M26(m,d,__VA_ARGS__))
#define _ENUM_M30(m,d,x,...) _ENUM_A(m,d,29,x) _ENUM_M29(m,d,__VA_ARGS__) #define _ENUM_M28(m,d,x,...) m(d,27,x) _ENUM_ID(_ENUM_M27(m,d,__VA_ARGS__))
#define _ENUM_M31(m,d,x,...) _ENUM_A(m,d,30,x) _ENUM_M30(m,d,__VA_ARGS__) #define _ENUM_M29(m,d,x,...) m(d,28,x) _ENUM_ID(_ENUM_M28(m,d,__VA_ARGS__))
#define _ENUM_M32(m,d,x,...) _ENUM_A(m,d,31,x) _ENUM_M31(m,d,__VA_ARGS__) #define _ENUM_M30(m,d,x,...) m(d,29,x) _ENUM_ID(_ENUM_M29(m,d,__VA_ARGS__))
#define _ENUM_M33(m,d,x,...) _ENUM_A(m,d,32,x) _ENUM_M32(m,d,__VA_ARGS__) #define _ENUM_M31(m,d,x,...) m(d,30,x) _ENUM_ID(_ENUM_M30(m,d,__VA_ARGS__))
#define _ENUM_M34(m,d,x,...) _ENUM_A(m,d,33,x) _ENUM_M33(m,d,__VA_ARGS__) #define _ENUM_M32(m,d,x,...) m(d,31,x) _ENUM_ID(_ENUM_M31(m,d,__VA_ARGS__))
#define _ENUM_M35(m,d,x,...) _ENUM_A(m,d,34,x) _ENUM_M34(m,d,__VA_ARGS__) #define _ENUM_M33(m,d,x,...) m(d,32,x) _ENUM_ID(_ENUM_M32(m,d,__VA_ARGS__))
#define _ENUM_M36(m,d,x,...) _ENUM_A(m,d,35,x) _ENUM_M35(m,d,__VA_ARGS__) #define _ENUM_M34(m,d,x,...) m(d,33,x) _ENUM_ID(_ENUM_M33(m,d,__VA_ARGS__))
#define _ENUM_M37(m,d,x,...) _ENUM_A(m,d,36,x) _ENUM_M36(m,d,__VA_ARGS__) #define _ENUM_M35(m,d,x,...) m(d,34,x) _ENUM_ID(_ENUM_M34(m,d,__VA_ARGS__))
#define _ENUM_M38(m,d,x,...) _ENUM_A(m,d,37,x) _ENUM_M37(m,d,__VA_ARGS__) #define _ENUM_M36(m,d,x,...) m(d,35,x) _ENUM_ID(_ENUM_M35(m,d,__VA_ARGS__))
#define _ENUM_M39(m,d,x,...) _ENUM_A(m,d,38,x) _ENUM_M38(m,d,__VA_ARGS__) #define _ENUM_M37(m,d,x,...) m(d,36,x) _ENUM_ID(_ENUM_M36(m,d,__VA_ARGS__))
#define _ENUM_M40(m,d,x,...) _ENUM_A(m,d,39,x) _ENUM_M39(m,d,__VA_ARGS__) #define _ENUM_M38(m,d,x,...) m(d,37,x) _ENUM_ID(_ENUM_M37(m,d,__VA_ARGS__))
#define _ENUM_M41(m,d,x,...) _ENUM_A(m,d,40,x) _ENUM_M40(m,d,__VA_ARGS__) #define _ENUM_M39(m,d,x,...) m(d,38,x) _ENUM_ID(_ENUM_M38(m,d,__VA_ARGS__))
#define _ENUM_M42(m,d,x,...) _ENUM_A(m,d,41,x) _ENUM_M41(m,d,__VA_ARGS__) #define _ENUM_M40(m,d,x,...) m(d,39,x) _ENUM_ID(_ENUM_M39(m,d,__VA_ARGS__))
#define _ENUM_M43(m,d,x,...) _ENUM_A(m,d,42,x) _ENUM_M42(m,d,__VA_ARGS__) #define _ENUM_M41(m,d,x,...) m(d,40,x) _ENUM_ID(_ENUM_M40(m,d,__VA_ARGS__))
#define _ENUM_M44(m,d,x,...) _ENUM_A(m,d,43,x) _ENUM_M43(m,d,__VA_ARGS__) #define _ENUM_M42(m,d,x,...) m(d,41,x) _ENUM_ID(_ENUM_M41(m,d,__VA_ARGS__))
#define _ENUM_M45(m,d,x,...) _ENUM_A(m,d,44,x) _ENUM_M44(m,d,__VA_ARGS__) #define _ENUM_M43(m,d,x,...) m(d,42,x) _ENUM_ID(_ENUM_M42(m,d,__VA_ARGS__))
#define _ENUM_M46(m,d,x,...) _ENUM_A(m,d,45,x) _ENUM_M45(m,d,__VA_ARGS__) #define _ENUM_M44(m,d,x,...) m(d,43,x) _ENUM_ID(_ENUM_M43(m,d,__VA_ARGS__))
#define _ENUM_M47(m,d,x,...) _ENUM_A(m,d,46,x) _ENUM_M46(m,d,__VA_ARGS__) #define _ENUM_M45(m,d,x,...) m(d,44,x) _ENUM_ID(_ENUM_M44(m,d,__VA_ARGS__))
#define _ENUM_M48(m,d,x,...) _ENUM_A(m,d,47,x) _ENUM_M47(m,d,__VA_ARGS__) #define _ENUM_M46(m,d,x,...) m(d,45,x) _ENUM_ID(_ENUM_M45(m,d,__VA_ARGS__))
#define _ENUM_M49(m,d,x,...) _ENUM_A(m,d,48,x) _ENUM_M48(m,d,__VA_ARGS__) #define _ENUM_M47(m,d,x,...) m(d,46,x) _ENUM_ID(_ENUM_M46(m,d,__VA_ARGS__))
#define _ENUM_M50(m,d,x,...) _ENUM_A(m,d,49,x) _ENUM_M49(m,d,__VA_ARGS__) #define _ENUM_M48(m,d,x,...) m(d,47,x) _ENUM_ID(_ENUM_M47(m,d,__VA_ARGS__))
#define _ENUM_M51(m,d,x,...) _ENUM_A(m,d,50,x) _ENUM_M50(m,d,__VA_ARGS__) #define _ENUM_M49(m,d,x,...) m(d,48,x) _ENUM_ID(_ENUM_M48(m,d,__VA_ARGS__))
#define _ENUM_M52(m,d,x,...) _ENUM_A(m,d,51,x) _ENUM_M51(m,d,__VA_ARGS__) #define _ENUM_M50(m,d,x,...) m(d,49,x) _ENUM_ID(_ENUM_M49(m,d,__VA_ARGS__))
#define _ENUM_M53(m,d,x,...) _ENUM_A(m,d,52,x) _ENUM_M52(m,d,__VA_ARGS__) #define _ENUM_M51(m,d,x,...) m(d,50,x) _ENUM_ID(_ENUM_M50(m,d,__VA_ARGS__))
#define _ENUM_M54(m,d,x,...) _ENUM_A(m,d,53,x) _ENUM_M53(m,d,__VA_ARGS__) #define _ENUM_M52(m,d,x,...) m(d,51,x) _ENUM_ID(_ENUM_M51(m,d,__VA_ARGS__))
#define _ENUM_M55(m,d,x,...) _ENUM_A(m,d,54,x) _ENUM_M54(m,d,__VA_ARGS__) #define _ENUM_M53(m,d,x,...) m(d,52,x) _ENUM_ID(_ENUM_M52(m,d,__VA_ARGS__))
#define _ENUM_M56(m,d,x,...) _ENUM_A(m,d,55,x) _ENUM_M55(m,d,__VA_ARGS__) #define _ENUM_M54(m,d,x,...) m(d,53,x) _ENUM_ID(_ENUM_M53(m,d,__VA_ARGS__))
#define _ENUM_M57(m,d,x,...) _ENUM_A(m,d,56,x) _ENUM_M56(m,d,__VA_ARGS__) #define _ENUM_M55(m,d,x,...) m(d,54,x) _ENUM_ID(_ENUM_M54(m,d,__VA_ARGS__))
#define _ENUM_M58(m,d,x,...) _ENUM_A(m,d,57,x) _ENUM_M57(m,d,__VA_ARGS__) #define _ENUM_M56(m,d,x,...) m(d,55,x) _ENUM_ID(_ENUM_M55(m,d,__VA_ARGS__))
#define _ENUM_M59(m,d,x,...) _ENUM_A(m,d,58,x) _ENUM_M58(m,d,__VA_ARGS__) #define _ENUM_M57(m,d,x,...) m(d,56,x) _ENUM_ID(_ENUM_M56(m,d,__VA_ARGS__))
#define _ENUM_M60(m,d,x,...) _ENUM_A(m,d,59,x) _ENUM_M59(m,d,__VA_ARGS__) #define _ENUM_M58(m,d,x,...) m(d,57,x) _ENUM_ID(_ENUM_M57(m,d,__VA_ARGS__))
#define _ENUM_M61(m,d,x,...) _ENUM_A(m,d,60,x) _ENUM_M60(m,d,__VA_ARGS__) #define _ENUM_M59(m,d,x,...) m(d,58,x) _ENUM_ID(_ENUM_M58(m,d,__VA_ARGS__))
#define _ENUM_M62(m,d,x,...) _ENUM_A(m,d,61,x) _ENUM_M61(m,d,__VA_ARGS__) #define _ENUM_M60(m,d,x,...) m(d,59,x) _ENUM_ID(_ENUM_M59(m,d,__VA_ARGS__))
#define _ENUM_M63(m,d,x,...) _ENUM_A(m,d,62,x) _ENUM_M62(m,d,__VA_ARGS__) #define _ENUM_M61(m,d,x,...) m(d,60,x) _ENUM_ID(_ENUM_M60(m,d,__VA_ARGS__))
#define _ENUM_M64(m,d,x,...) _ENUM_A(m,d,63,x) _ENUM_M63(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, \ #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, \ _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, \ _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, \
_58, _59, _60, _61, _62, _63, _64, count, ...) count _58, _59, _60, _61, _62, _63, _64, count, ...) count
#define _ENUM_PP_COUNT(...) _ENUM_PP_COUNT_IMPL(__VA_ARGS__, 64, 63, 62, 61, \ #define _ENUM_PP_COUNT(...) _ENUM_ID(_ENUM_PP_COUNT_IMPL(__VA_ARGS__, 64, 63, \
60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42,\ 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44,\
41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23,\ 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25,\
22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,\ 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, \
1) 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) \ #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) \ 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>)EnumType::expression), ((better_enums::_eat_assign<EnumType>)EnumType::expression),
#define _ENUM_EAT_ASSIGN(EnumType, ...) \ #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; _hasExplicitValue(#expression) ? _trimmed_ ## index : #expression;
#define _ENUM_TRIM_STRINGS(...) \ #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, _final_ ## index,
#define _ENUM_REFER_TO_STRINGS(...) \ #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_SINGLE(ignored, index, expression) #expression,
#define _ENUM_STRINGIZE(...) \ #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 better_enums { \
namespace _data_ ## Enum { \ 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; \ typedef _name_iterable::iterator _name_iterator; \
\ \
_ENUM_CONSTEXPR static const std::size_t _size = \ _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 const char* _name(); \
_ENUM_CONSTEXPR static _value_iterable _values(); \ _ENUM_CONSTEXPR static _value_iterable _values(); \
@ -455,9 +457,9 @@ namespace _data_ ## Enum { \
enum PutNamesInThisScopeAlso { __VA_ARGS__ }; \ enum PutNamesInThisScopeAlso { __VA_ARGS__ }; \
\ \
_ENUM_CONSTEXPR const Enum value_array[] = \ _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, ...) \ #define _ENUM_CXX98_TRIM_STRINGS_ARRAYS(Enum, ...) \
inline const char** raw_names() \ 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; \ return value; \
} \ } \
\ \
@ -654,7 +657,7 @@ _ENUM_CONSTEXPR inline bool operator >=(const Enum &a, const Enum &b) \
// C++11 fast version // C++11 fast version
#define _ENUM_CXX11_PARTIAL_CONSTEXPR_TRIM_STRINGS_ARRAYS(Enum, ...) \ #define _ENUM_CXX11_PARTIAL_CONSTEXPR_TRIM_STRINGS_ARRAYS(Enum, ...) \
constexpr const char *the_raw_names[] = \ constexpr const char *the_raw_names[] = \
{ _ENUM_STRINGIZE(__VA_ARGS__) }; \ { _ENUM_ID(_ENUM_STRINGIZE(__VA_ARGS__)) }; \
\ \
constexpr const char * const * raw_names() \ 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 // C++11 slow all-constexpr version
#define _ENUM_CXX11_FULL_CONSTEXPR_TRIM_STRINGS_ARRAYS(Enum, ...) \ #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[] = \ 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() \ constexpr const char * const * name_array() \
{ \ { \
@ -773,7 +776,8 @@ _ENUM_CONSTEXPR inline bool operator >=(const Enum &a, const Enum &b) \
#endif #endif
#define ENUM(Enum, Integral, ...) \ #define ENUM(Enum, Integral, ...) \
_ENUM_TYPE(_ENUM_CXX11_UNDERLYING_TYPE, \ _ENUM_ID(_ENUM_TYPE( \
_ENUM_CXX11_UNDERLYING_TYPE, \
_ENUM_DEFAULT_SWITCH_TYPE, \ _ENUM_DEFAULT_SWITCH_TYPE, \
_ENUM_DEFAULT_SWITCH_TYPE_GENERATE, \ _ENUM_DEFAULT_SWITCH_TYPE_GENERATE, \
_ENUM_DEFAULT_TRIM_STRINGS_ARRAYS, \ _ENUM_DEFAULT_TRIM_STRINGS_ARRAYS, \
@ -781,10 +785,11 @@ _ENUM_CONSTEXPR inline bool operator >=(const Enum &a, const Enum &b) \
_ENUM_DEFAULT_DECLARE_INITIALIZE, \ _ENUM_DEFAULT_DECLARE_INITIALIZE, \
_ENUM_DEFAULT_DEFINE_INITIALIZE, \ _ENUM_DEFAULT_DEFINE_INITIALIZE, \
_ENUM_DEFAULT_CALL_INITIALIZE, \ _ENUM_DEFAULT_CALL_INITIALIZE, \
Enum, Integral, __VA_ARGS__) Enum, Integral, __VA_ARGS__))
#define SLOW_ENUM(Enum, Integral, ...) \ #define SLOW_ENUM(Enum, Integral, ...) \
_ENUM_TYPE(_ENUM_CXX11_UNDERLYING_TYPE, \ _ENUM_ID(_ENUM_TYPE( \
_ENUM_CXX11_UNDERLYING_TYPE, \
_ENUM_DEFAULT_SWITCH_TYPE, \ _ENUM_DEFAULT_SWITCH_TYPE, \
_ENUM_DEFAULT_SWITCH_TYPE_GENERATE, \ _ENUM_DEFAULT_SWITCH_TYPE_GENERATE, \
_ENUM_CXX11_FULL_CONSTEXPR_TRIM_STRINGS_ARRAYS, \ _ENUM_CXX11_FULL_CONSTEXPR_TRIM_STRINGS_ARRAYS, \
@ -792,12 +797,13 @@ _ENUM_CONSTEXPR inline bool operator >=(const Enum &a, const Enum &b) \
_ENUM_DO_NOT_DECLARE_INITIALIZE, \ _ENUM_DO_NOT_DECLARE_INITIALIZE, \
_ENUM_DO_NOT_DEFINE_INITIALIZE, \ _ENUM_DO_NOT_DEFINE_INITIALIZE, \
_ENUM_DO_NOT_CALL_INITIALIZE, \ _ENUM_DO_NOT_CALL_INITIALIZE, \
Enum, Integral, __VA_ARGS__) Enum, Integral, __VA_ARGS__))
#else #else
#define ENUM(Enum, Integral, ...) \ #define ENUM(Enum, Integral, ...) \
_ENUM_TYPE(_ENUM_CXX98_UNDERLYING_TYPE, \ _ENUM_ID(_ENUM_TYPE( \
_ENUM_CXX98_UNDERLYING_TYPE, \
_ENUM_DEFAULT_SWITCH_TYPE, \ _ENUM_DEFAULT_SWITCH_TYPE, \
_ENUM_DEFAULT_SWITCH_TYPE_GENERATE, \ _ENUM_DEFAULT_SWITCH_TYPE_GENERATE, \
_ENUM_CXX98_TRIM_STRINGS_ARRAYS, \ _ENUM_CXX98_TRIM_STRINGS_ARRAYS, \
@ -805,7 +811,7 @@ _ENUM_CONSTEXPR inline bool operator >=(const Enum &a, const Enum &b) \
_ENUM_DO_DECLARE_INITIALIZE, \ _ENUM_DO_DECLARE_INITIALIZE, \
_ENUM_DO_DEFINE_INITIALIZE, \ _ENUM_DO_DEFINE_INITIALIZE, \
_ENUM_DO_CALL_INITIALIZE, \ _ENUM_DO_CALL_INITIALIZE, \
Enum, Integral, __VA_ARGS__) Enum, Integral, __VA_ARGS__))
#endif #endif

View File

@ -71,24 +71,27 @@ def generate(stream, constants, length, script):
print >> stream, '' print >> stream, ''
print >> stream, '#define _ENUM_PP_MAP(macro, data, ...) \\' 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__)) \\' '_ENUM_PP_COUNT(__VA_ARGS__)) \\'
print >> stream, ' (macro, data, __VA_ARGS__)' print >> stream, ' (macro, data, __VA_ARGS__))'
print >> stream, '' print >> stream, ''
print >> stream, '#define _ENUM_PP_MAP_VAR_COUNT(count) ' + \ print >> stream, '#define _ENUM_PP_MAP_VAR_COUNT(count) ' + \
'_ENUM_M ## count' '_ENUM_M ## count'
print >> stream, '' 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, ''
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): for index in range(2, constants + 1):
print >> stream, '#define _ENUM_M' + str(index) + \ print >> stream, '#define _ENUM_M' + str(index) + \
'(m,d,x,...) _ENUM_A(m,d,' + str(index - 1) + \ '(m,d,x,...) m(d,' + str(index - 1) + \
',x) _ENUM_M' + str(index - 1) + \ ',x) _ENUM_ID(_ENUM_M' + str(index - 1) + \
'(m,d,__VA_ARGS__)' '(m,d,__VA_ARGS__))'
print >> stream, '' print >> stream, ''
pp_count_impl_prefix = '#define _ENUM_PP_COUNT_IMPL(_1,' pp_count_impl_prefix = '#define _ENUM_PP_COUNT_IMPL(_1,'
@ -104,13 +107,13 @@ def generate(stream, constants, length, script):
print >> stream, '' print >> stream, ''
pp_count_prefix = \ 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) stream.write(pp_count_prefix)
pp_count = MultiLine(stream = stream, indent = 4, pp_count = MultiLine(stream = stream, indent = 4,
initial_column = len(pp_count_prefix)) initial_column = len(pp_count_prefix))
for index in range(0, constants - 1): for index in range(0, constants - 1):
pp_count.write(' ' + str(constants - index) + ',') pp_count.write(' ' + str(constants - index) + ',')
pp_count.write(' 1)', last = True) pp_count.write(' 1))', last = True)
print >> stream, '' print >> stream, ''
print >> stream, '' print >> stream, ''