Проявка плёнок молотком
Feb. 28th, 2015 12:33 am![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Красивая реализация счётчика периода компиляции на плюсах. Ноги, понятно, растут от Александреску, здесь публикуется из эстетических соображений.
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