Macro to iteratively generate variable names

M

Marcus Kwok

I am designing a GUI (my question is not about GUIs) and I have named my
variables using a regular naming scheme. However, in order to simplify
the code using these variables, I have created an array of non-owning
pointers to these variables. I am trying to write a macro to generate
these variable names for me, but I am not sure if what I want to do is
possible.

The code below demonstrates what I want to do (except it is generating
function names instead of variable names). I would like to have a macro
that I can put in a loop to generate the various names. However, since
macros are expanded before the compilation phase, I know this won't work
like this (in the loop, the macro gets expanded to method_i_do() since
the actual values for 'i' do not get set until runtime).

If it is possible at all, I am seeking a simple solution. There are 45
variables, which can be grouped into sets of 5 that I will apply the
solution to. It's not a matter of laziness (I have already typed the
variable names explicitly); I would just like to avoid having lots of
lines of trivial code that are all very similar, but only if the
overhead of implementing the solution is not significantly greater than
listing all 45 variables.

Is this possible using templates, or any other standard technique?


#include <iostream>

void method_1_do() { std::cout << "Method 1\n"; }
void method_2_do() { std::cout << "Method 2\n"; }
void method_3_do() { std::cout << "Method 3\n"; }

#define METHOD_DO(pre, i, post) pre ## i ## post()

int main()
{
METHOD_DO(method_, 1, _do);
METHOD_DO(method_, 2, _do);
METHOD_DO(method_, 3, _do);

/*
for (int i = 0; i < 3; ++i) {
METHOD_DO(method_, i, _do);
}
*/

return 0;
}
 
W

wkaras

Marcus said:
I am designing a GUI (my question is not about GUIs) and I have named my
variables using a regular naming scheme. However, in order to simplify
the code using these variables, I have created an array of non-owning
pointers to these variables. I am trying to write a macro to generate
these variable names for me, but I am not sure if what I want to do is
possible.

The code below demonstrates what I want to do (except it is generating
function names instead of variable names). I would like to have a macro
that I can put in a loop to generate the various names. However, since
macros are expanded before the compilation phase, I know this won't work
like this (in the loop, the macro gets expanded to method_i_do() since
the actual values for 'i' do not get set until runtime).

If it is possible at all, I am seeking a simple solution. There are 45
variables, which can be grouped into sets of 5 that I will apply the
solution to. It's not a matter of laziness (I have already typed the
variable names explicitly); I would just like to avoid having lots of
lines of trivial code that are all very similar, but only if the
overhead of implementing the solution is not significantly greater than
listing all 45 variables.

Is this possible using templates, or any other standard technique?


#include <iostream>

void method_1_do() { std::cout << "Method 1\n"; }
void method_2_do() { std::cout << "Method 2\n"; }
void method_3_do() { std::cout << "Method 3\n"; }

#define METHOD_DO(pre, i, post) pre ## i ## post()

int main()
{
METHOD_DO(method_, 1, _do);
METHOD_DO(method_, 2, _do);
METHOD_DO(method_, 3, _do);

/*
for (int i = 0; i < 3; ++i) {
METHOD_DO(method_, i, _do);
}
*/

return 0;
}

I think this is the closest you can get to what you want:

#define VARLIST \
X(int, a) \
X(char, b) \
X(double, c)

// Define vars.
#undef X
#define X(TYPE, NAME) TYPE NAME;
VARLIST

// Define ptrs.
#undef X
#define X(TYPE, NAME) TYPE * p_##NAME = &NAME;
VARLIST
 
I

Ivan Vecerina

:I am designing a GUI (my question is not about GUIs) and I have named my
: variables using a regular naming scheme. However, in order to simplify
: the code using these variables, I have created an array of non-owning
: pointers to these variables. I am trying to write a macro to generate
: these variable names for me, but I am not sure if what I want to do is
: possible.
[...]

I'm not an expert in this, but you probably should look into the Boost
Preprocessor Metaprogramming library:
http://www.boost.org/libs/preprocessor/doc/index.html
The provided examples are likely to inspire you towards a solution
if a macro-based solution is what you are looking for.

Ivan
 
P

Phlip

Marcus said:
I am designing a GUI (my question is not about GUIs)

You are allowed to ask on-topic questions about GUIs here.
void method_1_do() { std::cout << "Method 1\n"; }
void method_2_do() { std::cout << "Method 2\n"; }
void method_3_do() { std::cout << "Method 3\n"; }

Why so many methods?

Why aren't they members of a class?

Have you researched how other C++ GUIs do this?

Can't you find a leaner abstraction with less duplicated code?

If not, here's a good technique to inflate code around macros:

http://www.codeproject.com/macro/metamacros.asp
 
M

Marcus Kwok

Ivan Vecerina said:
:I am designing a GUI (my question is not about GUIs) and I have named my
: variables using a regular naming scheme. However, in order to simplify
: the code using these variables, I have created an array of non-owning
: pointers to these variables. I am trying to write a macro to generate
: these variable names for me, but I am not sure if what I want to do is
: possible.
[...]

I'm not an expert in this, but you probably should look into the Boost
Preprocessor Metaprogramming library:
http://www.boost.org/libs/preprocessor/doc/index.html
The provided examples are likely to inspire you towards a solution
if a macro-based solution is what you are looking for.

Thanks, I'll take a look.
 
M

Marcus Kwok

Phlip said:
You are allowed to ask on-topic questions about GUIs here.


Why so many methods?

Why aren't they members of a class?

Sorry, this was really just demonstrating the problem of putting the
variable 'i' into the macro, since the literal 'i' instead of the
numerical value of 'i' gets substituted into the macro. Really, my code
is doing something more like this:


// These get generated by the GUI designer
TextBox* textbox_foo_1_low;
TextBox* textbox_foo_2_low;
TextBox* textbox_foo_3_low;
TextBox* textbox_foo_4_low;
TextBox* textbox_foo_5_low;

// This is an array of non-owning (weak?) pointers to the variables,
// which is only used to simplify code using the textboxes by allowing
// code that has to be applied to all of them to be placed in a loop.
TextBox* foo_textboxes[max];
foo_textboxes[0] = textbox_foo_1_low;
foo_textboxes[1] = textbox_foo_2_low;
foo_textboxes[2] = textbox_foo_3_low;
foo_textboxes[3] = textbox_foo_4_low;
foo_textboxes[4] = textbox_foo_5_low;

Have you researched how other C++ GUIs do this?

Can't you find a leaner abstraction with less duplicated code?

Actually, this is an abstraction because by doing this, I can now have
code that does, for example,

for (int i = 0; i < max; ++i) {
foo_textboxes->Visible = true;
}

instead of

textbox_foo_1_low->Visible = true;
textbox_foo_2_low->Visible = true;
textbox_foo_3_low->Visible = true;
textbox_foo_4_low->Visible = true;
textbox_foo_5_low->Visible = true;

It's the initialization of the array of pointers that I was hoping to
abstract more.
If not, here's a good technique to inflate code around macros:

http://www.codeproject.com/macro/metamacros.asp

Thanks, this looks interesting.
 
P

Phlip

I looked at that, and read, "I am designing a new GUI toolkit from scratch".

If you were, then a map of pointers to members would be a perfect C++ way to
accomplish the "property bag" feature of all GUI controls.

You are, instead, concocting a single application's GUI. You are automating
the system that plugs the View into the Controller of a
Model-View-Controller pattern. The table of links between fields is the
Controller.

For an example of growing such a system, download the preview PDF from
here...

http://www.zeroplayer.com/cgi-bin/wiki?TestFirstUserInterfaces

....then search for Model View Controller.

My system did not happen to use a batch of macros. Yours still might if your
project needs them.
It's the initialization of the array of pointers that I was hoping to
abstract more.

Right - that's what OO is for. You need View objects that represent your
target view, and that encapsulate all the batches of updates to the target
GUI Toolkit objects themselves. MVC wraps that situation perfectly.
 

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,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top