#if !defined(UNIQUE_ID_HEADER) #define UNIQUE_ID_HEADER #define MAX_COUNTER 64 namespace counter_impl { template struct counter : counter {}; template<> struct counter<0> {}; template struct size_type { typedef char(&type)[N + 1]; }; size_type<0>::type check(...); } #define CURRENT(T) (sizeof(check((T*)0, (::counter_impl::counter*)0)) - 1) #define SET(T, N) size_type::type check(T*, ::counter_impl::counter*) namespace type_counter_impl { using namespace counter_impl; struct type_counter_1 {}; template struct type_counter_2 {}; template struct sizer : size_type { }; template struct next_values { static const int next1 = (Value + 1) / MAX_COUNTER; static const int next2 = (Value + 1) % MAX_COUNTER; typedef type_counter_2 counter2; }; template struct type_map { }; size_type<0>::type type_value(...); } #define TYPE_COUNTER_1_CURRENT CURRENT(type_counter_1) #define TYPE_COUNTER_2_CURRENT CURRENT(type_counter_2) #define GENERATE_SIZER(Type) ::type_counter_impl::sizer< \ GET_INDEX_FROM_TYPE(Type), \ TYPE_COUNTER_1_CURRENT, \ TYPE_COUNTER_2_CURRENT > #define GET_NEXT(Type) \ ::type_counter_impl::next_values // Just set the type index, can be called as many times as you want. #define SET_TYPE_INDEX(Type) \ namespace type_counter_impl { \ GENERATE_SIZER(Type)::type type_value(Type*); \ SET(type_counter_1, GET_NEXT(Type)::next1); \ SET(GET_NEXT(Type)::counter2, GET_NEXT(Type)::next2); \ } // Set the type index plus the type map back from the index. Can only // be called once per type. Could probably call it multiple times // by using negative numbers for the map index when it has been defined // before. #define SET_TYPE(Type) \ SET_TYPE_INDEX(Type) \ namespace type_counter_impl { \ template <> \ struct type_map \ { \ typedef Type type; \ }; \ } #define GET_INDEX_FROM_TYPE(Type) \ (sizeof(::type_counter_impl::type_value((Type*) 0)) - 1) #define GET_TYPE_FROM_INDEX(Index) \ ::type_counter_impl::type_map::type #endif