'C++ Macro with "double function"

I am looking for a way to use a single macro call (multiple times):

#define MAGIC  ???????

MAGIC(ref1, "text 1");
MAGIC(ref2, "text 2");

to expand into something like this:

const char *texts[] = {"text 1", "text 2"};
enum {ref1, ref2}

I got two ways of create first line:

#define _COUNT(z, a, b, c, d, e, f, g, h, i, j, count, ...) count
#define COUNT(...) _COUNT(0, ##__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)

#define EVENTS(...)                                           \
    const struct                                              \
    {                                                         \
        int n = COUNT(__VA_ARGS__);                           \
        const char *texts[COUNT(__VA_ARGS__)] = {__VA_ARGS__}; \
    }

EVENTS("text 1", "text 2", "text N");

and:

#define BEGIN(n) \
    const struct        \
    {                   \
        int cnt = (n);  \
        const char *texts[(n) + 1] = {

#define EVENT(id, text) text,

#define END \
    0              \
    }              \
    ;              \
    }              \
    ;

BEGIN(2)
EVENT(ref1, "text 1")
EVENT(ref2, "text 2")
END

both will work to create the fist line. However the first not even include the reference name and the second one ignores it.

I am sure I can create de second line as well, but how to create both at the same time?

I have hundreds of pairs like this to declare in a more complex code, and hope this will improve reading.

Any way to do it using GCC?



Solution 1:[1]

how to create both at the same time?

It is not possible - macros have no "state" that they can "set" from inside a macro expansion. You can't remember that you have seen some macro invocation and act on it later.

What you are (re-)implementing are X macros, where you use the same file with a different macro twice, solving the problem with remembering state. "State" depends on the location in the file, where you can change the macro definition.

// file_with_magic.h
MAGIC(ref1, "text 1")
MAGIC(ref2, "text 2")

// header.h
const char *texts[] = {
#define MAGIC(a, b)  b
#include <file_with_magic.h>
#undef MAGIC
};
enum {
#define MAGIC(a, b)  a
#include <file_with_magic.h>
#undef MAGIC
};

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 KamilCuk