7

I would like to write a preprocessor macro that does one thing if it's argument is a parenthesized tuple of tokens, like this:

MY_MACRO((x, y))

and something else if it's just a single token, like this:

MY_MACRO(x)

Is that possible?

How about distinguishing between the number of space-separated tokens, i.e. between MY_MACRO(x) and MY_MACRO(x y)?

Note that I am not trying to overload based on the number of arguments - it's a unary macro in all cases.

EDIT: I am willing to use variadic macros if they help

4
  • 1
    This is impossible in C/C++. You should define two different macros. Write more detailed what do you need (code example). Commented Mar 2, 2011 at 19:37
  • For the first question: with or without variadic macro support? For the second question: no. Commented Mar 2, 2011 at 19:38
  • Maybe stackoverflow.com/questions/2632300/… has some ideas you can use Commented Mar 2, 2011 at 19:47
  • @James Yes, I am willing to use variadic macros. Commented Mar 2, 2011 at 19:54

2 Answers 2

7

As for your first question, the following macros might meet your purpose:

#define CONCAT_( x, y ) x ## y
#define CONCAT( x, y ) CONCAT_( x, y )
#define IS_SINGLE_1(...) 0
#define IGNORE(...)
#define IS_SINGLE_2_0           0 IGNORE(
#define IS_SINGLE_2_IS_SINGLE_1 1 IGNORE(
#define IS_SINGLE( x ) CONCAT( IS_SINGLE_2_, IS_SINGLE_1 x ) )
IS_SINGLE((x, y)) // 0
IS_SINGLE(x)      // 1

Macro IS_SINGLE is expanded to 1 if the argument is single token, otherwise, 0.

Hope this helps

Sign up to request clarification or add additional context in comments.

4 Comments

Awesome, thanks! I assume the other one (distinguishing between number of space-separated tokens) is impossible as James said...
For space-separated it's impossible. For comma-separated, there is a solution for any bounded limit on the number of arguments.
@HighCommander4: Thanks! As you mentioned, as for space separated arguments, unless arguments are strictly restricted(for example only x, y and z are allowed), I think it is generally very difficult(impossible?)... If m4 is allowed, probably it is the way to go :-)
This is the first time I hear of m4... it looks interesting. Thanks for the tip :)
2

Using boost.preprocessor

#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/seq/for_each.hpp>

#define SEQ (w)(x)(y)(z)

#define MACRO(r, data, elem) BOOST_PP_CAT(elem, data)

BOOST_PP_SEQ_FOR_EACH(MACRO, _, SEQ) // expands to w_ x_ y_ z_

It's not exactly the same as even a single argument case requires parenthesis. But It does allow a variable number of parenthesized arguments.

Also a possibility: Use the BOOST_PP_IF, BOOST_PP_EQUAL, and BOOST_PP_TUPLE_ELEM to do something like:

MACRO(1, a)
MACRO(2, (a,b) )
MACRO(3, (a,b,c) )

or so.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.