макросы (шаблонные структуры)
От: nen777w  
Дата: 23.06.08 13:04
Оценка:
Понадобилось мне как то объявить набор шаблонных структур типа:

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;

Если будет желание сделаю. А мне и так как есть сгодилось.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.