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
|
///////////////////////////////////////////////////////////////////
template<typename T, typename U> //
struct is_same : std::false_type { }; // Teste
// l'égalité de deux types
template<typename T> //
struct is_same<T, T> : std::true_type { }; //
//
template<typename T, typename U> //
constexpr bool eqTypes() { return is_same<T, U>::value; } //
///////////////////////////////////////////////////////////////////
//
template<class T> struct typeinfo { //Un type info rudimentaire...
typedef T type; //
static const T typic = T(); //
}; //
///////////////////////////////////////////////////////////////////
//
template<class... Arg> struct CountArg; //
// Compte les arguments du template
template<class T, class... Arg> struct CountArg<T,Arg...> //
{ //
static const int count = 1+CountArg<Arg...>::count; //
}; //
//
template<> struct CountArg<> //
{ //
static const int count = 0; //
}; //
///////////////////////////////////////////////////////////////////
//
template<class... Arg> struct type_vector; // Un vecteur de types
template<> struct type_vector<> {}; //
//
template<class T, class... Arg> struct type_vector { //
typedef T type; //
typedef type_vector<Arg...> next; //
typedef type_vector<T,Arg...> begin; //
typedef type_vector<> end; //
}; //
///////////////////////////////////////////////////////////////////
//
template<int n, class v> struct selector { // Selectionne le type situé à l'index n dans le vecteur v
typedef selector<n-1,v::next>::at at; //
typedef at::next next; //
typedef v::end end; //
typedef selector<n-1,v::next>::type type; //
}; //
template<class v> struct selector<0,v> { //
typedef v::begin at; //
typedef v::end end; //
typedef v::type type; //
typedef v::next next; //
}; //
///////////////////////////////////////////////////////////////////
template<int n, class v> struct slicer { // Découpe un vecteur en deux vecteurs à l'indice n
typedef struct { //
typedef v::type type; //
typedef v::begin begin; //
typedef v::next next; //
typedef selector<n,v>::at end; //
} first ; //
typedef struct { //
typedef selector<n,v>::type type; //
typedef selector<n,v>::at begin; //
typedef selector<n,v>::next next; //
typedef v::end end; //
} second ; //
}; //
////////////////////////////////////////////////////////////////////////////////////////////////////
//
template<int n, class... Arg> class Graph { //
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef slicer<n,typevector<Arg...>>::first NodeTypes ; // Vecteur de types de Valeurs //
typedef slicer<n,typevector<Arg...>>::second FlagTypes ; // Vecteur de types de Flags //
////////////////////////////////////////////////////////////////////////////////////////////////////
/* //
* Générateur de classe de base //
*/ //
//
//
template <class v, template<class> class I, bool f = eqTypes<v::begin,v::end>()> class base_gen : //
public base_gen< v::begin::next, I , eqTypes<v::begin::next, v::end>()>, I<v> {}; //
template<class v, template<class> class I> class base_gen<v,I,false> {}; //
////////////////////////////////////////////////////////////////////////////////////////////////////
/* Dispatche les fonctions virtuelles pour la future Node_ */ //
template<class v> class base_node_disp { //
public : //
virtual typename v::begin::type getVal(const typename v::begin::type & t) const {throw 1;} //
virtual void setVal(const typename v::begin::type & t) const {throw 1;} //
}; //
////////////////////////////////////////////////////////////////////////////////////////////////////
/* Dispatche les fonctions virtuelles pour la future Link_ */ //
template<class v> class base_link_disp { //
public : //
virtual typename v::begin::type getFlag(const typename v::begin::type & t) const {throw 1;} //
virtual void setFlag(const typename v::begin::type & t) const {throw 1;} //
}; //
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef base_gen<NodeTypes,base_node_disp> Node_;
typedef base_gen<FlagTypes,base_link_disp> Link_;
}; |
Partager