Creating a list of string arguments with arguments with variations and late extensions

I have the following problem - a given variable number of arguments macro argX to create a list of string arguments #argX

Example:

LIST(A, B) -> "A", "B"
LIST(A, B, C) -> "A", "B", "C"

I use Boost, so this macro is not too difficult to implement using helper macros for each number of arguments and sending LIST (...) to the corresponding LIST_n (arg1, ... argn).

The problem starts when the LIST entries themselves are macros. In this case (if I use ... and __VA_ARGS__) the macros expand before they are built, giving:

#define A 10
LIST(A, B) -> "10", "B"

I want this to work with macros defined in Windows headers, and most of the values ​​are macros (MB_OK, AF_INET, ...), so all I get is a list of string numbers.

__VA_ARGS__, :

#define A 10
#define LIST_1(arg0) #arg0
LIST_1(A) -> "A"

, __VA_ARGS__ ( LIST_1, , ), .

C?

+4
1

, msvc. - (. ), __VA_ARGS__ . , , . C99 __VA_ARGS__ :

/* This counts the number of args */
#define NARGS_SEQ(_1,_2,_3,_4,_5,_6,_7,_8,N,...) N
#define NARGS(...) NARGS_SEQ(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1)

/* This will let macros expand before concating them */
#define PRIMITIVE_CAT(x, y) x ## y
#define CAT(x, y) PRIMITIVE_CAT(x, y)

/* p is an empty placeholder used to inhibit the expansion of __VA_ARGS__ */
#define STRINGIZE_ALL(p, ...) FIRST(NARGS(__VA_ARGS__), PRIMITIVE_STRINGIZE_ALL(p ## __VA_ARGS__,~,~,~,~,~,~,~,~))
#define PRIMITIVE_STRINGIZE_ALL(x1, x2, x3, x4, x5, x6, x7, x8, ...)  #x1, #x2, #x3, #x4, #x5, #x6, #x7, #x8

/* Retrieve the first n arguments from __VA_ARGS__ */
#define FIRST(n, ...) CAT(FIRST_, n)(__VA_ARGS__,~,~,~,~,~,~,~,~)
#define FIRST_1(x1, ...) x1
#define FIRST_2(x1, x2, ...) x1, x2
#define FIRST_3(x1, x2, x3, ...) x1, x2, x3
#define FIRST_4(x1, x2, x3, x4, ...) x1, x2, x3, x4
#define FIRST_5(x1, x2, x3, x4, x5, ...) x1, x2, x3, x4, x5
#define FIRST_6(x1, x2, x3, x4, x5, x6, ...) x1, x2, x3, x4, x5, x6
#define FIRST_7(x1, x2, x3, x4, x5, x6, x7, ...) x1, x2, x3, x4, x5, x6, x7
#define FIRST_8(x1, x2, x3, x4, x5, x6, x7, x8, ...) x1, x2, x3, x4, x5, x6, x7, x8

#define A 10
STRINGIZE_ALL(, A, B)

8 gcc clang 3.4 .

+1

All Articles