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 151 152 153 154
|
/*Debut de la partie TMP*/
//Début de la définition des listes de types template
template<template<class> class...>
struct TTL;
template<class T>
class NullTT;
typedef TTL<NullTT> NullTTL;
//Fin
//Class de traits, à spécialiser, cf exemple
template<template<class> class>
struct conv_traits
{
//Par défaut pas de conversion
typedef NullTTL ImplicitTTL;
typedef NullTTL ExplicitTTL;
};
//Classe contenant les données de l'itérateur
//Séparation interface/donnée via une composition
template<class>
struct impl_iterator
{
/*fonctions communes nécessaires*/
~impl_iterator(){ /*code si besoin*/ }
};
//Classe de concepte pour les conversion
//s'intercalle entre les données et l'interface
template<class, class, class>
struct conv_concept;
//Spécialisations pour un parcourt TMP des 2 listes
//Cas de bases et cas de récurrences
template<class T>
struct conv_concept<T,NullTTL,NullTTL>
{
protected:
impl_iterator<T> m_impl;
~conv_concept(){}; //cf MC++D
public:
//constructeur de copie et opérateur d'assignation par défaut
conv_concept(const conv_concept&) =default;
conv_concept& operator=(const conv_concept&) =default;
//constructeur depuis l'implémentation
conv_concept(impl_iterator<T>& impl) : m_impl(impl) {}
};
template<class T, template<class> class Head, template<class> class... Tail, class U>
struct conv_concept<T,TTL<Head,Tail...>,U> : conv_concept<T,TTL<Tail...>,U>
{
private:
typedef conv_concept<T,TTL<Tail...>,U> base;
public:
//constructeur de copie et opérateur d'assignation par défaut
conv_concept(const conv_concept&) =default;
conv_concept& operator=(const conv_concept&) =default;
//constructeur depuis l'implémentation
conv_concept(impl_iterator<T>& impl) : base(impl) {}
operator Head<T>()
{ return Head<T>(this->m_impl); }
protected:
~conv_concept(){}; //cf MC++D
};
template<class T, template<class> class Head, template<class> class... Tail>
struct conv_concept<T,NullTTL,TTL<Head,Tail...>> : conv_concept<T,NullTTL,TTL<Tail...> >
{
private:
typedef conv_concept<T,NullTTL,TTL<Tail...> > base;
public:
//constructeur de copie et opérateur d'assignation par défaut
conv_concept(const conv_concept&) =default;
conv_concept& operator=(const conv_concept&) =default;
//constructeur depuis l'implémentation
conv_concept(impl_iterator<T>& impl) : base(impl) {}
explicit operator Head<T>()
{ return Head<T>(this->m_impl); }
protected:
~conv_concept(){}; //cf MC++D
};
//Define pour générer une classe d'itérateur
#define ITERATOR(name) template<class T> \
struct name : \
conv_concept<T, \
conv_traits<name>::ImplicitTTL, \
conv_traits<name>::ExplicitTTL> \
{ \
private: \
typedef conv_concept<T, \
conv_traits<name>::ImplicitTTL, \
conv_traits<name>::ExplicitTTL> base; \
\
public: \
name(const name&) =default; \
name& operator=(const name&) =default; \
name(impl_iterator<T>& impl) : base(impl) {} \
}; \
/*Fin de la partie TMP*/
//Déclarations anticipées des iétrateurs
//Je les fais pas toute
template<class> class normal_iterator;
template<class> class const_normal_iterator;
template<class> class lign_iterator;
template<class> class const_lign_iterator;
//spécialisations de la classe de trait pour les conversions
//
template<>
struct conv_traits<normal_iterator>
{
typedef TTL<const_normal_iterator,NullTT> ImplicitTTL;
typedef TTL<lign_iterator,const_lign_iterator,NullTT> ExplicitTTL;
};
template<>
struct conv_traits<const_normal_iterator>
{
typedef TTL<NullTT> ImplicitTTL;
typedef TTL<const_lign_iterator,NullTT> ExplicitTTL;
};
template<>
struct conv_traits<lign_iterator>
{
typedef TTL<normal_iterator,const_normal_iterator,NullTT> ImplicitTTL;
typedef TTL<NullTT> ExplicitTTL;
};
template<>
struct conv_traits<const_lign_iterator>
{
typedef TTL<const_normal_iterator,NullTT> ImplicitTTL;
typedef TTL<NullTT> ExplicitTTL;
};
ITERATOR(normal_iterator)
ITERATOR(const_normal_iterator)
ITERATOR(lign_iterator)
ITERATOR(const_lign_iterator) |
Partager