By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,385 Members | 1,737 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,385 IT Pros & Developers. It's quick & easy.

multi block macro

P: n/a
Is it any possibility to define a macro that produces several blocks.
For example the input is :

BEFIN
ITEM(one)
ITEM(two)
ITEM(three)
END

or, alternatively,

ITEMS(one, two, three)

After preprocessing I need:

enum {one, two, three};

void on_one();
void on_two();
void on_three();

int map(char* id)
{
if (strcmp(id, "one") == 0) return one;
if (strcmp(id, "two") == 0) return two;
if (strcmp(id, "three") == 0) return three;
}

May 30 '07 #1
Share this Question
Share on Google+
8 Replies


P: n/a
ge****@gmail.com wrote:
Is it any possibility to define a macro that produces several blocks.
For example the input is :

BEFIN
ITEM(one)
ITEM(two)
ITEM(three)
END

or, alternatively,

ITEMS(one, two, three)

After preprocessing I need:

enum {one, two, three};

void on_one();
void on_two();
void on_three();

int map(char* id)
{
if (strcmp(id, "one") == 0) return one;
if (strcmp(id, "two") == 0) return two;
if (strcmp(id, "three") == 0) return three;
}
What problem are you encountering while trying to accomplish your
goal? Let's start with

#define ITEMS(a,b,c) enum { a, b, c }; \
void on_##a(); void on_##b(); void on_##c(); \
int map(char const* id) { \
return 42; \
}

Now's your turn.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
May 30 '07 #2

P: n/a
On May 30, 10:17 am, gel...@gmail.com wrote:
Is it any possibility to define a macro that produces several blocks.
For example the input is :

BEFIN
ITEM(one)
ITEM(two)
ITEM(three)
END

or, alternatively,

ITEMS(one, two, three)

After preprocessing I need:

enum {one, two, three};

void on_one();
void on_two();
void on_three();

int map(char* id)
{
if (strcmp(id, "one") == 0) return one;
if (strcmp(id, "two") == 0) return two;
if (strcmp(id, "three") == 0) return three;}
Hello.

Actually, yes, it is, but only in the alternative form used by you:

#define ITEMS(one, two, three) \
enum { one, two, three }; \
void on_ ## one (); \
void on_ ## two (); \
void on_ ## three ();

[]s

================
Wanderley Caloni
http://www.cthings.org

May 30 '07 #3

P: n/a
What problem are you encountering while trying to accomplish your
goal? Let's start with
Well, I'm implementing an interface between activex javascript and c++
backend. Every javascript call is translated into a query to a
function that retuns this call id, i.e., it converts a function name
into some unique integer. Second a function is invoked, and this
functions is called with this id. For example, let's assume, there are
two javascript functions: read and write. C++ code should be (for the
sake of simplicity I ommit a lot of unnecisesary details):

enum {read, write}

int get_id(char* name)
{
if (strcmp(name, "read")==0) return read;
if (strcmp(name, "write")==0) return write;
}

void invoke(int id)
{
if (id == read) on_read();
if (id == write) on_write;
}

I want to define macroses that generate this code automatically.

May 30 '07 #4

P: n/a
Sorry, I forgot to note, the number of arguments is not known ion
advance.

May 30 '07 #5

P: n/a
ge****@gmail.com wrote:
Sorry, I forgot to note, the number of arguments is not known ion
advance.
Variadic macros are coming in the next Standard, IIRC. At this
time you'll have to introduce all 1 through N macros yourself,
manually.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
May 30 '07 #6

P: n/a
Actually, visual c++ already has got __VA_ARGS__, but to the best of
my knowladge there is no way to iterate through the args list.

BTW, I found a different solution. ITEM(one), ITEM(two), ... may be
put into an additional header and it should be includede several times
with different enviroment.

May 30 '07 #7

P: n/a
On May 30, 8:17 pm, gel...@gmail.com wrote:
Is it any possibility to define a macro that produces several blocks.
For example the input is :

BEFIN
ITEM(one)
ITEM(two)
ITEM(three)
END

or, alternatively,

ITEMS(one, two, three)

After preprocessing I need:

enum {one, two, three};

void on_one();
void on_two();
void on_three();

int map(char* id)
{
if (strcmp(id, "one") == 0) return one;
if (strcmp(id, "two") == 0) return two;
if (strcmp(id, "three") == 0) return three;

}
You can reformulate this so that you're doing it in a different way.
This is the way that I've done this sort of thing in the past.

Use a global for the next id number:

int g_nextID = 1;

Use a map to store the function to run given an id or a name (use
wstring because JavaScript is UTF-16):

std::map< int, boost::function< void () g_byID;
std::map< std::wstring, boost::function< void () g_byName;

A superclass can now handle the registration:

class Function {
public:
Function( const std::wstring &name )
: m_id( g_nextID++ ), m_name( name ) {
g_byID[ m_id ] = boost::bind( &Function::execute, this );
g_byName[ m_name ] = g_byID[ m_id ];
}
virtual void execute() const = 0;
};

Now to add a "read" function:

class Read : public Function {
public:
Read() : Function( L"read" ) {}
void execute() const {
// Code to execute
}
} g_doRead;

To execute then by name or by id you simply execute the thing in the
map:

g_byID[ theID ]();

or

g_byName[ theName ]();

You can use boost::lambda to bind extra parameters and then pass the
missing ones in at invocation.

It looks different, but works just the same. If the ID numbers must be
g'teed the same all the time then issue the ID numbers yourself and
pass them from the constructor like the name. Or consider generating
the ID as a hash of the name.

A big advantage of this is that you can late load libraries (using
something like LoadLibrary in Windows) so the range of functions
supported can be extended much more neatly than otherwise possible as
you don't have an enum to edit.
K

May 31 '07 #8

P: n/a
On May 30, 3:17 pm, gel...@gmail.com wrote:
Is it any possibility to define a macro that produces several blocks.
For example the input is :
BEFIN
ITEM(one)
ITEM(two)
ITEM(three)
END
or, alternatively,
ITEMS(one, two, three)
After preprocessing I need:
enum {one, two, three};
void on_one();
void on_two();
void on_three();
int map(char* id)
{
if (strcmp(id, "one") == 0) return one;
if (strcmp(id, "two") == 0) return two;
if (strcmp(id, "three") == 0) return three;

}
Is there any reason this has to be done with macros. Victor has
pretty much covered the situation from within C++, but for
something like this, I'd normally use AWK to generate the code
from lines that look like:
one two three
It would only take about five minutes to write the AWK, and it
would be easily understood at a glance.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

May 31 '07 #9

This discussion thread is closed

Replies have been disabled for this discussion.