Pavel P
Pavel P

Reputation: 16892

C-preprocessor: extract [0...N] args from __VA_ARGS__

How can I extract [0...N] arguments from VA_ARGS assuming that N will be less or equal to the number of arguments.

Example:

#define MY_SEQ r0, r1, r2,  r3,  r4,  r5,  r6,  r7, \
               r8, r9, r10, r11, r12, r13, r14, r15

#define EXTRACT_N(n, SEQ) {... magic ...}

...

EXTRACT_N(5, (MY_SEQ()));

should expand to:

{r0, r1, r2, r3, r4};

It's ok to assume that sequence elements are of this form WHATEVER##N where N is Nth element.

I'm looking for some nice solution to this problem NOT using BOOST, e.g. I'd like to understand how it can be done.

I did it using iterative approach, but I'd like to know if there is some other way to do it. Here's how I implemented it:

#define EXTRACT_1(t0)               t0
#define EXTRACT_2(t0, t1)           EXTRACT_1(t0),t1
#define EXTRACT_3(t0, t1, t2)       EXTRACT_2(t0, t1),t2
#define EXTRACT_4(t0, t1, t2, t3)   EXTRACT_3(t0, t1, t2),t3
...

Upvotes: 4

Views: 1657

Answers (1)

You cannot do that in the general case. The c preprocessor is not that flexible.

You might have something like

#define EXTRACT_N(N,A) EXTRACTTHEM ## N(A)

and have

#define EXTRACTTHEM1(X, ...) X
#define EXTRACTTHEM2(X,Y, ...) X,Y

etc

(it is easy to generate an arbitrary large, but bounded, set of such macros).

There are more powerful processors than cpp, e.g. m4 or gpp

You might consider instead generating your C or C++ code (using your own script, or some generator) and having your building system (e.g. Makefile) take care of generating the C code from something different.

Upvotes: 3

Related Questions