2

I am trying to achieve something like the following:

#define def_name(delim, ...) ??? // how will this variadic macro concatenate its parameters to define a new variable?

// Calling `def_name` as follows should define a new variable.

def_name("_", "abc", "def", "ghi");

// The following code should be generated after invoking the above macro.

inline constexpr char const abc_def_ghi_name[]{"abc_def_ghi"};

// Invoking the macro as:

def_name("", "abc", "def", "ghi");

// should produce the following code:

inline constexpr char const abcdefghi_name[]{"abcdefghi"};

What should the def_name macro be to support the above use-case? Also, can something similar be achieved at compile-time using C++ templates/constexpr?

ChrisMM
  • 8,448
  • 13
  • 29
  • 48
Meekaa Saangoo
  • 309
  • 1
  • 2
  • 8

1 Answers1

2

With little syntax change (MACRO can stringify, but cannot unstringify), your usage might be:

def_name(, a, b)
def_name(_, a, b, c)

You might do, with some upper bound limit:

#define def_name1(sep, p1) \
    inline constexpr char const p1##_name[]{#p1};
#define def_name2(sep, p1, p2) \
    inline constexpr char const p1##sep##p2##_name[]{#p1 #sep #p2};
#define def_name3(sep, p1, p2, p3) \
    inline constexpr char const p1##sep##p2##sep##p3##_name[]{#p1 #sep #p2 #sep #p3};
// ...

and to dispatch to the correct one, some utilities:

#define COUNT_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...)    N
#define COUNT(...)   COUNT_N(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
// Warning: COUNT() return 1 (as COUNT(A)) :-/

#define IDENTITY(N) N
#define APPLY(macro, ...) IDENTITY(macro(__VA_ARGS__))

and finally

#define DISPATCH(N) def_name ## N
#define def_name(sep, ...) IDENTITY(APPLY(DISPATCH, COUNT(__VA_ARGS__)))(sep, __VA_ARGS__)

Demo

Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • Nice mix of constexpr and macros :) I am accepting your answer, but I think I will go with pure constexpr solution instead of mixing macros and constexpr. – Meekaa Saangoo Nov 16 '21 at 14:07
  • @MeekaaSaangoo: There are no "`constexpr`" in that solution (it is just present to respect your expected output). Stringification and token manipulation cannot be done without MACROs :/ (you can indeed concatenate string/`std::array` with constexpr though). – Jarod42 Nov 16 '21 at 14:15