tarnyagin: (Default)
Dmitry Tarnyagin ([personal profile] tarnyagin) wrote2015-02-28 12:33 am
Entry tags:

Проявка плёнок молотком

Красивая реализация счётчика периода компиляции на плюсах. Ноги, понятно, растут от Александреску, здесь публикуется из эстетических соображений.


template <int T>
struct IntToType
{ enum {value = T}; };

template <class T, class U>
class CStaticCounter
: public CStaticCounter<IntToType<T::value - 1>, U>
{};

#define DEF_STATIC_COUNTER(type) \
class CStaticCounterType_ ## type;\
template<class U> \
class CStaticCounter<IntToType<__LINE__>, U> \
{ unsigned char m_space[1]; }

#define INC_STATIC_COUNTER(type) \
template<> \
class CStaticCounter<IntToType<__LINE__>, CStaticCounterType_ ## type> \
{ unsigned char m_space[GET_STATIC_COUNTER(type) + 2]; }

#define ADD_STATIC_COUNTER(type, val) \
template<> \
class CStaticCounter<IntToType<__LINE__>, CStaticCounterType_ ## type> \
{ unsigned char m_space[GET_STATIC_COUNTER(type) + 1 + (val)]; }

#define GET_STATIC_COUNTER(type) \
(sizeof(CStaticCounter<IntToType<__LINE__ - 1>, CStaticCounterType_ ## type>) - 1)

#if 0
// Usage:
DEF_STATIC_COUNTER(test);

static const int cnt0 = GET_STATIC_COUNTER(test); // -> 0

INC_STATIC_COUNTER(test);

static const int cnt1 = GET_STATIC_COUNTER(test); // -> 1

INC_STATIC_COUNTER(test);
INC_STATIC_COUNTER(test);

static const int cnt2 = GET_STATIC_COUNTER(test); // -> 3

ADD_STATIC_COUNTER(test, -1);

static const int cnt3 = GET_STATIC_COUNTER(test); // -> 2
#endif