Preprocessor trick?

S

SerGioGio

Hello,

Is there a way to #define a (set of) macro that will turn:
FUNC(a)(b)(c)
into:
func(a, b, c)
regardless of the number of parameters?

i.e:
FUNC(a)(b)(c) ---> func(a, b, c)
FUNC(a)(b) ---> func(a, b)
FUNC(a) ---> func(a)

Despite my efforts I can't find one so I am wondering whether there actually
is.

Thanks in advance!

SerGioGio
 
P

puzzlecracker

SerGioGio said:
Hello,

Is there a way to #define a (set of) macro that will turn:
FUNC(a)(b)(c)
into:
func(a, b, c)
regardless of the number of parameters?

i.e:
FUNC(a)(b)(c) ---> func(a, b, c)
FUNC(a)(b) ---> func(a, b)
FUNC(a) ---> func(a)

Despite my efforts I can't find one so I am wondering whether there actually
is.

Thanks in advance!

SerGioGio

NO!
 
M

Mike Wahler

SerGioGio said:
Hello,

Is there a way to #define a (set of) macro that will turn:
FUNC(a)(b)(c)
into:
func(a, b, c)
regardless of the number of parameters?

i.e:
FUNC(a)(b)(c) ---> func(a, b, c)
FUNC(a)(b) ---> func(a, b)
FUNC(a) ---> func(a)

Despite my efforts I can't find one so I am wondering whether there actually
is.

I'm not sure, but I've seen some rather clever tricks done
with macros. BUT: I wouldn't even try, because:
Why do you want to do this? Macros don't allow for the level of
type saftey and error checking that functions do (all they are
is a text-substitution mechanism). Their necessity is much less
in C++ than in C. Especially in the context you ask about,
because C++ has function overloading and default parameters.


Overloaded functions:

/* A */ void func(int a){}
/* B */ void func(int a, int b){}
/* C */ void func(int a, int b, int c){}

int main()
{
func(1); /* calls version A */
func(1, 2); /* calls version B */
func(1, 2, 3); /* calls version C */
return 0;
}

Default paramters:

void func(int a = 0, int b = 0, int c = 0){}

int main()
{
func(); /* same as func(0, 0, 0); */
func(1); /* same as func(1, 0, 0); */
func(1, 2); /* same as func(1, 2, 0); */
func(1, 2, 3);
return 0;
}

(The defaults can be any values you want, and the
function need not refer to any parameters not
applicable to a particular call).

-Mike
 
V

Victor Bazarov

SerGioGio said:
Hello,

Is there a way to #define a (set of) macro that will turn:
FUNC(a)(b)(c)
into:
func(a, b, c)
regardless of the number of parameters?

i.e:
FUNC(a)(b)(c) ---> func(a, b, c)
FUNC(a)(b) ---> func(a, b)
FUNC(a) ---> func(a)

Despite my efforts I can't find one so I am wondering whether there
actually
is.

Well, it's relatively simple to prove that there can be no such macro.
If you write

FUNC(a)(b)

why should the preprocessor continue looking ahead for (b), when it can
stop right there and simply substitute FUNC(a) with func(a)? So, the
preprocessor cannot decide, I guess.

You can simulate this with C++, though. By overloading operator() and
defining what value it returns, you probably could make it so if you
write

func1(a)(b)(c)

it actually eventually calls some func(a,b,c)... I'll leave it for you
to try.

V
 
J

Jonathan Turkanis

SerGioGio said:
Hello,

Is there a way to #define a (set of) macro that will turn:
FUNC(a)(b)(c)
into:
func(a, b, c)
regardless of the number of parameters?

i.e:
FUNC(a)(b)(c) ---> func(a, b, c)
FUNC(a)(b) ---> func(a, b)
FUNC(a) ---> func(a)

Victor's argument that it can't be done sounds right, but my intuitions about
the preprocessor are often wrong.

It can *almost* be done, though, using the Boost Preprocessor Metaprogramming
library:

Program:

#include <boost/preprocessor/seq/enum.hpp>

#define FUNC(seq) func(BOOST_PP_SEQ_ENUM(seq))

FUNC((a))
FUNC((a)(b))
FUNC((a)(b)(c))

Preprocessed output:

func(a)
func(a, b)
func(a, b, c)
SerGioGio

Jonathan
 
A

Alan Krueger

SerGioGio said:
Is there a way to #define a (set of) macro that will turn:
FUNC(a)(b)(c)
into:
func(a, b, c)
regardless of the number of parameters?

The specific example with three parameters might be constructed like this:

#define A(x) x)
#define B(x) x,A
#define SUM(x) sum(x,B

int sum( int a, int b, int c )
{
return a + b + c;
}

int a = 2;
int b = 3;
int c = 5;
int s = SUM(a)(b)(c);

Not sure if iterative replacement is standard, or just supported by the
compiler I'm using, but this last line gets transformed to

int s = sum(a,b,c);

Doing this for *any* number of parameters with a single set of macros is
unlikely, because you'd have to use a recursive macro, which cannot be
propertly terminated.
 
S

SerGioGio

I'm not sure, but I've seen some rather clever tricks done
with macros. BUT: I wouldn't even try, because:
Why do you want to do this? Macros don't allow for the level of
type saftey and error checking that functions do (all they are
is a text-substitution mechanism). Their necessity is much less
in C++ than in C. Especially in the context you ask about,
because C++ has function overloading and default parameters.

Actually I would like to get the text of the arguments, not only their
values...
so I can only use a macros and #x command.
This could be achieved using a FUNC(a, b, c) macro but the FUNC(a)(b)(c)
form suits more to the purpose.

SerGioGio
 
S

SerGioGio

Not sure if iterative replacement is standard, or just supported by the
compiler I'm using, but this last line gets transformed to

int s = sum(a,b,c);

Doing this for *any* number of parameters with a single set of macros is
unlikely, because you'd have to use a recursive macro, which cannot be
propertly terminated.

Yes, it really looks like doing it for any number of parameters is
impossible.
I tried the following:

#define FUNC2(x) func(dummy FUNC2_END_A(x)
#define FUNC2_END_A(x) ,x FUNC2_END_B
#define FUNC2_END_B(x) ,x FUNC2_END_A

which does:

FUNC2(a)(b)(c) --> func(dummy ,a ,b ,c FUNC2_END_B
FUNC2(a)(b) --> func(dummy ,a ,b FUNC2_END_A
FUNC2(a) --> func(dummy ,a FUNC2_END_B

unfortunately there is no way to transform subsequentely... FUNC2_END_A and
FUNC2_END_B into )

The solution I am now considering is doing:

enum FUNC6_END { FUNC6_END_A, FUNC6_END_B };
#define FUNC6(x) func* FUNC6_END_A(x)
#define FUNC6_END_A(x) (x)*(#x)*FUNC6_END_B
#define FUNC6_END_B(x) (x)*(#x)*FUNC6_END_A

which does:

FUNC6(a)(b)(c) --> func*(a)*(#a)*(b)*(#b)*(c)*(#c)*FUNC6_END_A
FUNC6(a)(b) --> func*(a)*(#a)*(b)*(#b)*FUNC6_END_B
FUNC6(a) --> func*(a)*(#a)*FUNC6_END_A

As you can see, my aim is to get the text and values of all the "arguments"
of the macro FUNC6, and that is why I can't just use overload operator().

This solution requires slightly more complicated code, possibly slighlty
slower, and there may be a problem with the precedence of operators. But it
looks its the closest solution.

SerGioGio
 
?

=?ISO-8859-1?Q?Tobias_G=FCntner?=

SerGioGio said:
#define FUNC2(x) func(dummy FUNC2_END_A(x)
#define FUNC2_END_A(x) ,x FUNC2_END_B
#define FUNC2_END_B(x) ,x FUNC2_END_A

enum FUNC_END { FUNC2_END_A, FUNC2_END_B }
#define FUNC2(x) func(FUNC2_END_A(x)
#define FUNC2_END_A(x) x, FUNC2_END_B
#define FUNC2_END_B(x) x, FUNC2_END_A
FUNC2(a)(b)(c) --> func(dummy ,a ,b ,c FUNC2_END_B
FUNC2(a)(b) --> func(dummy ,a ,b FUNC2_END_A
FUNC2(a) --> func(dummy ,a FUNC2_END_B

FUNC2(a)(b)(c)) --> func(a, b, c, FUNC2_END_B)
FUNC2(a)(b)) --> func(a, b, FUNC2_END_A)
FUNC2(a)) --> func(a, FUNC2_END_B)

If you
#define FUNC3(x) FUNC2 x )
it should be possible to write FUNC3((a)(b)(c)), which looks
much nicer ;)

A different approach:

extern class func_t
{
public:
func_t() :
FUNC_END_A(*this), FUNC_END_B(*this) {}

template<class T>
func_t& operator()(const ::std::pair<T, const char*>& param)
{
std::cout << param.second << ": " <<
param.first << "\n";
return *this;
}

func_t& FUNC_END_A;
func_t& FUNC_END_B;

} func;

#define FUNC func.FUNC_END_A
#define FUNC_END_A(x) FUNC_END_A:):std::make_pair(x, #x)).FUNC_END_B
#define FUNC_END_B(x) FUNC_END_B:):std::make_pair(x, #x)).FUNC_END_A

// in some cpp file
func_t func;

int main()
{
int a = 0, b = 1, c = 2;
FUNC(a)(b)(c);
FUNC(a)(b);
FUNC(a);
}
 
T

Thomas Matthews

SerGioGio said:
Hello,

Is there a way to #define a (set of) macro that will turn:
FUNC(a)(b)(c)
into:
func(a, b, c)
regardless of the number of parameters?

i.e:
FUNC(a)(b)(c) ---> func(a, b, c)
FUNC(a)(b) ---> func(a, b)
FUNC(a) ---> func(a)

Despite my efforts I can't find one so I am wondering whether there actually
is.

Thanks in advance!

SerGioGio

I believe a better design would be to pass a structure
to the function that contains information about the
parameters, such as quantity, locations and type.

enum Parameter_Type
{
PT_CHAR, PT_UCHAR, PT_INT, PT_UINT,
PT_DOUBLE, PT_FLOAT, PT_LONG
};

struct Param_Attributes
{
enum Parameter_Type type;
void * pointer_to_data;
}

void Process_Parameters(struct Param_Attributes * array,
size_t quantity)
{
/* ... */
}

The idea here is that one function is used for multiple
data types versus one function for each quantity and
variation of types.

Just a thought...

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,021
Latest member
AkilahJaim

Latest Threads

Top