#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<__LINE__> : CTCOrigin<__VA_ARGS__> { };
#define UPDATE_CTC(name) \
template <> struct name<__LINE__> : name<__LINE__ - 1> \
{ \
static constexpr int value = name<__LINE__ - 1>::value + increment; \
};
#define GET_CTC(name) \
name<__LINE__>::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;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGUgPGludCBPUklHSU4gPSAwLCBpbnQgSU5DUkVNRU5UID0gMT4Kc3RydWN0IENUQ09yaWdpbiA6IHN0ZDo6aW50ZWdyYWxfY29uc3RhbnQ8aW50LCBPUklHSU4+CnsKICAgc3RhdGljIGNvbnN0ZXhwciBpbnQgaW5jcmVtZW50ID0gSU5DUkVNRU5UOwp9OwoKI2RlZmluZSBDUkVBVEVfQ1RDKG5hbWUsIC4uLikgXAogICB0ZW1wbGF0ZSA8c2l6ZV90IE4+IHN0cnVjdCBuYW1lIDogbmFtZTxOIC0gMT4geyB9OyBcCiAgIHRlbXBsYXRlIDw+IHN0cnVjdCBuYW1lPF9fTElORV9fPiA6IENUQ09yaWdpbjxfX1ZBX0FSR1NfXz4geyB9OwoKI2RlZmluZSBVUERBVEVfQ1RDKG5hbWUpIFwKICAgdGVtcGxhdGUgPD4gc3RydWN0IG5hbWU8X19MSU5FX18+IDogbmFtZTxfX0xJTkVfXyAtIDE+IFwKICAgeyBcCiAgICAgIHN0YXRpYyBjb25zdGV4cHIgaW50IHZhbHVlID0gbmFtZTxfX0xJTkVfXyAtIDE+Ojp2YWx1ZSArIGluY3JlbWVudDsgXAogICB9OwoKI2RlZmluZSBHRVRfQ1RDKG5hbWUpIFwKICAgbmFtZTxfX0xJTkVfXz46OnZhbHVlCgoKQ1JFQVRFX0NUQyhjdGMxKTsKQ1JFQVRFX0NUQyhjdGMyLCAyKTsKQ1JFQVRFX0NUQyhjdGMzLCAyMCwgLTUpOwpjb25zdGV4cHIgYXV0byBpMTEgPSBHRVRfQ1RDKGN0YzEpOwpjb25zdGV4cHIgYXV0byBpMTIgPSBHRVRfQ1RDKGN0YzIpOwpjb25zdGV4cHIgYXV0byBpMTMgPSBHRVRfQ1RDKGN0YzMpOwoKVVBEQVRFX0NUQyhjdGMxKTsKVVBEQVRFX0NUQyhjdGMyKTsKVVBEQVRFX0NUQyhjdGMzKTsKY29uc3RleHByIGF1dG8gaTIxID0gR0VUX0NUQyhjdGMxKTsKY29uc3RleHByIGF1dG8gaTIyID0gR0VUX0NUQyhjdGMyKTsKY29uc3RleHByIGF1dG8gaTIzID0gR0VUX0NUQyhjdGMzKTsKClVQREFURV9DVEMoY3RjMSk7ClVQREFURV9DVEMoY3RjMik7ClVQREFURV9DVEMoY3RjMyk7CmNvbnN0ZXhwciBhdXRvIGkzMSA9IEdFVF9DVEMoY3RjMSk7CmNvbnN0ZXhwciBhdXRvIGkzMiA9IEdFVF9DVEMoY3RjMik7CmNvbnN0ZXhwciBhdXRvIGkzMyA9IEdFVF9DVEMoY3RjMyk7CgppbnQgbWFpbigpCnsKCXN0ZDo6Y291dCA8PCBpMTEgPDwgIiwgIiA8PCBpMTIgPDwgIiwgIiA8PCBpMTMgPDwgc3RkOjplbmRsOwoJc3RkOjpjb3V0IDw8IGkyMSA8PCAiLCAiIDw8IGkyMiA8PCAiLCAiIDw8IGkyMyA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgaTMxIDw8ICIsICIgPDwgaTMyIDw8ICIsICIgPDwgaTMzIDw8IHN0ZDo6ZW5kbDsKfQ==