#include <iostream>
template <int ORIGIN = 0, int INCREMENT = 1>
struct $CTCOrigin : std::integral_constant<int, ORIGIN>
{
static constexpr int increment = INCREMENT;
};
#define CREATE_CTC(name, ...) \
template <size_t N> struct name : name<N - 1> { }; \
template <> struct name<0> : $CTCOrigin<__VA_ARGS__> \
{ \
static constexpr int counter_base = __COUNTER__; \
};
#define UPDATE_CTC_(name, counter) \
template <> struct name<counter - name<0>::counter_base> \
: name<counter - name<0>::counter_base - 1> \
{ \
using base = name<counter - name<0>::counter_base - 1>; \
static constexpr int value = base::value + increment; \
};
#define UPDATE_CTC(name) UPDATE_CTC_(name, __COUNTER__)
#define GET_CTC(name) \
name<__COUNTER__ - name<0>::counter_base>::value
CREATE_CTC(ctc1);
CREATE_CTC(ctc2, 2);
CREATE_CTC(ctc3, 20, -5);
constexpr auto i11 = GET_CTC(ctc1);
constexpr auto i12 = GET_CTC(ctc2);
constexpr auto i13 = GET_CTC(ctc3);
UPDATE_CTC(ctc1);
UPDATE_CTC(ctc2);
UPDATE_CTC(ctc3);
constexpr auto i21 = GET_CTC(ctc1);
constexpr auto i22 = GET_CTC(ctc2);
constexpr auto i23 = GET_CTC(ctc3);
UPDATE_CTC(ctc1);
UPDATE_CTC(ctc2);
UPDATE_CTC(ctc3);
constexpr auto i31 = GET_CTC(ctc1);
constexpr auto i32 = GET_CTC(ctc2);
constexpr auto i33 = GET_CTC(ctc3);
int main()
{
std::cout << i11 << ", " << i12 << ", " << i13 << std::endl;
std::cout << i21 << ", " << i22 << ", " << i23 << std::endl;
std::cout << i31 << ", " << i32 << ", " << i33 << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGUgPGludCBPUklHSU4gPSAwLCBpbnQgSU5DUkVNRU5UID0gMT4Kc3RydWN0ICRDVENPcmlnaW4gOiBzdGQ6OmludGVncmFsX2NvbnN0YW50PGludCwgT1JJR0lOPgp7CiAgIHN0YXRpYyBjb25zdGV4cHIgaW50IGluY3JlbWVudCA9IElOQ1JFTUVOVDsKfTsKCiNkZWZpbmUgQ1JFQVRFX0NUQyhuYW1lLCAuLi4pIFwKICAgdGVtcGxhdGUgPHNpemVfdCBOPiBzdHJ1Y3QgbmFtZSA6IG5hbWU8TiAtIDE+IHsgfTsgXAogICB0ZW1wbGF0ZSA8PiBzdHJ1Y3QgbmFtZTwwPiA6ICRDVENPcmlnaW48X19WQV9BUkdTX18+IFwKICAgeyBcCiAgICAgIHN0YXRpYyBjb25zdGV4cHIgaW50IGNvdW50ZXJfYmFzZSA9IF9fQ09VTlRFUl9fOyBcCiAgIH07CgojZGVmaW5lIFVQREFURV9DVENfKG5hbWUsIGNvdW50ZXIpIFwKICAgdGVtcGxhdGUgPD4gc3RydWN0IG5hbWU8Y291bnRlciAtIG5hbWU8MD46OmNvdW50ZXJfYmFzZT4gXAogICA6IG5hbWU8Y291bnRlciAtIG5hbWU8MD46OmNvdW50ZXJfYmFzZSAtIDE+IFwKICAgeyBcCiAgICAgIHVzaW5nIGJhc2UgPSBuYW1lPGNvdW50ZXIgLSBuYW1lPDA+Ojpjb3VudGVyX2Jhc2UgLSAxPjsgXAogICAgICBzdGF0aWMgY29uc3RleHByIGludCB2YWx1ZSA9IGJhc2U6OnZhbHVlICsgaW5jcmVtZW50OyBcCiAgIH07CiNkZWZpbmUgVVBEQVRFX0NUQyhuYW1lKSBVUERBVEVfQ1RDXyhuYW1lLCBfX0NPVU5URVJfXykKCiNkZWZpbmUgR0VUX0NUQyhuYW1lKSBcCiAgIG5hbWU8X19DT1VOVEVSX18gLSBuYW1lPDA+Ojpjb3VudGVyX2Jhc2U+Ojp2YWx1ZQoKQ1JFQVRFX0NUQyhjdGMxKTsKQ1JFQVRFX0NUQyhjdGMyLCAyKTsKQ1JFQVRFX0NUQyhjdGMzLCAyMCwgLTUpOwpjb25zdGV4cHIgYXV0byBpMTEgPSBHRVRfQ1RDKGN0YzEpOwpjb25zdGV4cHIgYXV0byBpMTIgPSBHRVRfQ1RDKGN0YzIpOwpjb25zdGV4cHIgYXV0byBpMTMgPSBHRVRfQ1RDKGN0YzMpOwoKVVBEQVRFX0NUQyhjdGMxKTsKVVBEQVRFX0NUQyhjdGMyKTsKVVBEQVRFX0NUQyhjdGMzKTsKY29uc3RleHByIGF1dG8gaTIxID0gR0VUX0NUQyhjdGMxKTsKY29uc3RleHByIGF1dG8gaTIyID0gR0VUX0NUQyhjdGMyKTsKY29uc3RleHByIGF1dG8gaTIzID0gR0VUX0NUQyhjdGMzKTsKClVQREFURV9DVEMoY3RjMSk7ClVQREFURV9DVEMoY3RjMik7ClVQREFURV9DVEMoY3RjMyk7CmNvbnN0ZXhwciBhdXRvIGkzMSA9IEdFVF9DVEMoY3RjMSk7CmNvbnN0ZXhwciBhdXRvIGkzMiA9IEdFVF9DVEMoY3RjMik7CmNvbnN0ZXhwciBhdXRvIGkzMyA9IEdFVF9DVEMoY3RjMyk7CgppbnQgbWFpbigpCnsKCXN0ZDo6Y291dCA8PCBpMTEgPDwgIiwgIiA8PCBpMTIgPDwgIiwgIiA8PCBpMTMgPDwgc3RkOjplbmRsOwoJc3RkOjpjb3V0IDw8IGkyMSA8PCAiLCAiIDw8IGkyMiA8PCAiLCAiIDw8IGkyMyA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgaTMxIDw8ICIsICIgPDwgaTMyIDw8ICIsICIgPDwgaTMzIDw8IHN0ZDo6ZW5kbDsKfQ==