I have many macros that end up generating code. For example:
#define CODE_GEN_IDENT1_HDR(PARAM1, PARAM2, PARAM3) \
// code generated
#define CODE_GEN_IDENT2_HDR(PARAM1, PARAM2, PARAM3) \
// code generated
#define CODE_GEN_IDENT1_SRC(PARAM1, PARAM2, PARAM3) \
// code generated
#define CODE_GEN_IDENT2_SRC(PARAM1, PARAM2, PARAM3) \
// code generated
The idea is that HDR
generates functions definitions and SRC
generates their implementation. All macros have the same amount of arguments (in this example, 3). IDENT
can be any name like MATH
, TRIG
, ALGS
, CONTAINERS
, etc. This is what I want to focus on.
I'm trying to build up a macro that can generate all of these macros macros with different IDENT
using variadic macros. For example:
// Concatenate macros to a standard form
#define CONCATH_(C) CODE_GEN_##C##_HDR
#define CONCATC_(C) CODE_GEN_##C##_SRC
// CONCATH concatenates to HDR
// CONCATC concatenates to SRC
#define CONCATH(C) CONCATH_(C)
#define CONCATC(C) CONCATC_(C)
#define MASTER_MACRO(PARAM1, PARAM2, PARAM3, ...) \
// Code that generates all other macros
// using CONCATH and CONCATC
// how could this be done?
When I write:
MASTER_MACRO(int, "Hello", char *, MATH, TRIG, CONT)
I would like to have something like:
CODE_GEN_MATH_HDR(int, "Hello", char *)
CODE_GEN_TRIG_HDR(int, "Hello", char *)
CODE_GEN_CONT_HDR(int, "Hello", char *)
CODE_GEN_MATH_SRC(int, "Hello", char *)
CODE_GEN_TRIG_SRC(int, "Hello", char *)
CODE_GEN_CONT_SRC(int, "Hello", char *)
To somehow access the given arguments and concatenate each, making both header and source.
What I currently have is a fixed length macro like:
MASTER_MACRO(PARAM1, PARAM2, PARAM3, MATH, TRIG, CONT, DUPL, SORT) \
CONCATH(MATH)(PARAM1, PARAM2, PARAM3)
CONCATH(TRIG)(PARAM1, PARAM2, PARAM3)
...
CONCATC(MATH)(PARAM1, PARAM2, PARAM3)
...
And when the user doesn't want to generate CONT
, DUPL
or any other macro he's got to pass in a pre-defined argumet like _
meaning he is not wanting to generate that and having an empty macro:
#define CODE_GEN___SRC(PARAM1, PARAM2, PARAM3) // Empty
But this is not good enough. On different projects these different IDENT
have different names, so having to make new master macros are a bit annoying.
But the big questions are:
- Can this be done?
- Is there a simple way to do this?
- Can it be done using only standard C (no compiler-dependent macro)?