Francesco Dondi
Francesco Dondi

Reputation: 1094

Matching list of #define to a pattern

I have an header with a lot of #defines, like this:

#define XY_ABC_FOO 1
#define XY_ABC_BAR 3
#define XY_ABC_PIPPO 5
#define XY_ABC_PLUTO 7
#define XY_ABC_ETC 19
...

and so on and on.

I'd like to put all those in a vector.I can do it by hand (in a few minutes).

std::vector<int> defs = { 1, 3, 5, 7, 19 , ... } 

But then, next time definition are added in the header, someone will have to remember to add them in my code too.

Is there any very clever preprocessor/metaprogramming trick to catch them all at compile time? I don't particularly care about fast compilation, it's test code so it will be compiled seldom and mostly overnight.

Upvotes: 1

Views: 79

Answers (2)

HolyBlackCat
HolyBlackCat

Reputation: 96699

You seem to want to achieve that using only #defines, but I'm almost completely sure that it's impossible.

But if you'd allow those values to be constexprs, then you'd be able to do following. (And it's probably a best thing you can get without external tools.)

#define DEFS \
    C(XY_ABC_FOO,    1) \
    C(XY_ABC_BAR,    3) \
    C(XY_ABC_PIPPO,  5) \
    C(XY_ABC_PLUTO,  7) \
    C(XY_ABC_ETC,   19)

#define C(name, value) constexpr int name = value;
DEFS 
#undef C

/* ... */

#define C(name, value) value,
std::vector<int> defs = {DEFS};
#undef C

Upvotes: 0

Barmar
Barmar

Reputation: 781868

You could do it with awk:

awk '/^#define XY_ABC_\w+ \d+$/ { 
    if(line) {
        line = line ", " $2
    } else {
        line = "std::vector<int> defs = { " $2
    }
    END { print line " };" }' < header.hpp > defs.hpp

Then in your main program use #include defs.hpp to get the declaration.

Upvotes: 1

Related Questions