Понадобилось мне как то объявить набор шаблонных структур типа:
template< typename T1, typename T2, ... >
struct some_struct {
T1 var1;
T2 var2;
};
typedef some_struct< int, char > new_type;
Да ещё с переменным числом типов.
Сваял вот такую конструкцию. Кому надо берите пользуйтесь:
#ifndef __datastruct_h__
#define __datastruct_h__
#define _NOP()
#define _E1(x) x
#define _COMA() ,
#define _SEMICOLUMN() ;
#define _TYPENAME() typename
#define _VARGF(f,x) _E1(/_E1(**f)/_NOP()/_E1(f*)/_NOP() x f _SEMICOLUMN()/_E1(**)/)
#define _VARGF_BEGIN(f,x) _E1(/_E1(**f)/_NOP()/_E1(f*)/_NOP() x f _SEMICOLUMN()/_E1(**)/)
#define _VARGF_T(f,x) _E1(/_E1(**f)/_NOP()/_E1(f*)/_COMA() _TYPENAME() x/_E1(**)/)
#define _VARGF_BEGIN_T(f,x) _E1(/_E1(**f)/_NOP()/_E1(f*)/_NOP() _TYPENAME() x/_E1(**)/)
#define _TV_BEGIN(t,v) \
_VARGF_BEGIN(v,t)
#define _TV(t,v) \
_VARGF(v,t)
#define _VARGTI(x) _E1(/_E1(**x)/_NOP()/_E1(x*)/_COMA() x/_E1(**)/)
#define _VARGTI_BEGIN(x) _E1(/_E1(**x)/_NOP()/_E1(x*)/_NOP() x/_E1(**)/)
#define DECLARE_STRUCT_T(name, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11) \
template< _VARGF_BEGIN_T(m1,T1) _VARGF_T(m2,T2) _VARGF_T(m3,T3) _VARGF_T(m4,T4) _VARGF_T(m5,T5) \
_VARGF_T(m6,T6) _VARGF_T(m7,T7) _VARGF_T(m8,T8) _VARGF_T(m9,T9) _VARGF_T(m10,T10) _VARGF_T(m11,T11) \
> \
struct name \
{ \
_TV_BEGIN(T1,m1) \
_TV(T2,m2) \
_TV(T3,m3) \
_TV(T4,m4) \
_TV(T5,m5) \
_TV(T6,m6) \
_TV(T7,m7) \
_TV(T8,m8) \
_TV(T9,m9) \
_TV(T10,m10) \
_TV(T11,m11) \
};
#define DECLARE_TYPE_T(new_type, s_name, t1, m1, t2, m2, t3, m3, t4, m4, t5, m5, t6, m6, t7, m7, t8, m8, t9, m9, t10, m10, t11, m11 ) \
DECLARE_STRUCT_T(s_name, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11 ) \
typedef s_name< _VARGTI_BEGIN(t1) _VARGTI(t2) _VARGTI(t3) _VARGTI(t4) _VARGTI(t5) _VARGTI(t6) \
_VARGTI(t7) _VARGTI(t8) _VARGTI(t9) _VARGTI(t10) _VARGTI(t11) \
> new_type;
#endif
Для примера вот это:
typedef void* void_ptr;
DECLARE_STRUCT_T( test_struct, x, y, z )
DECLARE_TYPE_T(new_type, sstruct, int, x, const char, z, void_ptr, y )
Раскроется вот в это:
template< typename T1 , typename T2 , typename T3 >
struct test_struct {
T1 x ;
T2 y ;
T3 z ;
};
template< typename T1 , typename T2 , typename T3 >
struct sstruct {
T1 x ;
T2 z ;
T3 y ;
};
typedef sstruct< int , const char , void_ptr > new_type;
Что можно было сделать лучше?
Это преобразование аргументов t1, t2, ... макроса DECLARE_TYPE_T()
внутри кода макроса в:
typedef t1 tt1;
typedef t2 tt2;
Потому как если в качестве аргумента будет выступать тип* то макрос будет раскрыт не правильно.
Из за этого для void* в тестовом примере пришлось сделать typedef void* void_ptr;
Если будет желание сделаю. А мне и так как есть сгодилось.