プリプロセッサで指数爆発させる

関数fと引数vのタプルと、整数nを渡すとvにfを2^n回適用する関数マクロを作った

#define PP_TUPLE_ELEM_0(a, b) a
#define PP_TUPLE_ELEM_1(a, b) b
#define PP_TUPLE_ELEM(n, tup) PP_TUPLE_ELEM_I(n, tup)
#define PP_TUPLE_ELEM_I(n, tup) PP_TUPLE_ELEM_ ## n tup

#define PP_EXP_REC_0(fv) PP_TUPLE_ELEM(0, fv)(PP_TUPLE_ELEM(1, fv))
#define PP_EXP_REC_1(fv) PP_EXP_REC_0((PP_TUPLE_ELEM(0, fv), PP_EXP_REC_0(fv)))
#define PP_EXP_REC_2(fv) PP_EXP_REC_1((PP_TUPLE_ELEM(0, fv), PP_EXP_REC_1(fv)))
#define PP_EXP_REC_3(fv) PP_EXP_REC_2((PP_TUPLE_ELEM(0, fv), PP_EXP_REC_2(fv)))
#define PP_EXP_REC_4(fv) PP_EXP_REC_3((PP_TUPLE_ELEM(0, fv), PP_EXP_REC_3(fv)))
#define PP_EXP_REC_5(fv) PP_EXP_REC_4((PP_TUPLE_ELEM(0, fv), PP_EXP_REC_4(fv)))
#define PP_EXP_REC_6(fv) PP_EXP_REC_5((PP_TUPLE_ELEM(0, fv), PP_EXP_REC_5(fv)))
#define PP_EXP_REC_7(fv) PP_EXP_REC_6((PP_TUPLE_ELEM(0, fv), PP_EXP_REC_6(fv)))
#define PP_EXP_REC_8(fv) PP_EXP_REC_7((PP_TUPLE_ELEM(0, fv), PP_EXP_REC_7(fv)))

#define PP_EXP_REC(n, fv) PP_EXP_REC_I(n, fv)
#define PP_EXP_REC_I(n, fv) PP_EXP_REC_ ## n (fv)

#define PP_TO_STR(a) PP_TO_STR_I(a)
#define PP_TO_STR_I(a) #a

#define EXP(v) exp v

void f() {
    std::cout << PP_TO_STR(PP_EXP_REC(8, (EXP, rec!))) << std::endl;  // exp exp exp exp (expがあと252個) rec!
}

追記:
タプル使わんでもいい方法を思いついた。

#define EXIST_PP_EXP_REC(n, f, v) EXIST_PP_EXP_REC_I(n, f, v)
#define EXIST_PP_EXP_REC_I(n, f, v) EXIST_PP_EXP_REC_ ## n(f, v)

#define EXIST_PP_EXP_REC_0(f, v) f(v)
#define EXIST_PP_EXP_REC_1(f, v) EXIST_PP_EXP_REC_0(f, EXIST_PP_EXP_REC_0(f, v))
#define EXIST_PP_EXP_REC_2(f, v) EXIST_PP_EXP_REC_1(f, EXIST_PP_EXP_REC_1(f, v))
#define EXIST_PP_EXP_REC_3(f, v) EXIST_PP_EXP_REC_2(f, EXIST_PP_EXP_REC_2(f, v))
#define EXIST_PP_EXP_REC_4(f, v) EXIST_PP_EXP_REC_3(f, EXIST_PP_EXP_REC_3(f, v))
#define EXIST_PP_EXP_REC_5(f, v) EXIST_PP_EXP_REC_4(f, EXIST_PP_EXP_REC_4(f, v))
#define EXIST_PP_EXP_REC_6(f, v) EXIST_PP_EXP_REC_5(f, EXIST_PP_EXP_REC_5(f, v))
#define EXIST_PP_EXP_REC_7(f, v) EXIST_PP_EXP_REC_6(f, EXIST_PP_EXP_REC_6(f, v))
#define EXIST_PP_EXP_REC_8(f, v) EXIST_PP_EXP_REC_7(f, EXIST_PP_EXP_REC_7(f, v))

もういっこ追記:一つ目のコードでタプル適用し忘れてたのを修正。