IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

membres en fonction d'un template


Sujet :

Langage C++

  1. #1
    Membre averti
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Points : 392
    Points
    392
    Par défaut membres en fonction d'un template
    J'ai encore une autre question sur les templates qui me travaille depuis un certain temps: est-ce qu'il est possible de faire un "branchement" selon un paramètre de template ?

    Par exemple, du genre suivant: (code qui ne compilera pas)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    template<typename _T, int _sizeT>
    struct vec_proto
    {
      union
      {
         _T a[_sizeT];
        struct
        {
           _T x;
    ##if(_sizeT >= 2)
           _T y;
    ##if(_sizeT >= 3)
           _T z;
    ##if(_sizeT >= 4)
           _T w;
    ##if(_sizeT > 4)
    #pragma error;
    ##endif
    ##endif
    ##endif
    ##endif
        };
      };
    };

  2. #2
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 861
    Points
    11 861
    Par défaut
    Salut,

    Bon déjà là ça rentre dans le cadre de la métaprogrammation (pour des solutions "automatisées").
    Tu trouveras de quoi te satisfaire sur le sujet (niveau lecture + outils) dans l'article de Laurent (http://loulou.developpez.com/tutoriels/cpp/metaprog/) et dans Boost.MPL (http://www.boost.org/doc/libs/1_35_0...doc/index.html).

    Toutefois, la solution la plus facile à mettre en place dans ton cas, c'est de spécialiser selon la valeur de sizeT.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    template<typename _T, int _sizeT>
    struct vec_proto
    {
      union
      {
         _T a[_sizeT];
           struct 
           {
              _T x;
           };
       };
    };
     
    template <typename _T>
    struct vec_proto<_T, 2>
    {
       union
       {
          _T a[2];
          struct
          {
             _T x;
             _T y;
          };
       };
    };
     
    // etc...
    Et pour générer les spécialisations automatiquement, regarde du côté de Boost.Preprocessor (http://www.boost.org/doc/libs/1_35_0...doc/index.html).

  3. #3
    Membre du Club
    Inscrit en
    Mai 2005
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 73
    Points : 68
    Points
    68
    Par défaut
    Je connais assez mal la méta-programmation, mais ton problème m'a donné envie de m'amuser un peu, voilà ce qui en est ressorti :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    //Permet de créer une structure contenant N attributs nommés x1..xN
     
    template<int a, int b>
    struct sub
    {
        static const int res = a - b;
    };
     
    template<typename T, int N>
    struct attr
    {
    };
     
    #define ATTR(n)                                     \
     template<typename T>                               \
     struct attr<T, n> : public attr<T, sub<n, 1>::res> \
     {                                                  \
         T x##n;                                        \
     }
     
    ATTR(1);
    ATTR(2);
    ATTR(3);
    ATTR(4);
     
    int main()
    {
        attr<int, 1> a;
     
        a.x1;
        //a.x2 --> erreur de compilation
     
        attr<int, 2> b;
     
        b.x1;
        b.x2; // --> ok
     
        attr<int, 5> notok; // malheureusement, cela passe à la compil
     
        //notok.x1; --> si on essaye d'atteindre un attribut, erreur de compil
     
        return 0;
    }
    Je n'ai pas mis le tableau, mais je ne pense que cela pose trop de problèmes.

  4. #4
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Tu te complique la vie avec ta structure sub.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    //...
    struct attr<T, n> : public attr<T,n-1>		    \
    //....
    passe tout aussi bien.

    Edit:
    Ce code empèche att<int,5> de compiler
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    template<typename T, int N> struct attr;
    template <typename T> struct attr<T,0>{};
     
    #define ATTR(n)                                     \
     template<typename T>                               \
     struct attr<T, n> : public attr<T,n-1>		    \
     {                                                  \
         T x##n;                                        \
     }
     
    ATTR(1);
    ATTR(2);
    ATTR(3);
    ATTR(4);
     
    int main()
    {
        attr<int, 1> a;
     
        a.x1;
        //a.x2 --> erreur de compilation
     
        attr<int, 2> b;
     
        b.x1;
        b.x2; // --> ok
     
        attr<int, 5> notok; //passe plus
     
        return 0;
    }

  5. #5
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 861
    Points
    11 861
    Par défaut
    Pour empêcher d'instancier à plus de 4 et moins de 1, on peut utiliser un static assert, ceux de boost pour le moment par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #define ATTR(n)                                     \
     template<typename T>                               \
     struct attr<T, n> : public attr<T, n-1> \
     {                      
         BOOST_STATIC_ASSERT(n > 0 && n < 5)       \
         T x##n;                                                   \
     }

  6. #6
    Membre du Club
    Inscrit en
    Mai 2005
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 73
    Points : 68
    Points
    68
    Par défaut
    Citation Envoyé par Davidbrcz Voir le message
    Tu te complique la vie avec ta structure sub.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    //...
    struct attr<T, n> : public attr<T,n-1>		    \
    //....
    passe tout aussi bien.
    Tout à fait, c'est une complication totalement inutile ! Je l'ai mise en oeuvre en me disant que le préprocesseur ne ferait pas le calcul et remplaçerait le code par attr<T, 1 - 1> au lieu de attr<T, 0>...mais ça n'a aucune raison de gêner le compilo ! J'ai le cerveau qui tourne au ralenti...

  7. #7
    Membre averti
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Points : 392
    Points
    392
    Par défaut
    j'ai l'impression que ce que je veux générer pourrait se faire via BOOST_PP_ARRAY_DATA(a), mais je n'ai pas vraiment compris l'exmple. (Bon,il fait tard après une semaine lourde en boulot, donc...)

    edit: merci pour les idées, j'ai écrit un petit bout de code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    template<typename T>
    struct math
    {
    	class vec2;
    	class vec3;
    	class vec4;
    };
     
    template<typename T, int sizeT> 
    struct t_vec;
     
     
    template<typename T>struct t_vec<T, 2>{	T x; T y;	};
    template<typename T>struct t_vec<T, 3>{	T x; T y; T z;	};
    template<typename T>struct t_vec<T, 4>{	T x; T y; T z; T w;	};
     
    template<typename T, int sizeT> union tunion
    {
    	T a[sizeT];
    	t_vec<T, sizeT> v;
    };
     
    template<typename T>
    struct math<T>::vec2
    {
    	tunion<T, 2> u;
    };
     
    template<typename T>
    struct math<T>::vec3
    {
    	tunion<T, 3> u;
    };
     
    template<typename T>
    struct math<T>::vec4
    {
    	tunion<T, 4> u;
    };
    pour l'instance du tout:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    math<float>::vec2 fv2;
    	fv2.u.v.x = 1.0f;
    	fv2.u.v.y = 2.0f;
    le poblème, c'est que ce u.v.x ... c'est un peu lourdingue. Il y a mieux, je suppose. Des idées?

  8. #8
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 861
    Points
    11 861
    Par défaut
    Citation Envoyé par Kurisu Voir le message
    j'ai l'impression que ce que je veux générer pourrait se faire via BOOST_PP_ARRAY_DATA(a), mais je n'ai pas vraiment compris l'exmple. (Bon,il fait tard après une semaine lourde en boulot, donc...)
    C'est sur cette piste là que je voulais te mettre, effectivement
    Boost.PP te permettra de faire ce que tu souhaites aussi. Mais la technique donnée plus tôt est très bonne aussi.

  9. #9
    Membre averti
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Points : 392
    Points
    392
    Par défaut
    En regardant un peu la doc, je suis arrivé à un truc comme le suivant...
    je testerai ca plus tard en tout cas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #define VNAME (x, y, z, w)
    #define CNAME (r, g, b, a)
    #define NNAME (_0, _1, _2, _3)
     
    template<typename T, int sizeT>
    union UU
    {
    	T a[sizeT];	
    	struct{ T BOOST_PP_ARRAY_DATA(sizeT, VNAME); };
    	struct{ T BOOST_PP_ARRAY_DATA(sizeT, CNAME); };
    	struct{ T BOOST_PP_ARRAY_DATA(sizeT, NNAME); };
    };
    Est-ce la bonne direction?

  10. #10
    Membre averti
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Points : 392
    Points
    392
    Par défaut
    en fait, en regardant ca de plus de près, c'est le chemin inverse, c'est-à-dire, générer la concretisation du template avec le preprocesseur. C'est vicieux et pervers, mais ca me plaît comme direction.
    Update demain, une fois que j'aurais testé un peu mon idée.

  11. #11
    Membre averti
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Points : 392
    Points
    392
    Par défaut
    Bon, actuellement, j'ai écrit un petit bout de code qui ressemble plus à de la magie noire qu'à du C++. J'ai pas encore compilé (car pas de boost sur Wii et la flemme de l'installer pour VC2005 (je suis au boulot)), mais voici le code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    #include <boost/preprocessor/arithmetic/inc.hpp>
    #include <boost/preprocessor/comparison/not_equal.hpp>
    #include <boost/preprocessor/repetition/for.hpp>
    #include <boost/preprocessor/tuple/elem.hpp>
     
     
     
    namespace kazu
    {
    	template<typename typeT> 
    	typedef typeT scalar;
    	struct blast
    	{
    		class vec2;
    		class vec3;
    		class vec4;
    	};
    } //namespace kazu
     
    template<typename typeT, int sizeT>
    struct vec_struct;
     
    #define	STRUCT_SIZE_ASSERT(x)	BOOST_STATIC_ASSERT(1 < x && x <= 4)
    #define	VEC_POSITION_ARRAY		(x, y, z, w)
    #define VEC_NUM_ARRAY			(_0, _1, _2, _3)
    #define	VEC_TEXCOORD_ARRAY		(s, t, u, v)
    #define	VEC_COLOR_ARRAY4		(r, g, b, a)
    #define VEC_COLOR_ARRAY2		(i, a)
     
    #define	GEN_SIMPLE_VEC_ELEM(index, array)				\
    		BOOST_PP_ARRAY_ELEM(index, array)				\
     
    #define	GEN_COLOR_VEC_ELEM()
     
     
    #define FOR_END_PREDICATE(r, state)							\
    		BOOST_PP_NOT_EQUAL(									\
    			BOOST_PP_TUPLE_ELEM(2, 0, state),				\
    			BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(2, 1, state))	\
    		)													\
     
     
    #define FOR_INCREMENT_OP(r, state)							\
    		(													\
    			BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(2, 0, state)),	\
    			BOOST_PP_TUPLE_ELEM(2, 1, state) 				\
    		)													\
     
     
    #define	FOR_GEN_SIMPLE_MACRO(r, state)						\
    		GEN_SIMPLE_VEC_ELEM(								\
    			BOOST_PP_TUPLE_ELEM(2, 0, state),				\
    			array)											\
     
     
    #define	GEN_SIMLE_VEC(type, size, array)					\
    		BOOST_PP_FOR(										\
    			(0, size),										\
    			FOR_END_PREDICATE,								\
    			FOR_INCREMENT_OP,								\
    			FOR_GEN_SIMPLE_MACRO)							\
     
     
    #define	VEC_MEMBER_TPL_GEN(size)												\
    		template<typename typeT>												\
    		struct vec_struct<typeT, size>		{									\		
    			STRUCT_SIZE_ASSERT(size);											\
    			union		{														\			
    				typeT	_a[size];												\
    				struct	{	GEN_SIMPLE_VEC(typeT, size, VEC_POSITION_ARRAY)	};	\
    				struct	{	GEN_SIMPLE_VEC(typeT, size, VEC_NUM_ARRAY)		};	\
    				struct	{	GEN_SIMPLE_VEC(typeT, size, VEC_TEXCOORD_ARRAY)	};	\
    //				struct	{	GEN_COLOR_VEC(typeT, size, VEC_COLOR_ARRAY)		};	\
    			};																	\				
    		}																		\
    			
    VEC_MEMBER_TPL_GEN(2);
    VEC_MEMBER_TPL_GEN(3);
    VEC_MEMBER_TPL_GEN(4);
    VEC_MEMBER_TPL_GEN(1);	//error
    VEC_MEMBER_TPL_GEN(5);	//error
     
    #define	VEC_STRUCT_CONCRETE(type, size)						\
    		class kazu::blast<type>::vec##size		:			\
    		public vec_struct<kazu::blast<type>::scalar, size>
     
    template<typename typeT>
    VEC_STRUCT_CONCRETE(typeT, 2)
    {
    };
     
    template<typename typeT>
    VEC_STRUCT_CONCRETE(typeT, 3)
    {
    };
     
    template<typename typeT>
    VEC_STRUCT_CONCRETE(typeT, 4)
    {
    };

    Est-ce qu'il y a un petit tool qui permet de voir le code que le préprocesseur me génère, histoire de pouvoir debugger.

    Puis, j'ai pas vraiment compris à quoi sert le "r" dans le FOR: cf.: http://www.boost.org/doc/libs/1_35_0...c/ref/for.html

  12. #12
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Est-ce qu'il y a un petit tool qui permet de voir le code que le préprocesseur me génère, histoire de pouvoir debugger.
    option -E de g++
    Mais attention, ca va aussi t'afficher les includes, ce qui fait au final pas mal de texte.

  13. #13
    Membre averti
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Points : 392
    Points
    392
    Par défaut
    Citation Envoyé par Davidbrcz Voir le message
    option -E de g++
    Mais attention, ca va aussi t'afficher les includes, ce qui fait au final pas mal de texte.
    merci, j'avais déjà trouvé ca sur le web 10 minutes avant ta réponse.
    D'ailleurs XCode propose directement l'option "Preprocess".
    Avec MSVC, ce sont les paramètres /E, /P ou /EP (et /C pour laisser les commentaires) qui perment de l'obtenir. /P va générer le fameux fichier .i du preprocesseur.


    Actuellement, je suis en train de debugger le code prepro en suivant les exemples:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #define PRED(r, state) \
    	BOOST_PP_NOT_EQUAL( \
    	BOOST_PP_TUPLE_ELEM(2, 0, state), \
    	BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(2, 1, state)) \
    	) \
    	/**/
     
    #define OP(r, state) \
    	( \
    	BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(2, 0, state)), \
    	BOOST_PP_TUPLE_ELEM(2, 1, state) \
    	) \
    	/**/
     
    #define MACRO(r, state) BOOST_PP_TUPLE_ELEM(2, 0, state)
     
    #define STRING #BOOST_PP_FOR((5, 10), PRED, OP, MACRO) // expands to 5 6 7 8 9 10
     
    void test_orig()
    {
    	std::cout << STRING << std::endl;
    }
     
    #define TEST_ARRAY (10, (a, b, c, d, e, f, g, h, i, j))
     
    #define MACRO_ARRAY(r, state)	BOOST_PP_ARRAY_ELEM( BOOST_PP_TUPLE_ELEM(2, 0, state), TEST_ARRAY)
    BOOST_PP_FOR((0, 6), PRED, OP, MACRO_ARRAY) //expands to a b c d e f

  14. #14
    Membre averti
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Points : 392
    Points
    392
    Par défaut
    ca avance, ca avance

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    #define	STRUCT_SIZE_ASSERT(x)	BOOST_STATIC_ASSERT(1 < x && x <= 4)
    #define	VEC_POSITION_ARRAY		(4, (x, y, z, w))
    #define VEC_NUM_ARRAY			(4, (_0, _1, _2, _3))
    #define	VEC_TEXCOORD_ARRAY		(4, (s, t, u, v))
    #define	VEC_COLOR_ARRAY4		(4, (r, g, b, a))
    #define VEC_COLOR_ARRAY2		(2, (i, a))
     
    #define	GEN_STRUCT_REP_MACRO(z, n, param)						\
    	BOOST_PP_TUPLE_ELEM(2, 0, param)							\
    	BOOST_PP_ARRAY_ELEM(n, BOOST_PP_TUPLE_ELEM(2, 1, param));	\
    //resolves to type array(n);
     
    #define GEN_STRUCT(type, size, array)					\
    		struct {										\
    			BOOST_PP_REPEAT_FROM_TO(					\
    				0,										\
    				size,									\
    				GEN_STRUCT_REP_MACRO,					\
    				(type, array)							\
    			)											\
    		}												\
     
    //resolves to struct { type array(0); ... };
     
    GEN_STRUCT(float, 3, VEC_POSITION_ARRAY);	//resolves to struct { float x; float y; float z; };
    le code final plus tard.

  15. #15
    Membre averti
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Points : 392
    Points
    392
    Par défaut
    ca y est, fini.
    merci encore à Alp pour m'avoir mis sur la voie de Boost.Preprocessor (et de m'avoir mis la puce à l'oreille).

    le code (avec un peu de chance, les \\ se feront pas bouffer):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    //!     \file   boostpp_test.cpp
    //!     @brief  testing boost pp
     
    #include <boost/static_assert.hpp>
    #include <boost/preprocessor/arithmetic/inc.hpp>
    #include <boost/preprocessor/comparison/not_equal.hpp>
    #include <boost/preprocessor/repetition/for.hpp>
    #include <boost/preprocessor/tuple/elem.hpp>
    #include <boost/preprocessor/array/elem.hpp>
    #include <boost/preprocessor/array/size.hpp>
    #include <boost/preprocessor/cat.hpp>
    #include <boost/preprocessor/repetition/repeat_from_to.hpp>
    #include <boost/preprocessor/control/iif.hpp>
    #include <boost/preprocessor/comparison/equal.hpp>
     
     
    namespace kazu
    {
    	template<typename typeT> 
    	struct blast
    	{
    		typedef typeT scalar;
     
    		class vec2;
    		class vec3;
    		class vec4;
    	};
    } //namespace kazu
     
    template<typename typeT, int sizeT>
    struct vec_struct;
     
    //---------------------------------------------------------------------------
     
    #define	STRUCT_SIZE_ASSERT(x)	BOOST_STATIC_ASSERT(1 < x && x <= 4)
    #define	VEC_POSITION_ARRAY		(4, (x, y, z, w))
    #define VEC_NUM_ARRAY			(4, (_0, _1, _2, _3))
    #define	VEC_TEXCOORD_ARRAY		(4, (s, t, u, v))
    #define	VEC_COLOR_ARRAY4		(4, (r, g, b, a))
    #define VEC_COLOR_ARRAY2		(2, (i, a))
     
    #define ELEMENT_ARRAYS			(3, (VEC_POSITION_ARRAY, VEC_NUM_ARRAY, VEC_TEXCOORD_ARRAY))
    #define COLOR_ARRAYS			(VEC_COLOR_ARRAY2, VEC_COLOR_ARRAY4)
     
    //---------------------------------------------------------------------------
     
     
    #define	GEN_STRUCT_REP_MACRO(z, n, param)						\
    	BOOST_PP_TUPLE_ELEM(2, 0, param)							\
    	BOOST_PP_ARRAY_ELEM(n, BOOST_PP_TUPLE_ELEM(2, 1, param));	\
    //resolves to type array(n);
     
    #define GEN_STRUCT(type, size, array)	\
    		struct {						\
    			BOOST_PP_REPEAT_FROM_TO(	\
    				0,						\
    				size,					\
    				GEN_STRUCT_REP_MACRO,	\
    				(type, array)			\
    			)							\
    		}								\
    //resolves to struct { type array(0); ... };
     
    GEN_STRUCT(float, 3, VEC_POSITION_ARRAY);	//resolves to struct { float x; float y; float z; };
     
    //---------------------------------------------------------------------------
     
    #define GEN_COLOR_STRUCT(type, size, colors)		\
    		BOOST_PP_IIF(								\
    			BOOST_PP_EQUAL(size, 2),				\
    			GEN_STRUCT(type, size,					\
    				BOOST_PP_TUPLE_ELEM(2, 0, colors)),	\
    			GEN_STRUCT(type, size,					\
    				BOOST_PP_TUPLE_ELEM(2, 1, colors))	\
    		)											\
     
    //--------------------------------------
     
    #define GEN_UNION_REP_MACRO(z, n, param)			\
    		GEN_STRUCT(									\
    			BOOST_PP_TUPLE_ELEM(3, 0, param),		\
    			BOOST_PP_TUPLE_ELEM(3, 1, param),		\
    			BOOST_PP_ARRAY_ELEM(n,					\
    				BOOST_PP_TUPLE_ELEM(3, 2, param)	\
    			)										\
    		);											\
     
    #define GEN_UNION(type, size, arrays, colors)		\
    		union {										\
    			type	_a[size];						\
    			BOOST_PP_REPEAT_FROM_TO(				\
    				0,									\
    				BOOST_PP_ARRAY_SIZE(arrays),		\
    				GEN_UNION_REP_MACRO,				\
    				(type, size, arrays)				\
    			)										\
    			GEN_COLOR_STRUCT(type, size, colors);	\
    		}											\
     
    GEN_UNION(float, 3, ELEMENT_ARRAYS, COLOR_ARRAYS);
    GEN_UNION(float, 2, ELEMENT_ARRAYS, COLOR_ARRAYS);
     
    //---------------------------------------------------------------------------
     
    #define GEN_TPL_STRUCT(type, name, size, arrays, colors)	\
    		struct	name<type, size> {							\
    			GEN_UNION(type, size, arrays, colors);			\
    		}													\
     
    //---------------------------------------------------------------------------
     
    template<typename typeT>
    GEN_TPL_STRUCT(typeT, vec_struct, 2, ELEMENT_ARRAYS, COLOR_ARRAYS);
     
    template<typename typeT>
    GEN_TPL_STRUCT(typeT, vec_struct, 3, ELEMENT_ARRAYS, COLOR_ARRAYS);
     
    template<typename typeT>
    GEN_TPL_STRUCT(typeT, vec_struct, 4, ELEMENT_ARRAYS, COLOR_ARRAYS);
     
    //---------------------------------------------------------------------------
     
    #define GEN_TPL_CONCRETE_STRUCT(type, name, size, tpl)	\
    		struct name##size : public tpl<type, size>		\
     
    template<typename typeT>
    GEN_TPL_CONCRETE_STRUCT(kazu::blast<typeT>::scalar, kazu::blast<typeT>::vec, 2, vec_struct)
    {
    };
     
    template<typename typeT>
    GEN_TPL_CONCRETE_STRUCT(kazu::blast<typeT>::scalar, kazu::blast<typeT>::vec, 3, vec_struct)
    {
    };
     
    template<typename typeT>
    GEN_TPL_CONCRETE_STRUCT(kazu::blast<typeT>::scalar, kazu::blast<typeT>::vec, 4, vec_struct)
    {
    };
     
    //---------------------------------------------------------------------------
     
    static void test_it()
    {
    	kazu::blast<float>::vec2 fv2;
    	fv2.x = 0.0f;
    	fv2.y = 1.0f;	
    }
     
    //---------------------------------------------------------------------------

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. fonction membre depuis fonction anonyme
    Par PoZZyX dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 09/06/2010, 17h30
  2. Appel de fonction problème class/template
    Par Niko_de_bordo dans le forum Langage
    Réponses: 3
    Dernier message: 15/04/2010, 00h48
  3. [2K8] Membres Calculés - Fonction AVG
    Par Mourad69 dans le forum SSAS
    Réponses: 1
    Dernier message: 18/08/2009, 11h13
  4. Réponses: 0
    Dernier message: 25/07/2007, 14h47
  5. Réponses: 11
    Dernier message: 18/02/2007, 15h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo