Fix for VS2010 usage of __VA_ARGS__

This commit is contained in:
Freddie Akeroyd
2019-06-08 20:46:21 +01:00
parent 1cc5f3fbd6
commit 905d8a3b4a

View File

@ -37,28 +37,35 @@ _ENUM_CAST(type)
#define _NTH_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, N, ...) N #define _NTH_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, N, ...) N
/*
* we need to use _EXPAND below to work around a problem in Visual Studio 2010
* where __VA_ARGS__ is treated as a single argument
* See https://stackoverflow.com/questions/5134523/msvc-doesnt-expand-va-args-correctly
*/
#define _EXPAND( x ) x
#define _fe_0(_call, ...) #define _fe_0(_call, ...)
#define _fe_1(_call, x) _call(x) #define _fe_1(_call, x) _call(x)
#define _fe_2(_call, x, ...) _call(x) _fe_1(_call, __VA_ARGS__) #define _fe_2(_call, x, ...) _call(x) _EXPAND(_fe_1(_call, __VA_ARGS__))
#define _fe_3(_call, x, ...) _call(x) _fe_2(_call, __VA_ARGS__) #define _fe_3(_call, x, ...) _call(x) _EXPAND(_fe_2(_call, __VA_ARGS__))
#define _fe_4(_call, x, ...) _call(x) _fe_3(_call, __VA_ARGS__) #define _fe_4(_call, x, ...) _call(x) _EXPAND(_fe_3(_call, __VA_ARGS__))
#define _fe_5(_call, x, ...) _call(x) _fe_4(_call, __VA_ARGS__) #define _fe_5(_call, x, ...) _call(x) _EXPAND(_fe_4(_call, __VA_ARGS__))
#define _fe_6(_call, x, ...) _call(x) _fe_5(_call, __VA_ARGS__) #define _fe_6(_call, x, ...) _call(x) _EXPAND(_fe_5(_call, __VA_ARGS__))
#define _fe_7(_call, x, ...) _call(x) _fe_6(_call, __VA_ARGS__) #define _fe_7(_call, x, ...) _call(x) _EXPAND(_fe_6(_call, __VA_ARGS__))
#define _fe_8(_call, x, ...) _call(x) _fe_7(_call, __VA_ARGS__) #define _fe_8(_call, x, ...) _call(x) _EXPAND(_fe_7(_call, __VA_ARGS__))
#define _fe_9(_call, x, ...) _call(x) _fe_8(_call, __VA_ARGS__) #define _fe_9(_call, x, ...) _call(x) _EXPAND(_fe_8(_call, __VA_ARGS__))
#define _fe_10(_call, x, ...) _call(x) _fe_9(_call, __VA_ARGS__) #define _fe_10(_call, x, ...) _call(x) _EXPAND(_fe_9(_call, __VA_ARGS__))
#define MACRO_FOR_EACH(x, ...) \ #define MACRO_FOR_EACH(x, ...) \
_NTH_ARG(_, ##__VA_ARGS__, \ _EXPAND(_NTH_ARG(_, ##__VA_ARGS__, \
_fe_10, _fe_9, _fe_8, _fe_7, _fe_6, _fe_5, _fe_4, _fe_3, _fe_2, _fe_1, _fe_0) \ _fe_10, _fe_9, _fe_8, _fe_7, _fe_6, _fe_5, _fe_4, _fe_3, _fe_2, _fe_1, _fe_0) \
(x, ##__VA_ARGS__) (x, ##__VA_ARGS__))
/* Enum to string magic */ /* Enum to string magic */
#define ENUM(type,...) \ #define ENUM(type,...) \
enum type { __VA_ARGS__ }; \ enum type { __VA_ARGS__ }; \
static inline const char* type##ToStr(int x) {switch(x){MACRO_FOR_EACH(_CASE_LINE,__VA_ARGS__) default: return "invalid";}} \ static inline const char* type##ToStr(int x) {switch(x){_EXPAND(MACRO_FOR_EACH(_CASE_LINE,__VA_ARGS__)) default: return "invalid";}} \
_ENUM_CAST(type) _ENUM_CAST(type)
#endif #endif