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
|
#ifndef TUPLE
#define TUPLE
#include <tuple>
#include <memory>
namespace odfaeg {
namespace helper {
template <int...> struct seq {};
template<int N, int ...S> struct gens : gens<N-1, N-1, S...> {
};
template<int ...S> struct gens<0, S...>{
typedef seq<S...> type;
};
}
template <size_t I, typename L, typename T>
struct Element {
T type;
};
template <size_t I, typename L, template <std::size_t I, typename L, typename T> class E, typename T, class = std::allocator<T>>
struct TypelistElement : public Element<I, L, T> {
};
template <typename L>
class TypeList {
template <size_t I, typename T>
using ElementType = typename TypelistElement<I, L, Element, T>::type;
TypeList () {
nbTypes = 0;
}
template <typename A>
void add_type (A type) {
static ElementType<nbTypes, A> elementtype = type;
nbTypes++;
}
int getSize() {
return nbTypes;
}
int nbTypes;
};
namespace details {
template <typename L, int I=0, bool B=true>
struct get_type {
};
template <typename L, int I>
struct get_type <L, I, true> {
template <size_t N>
using ElementType = typename TypelistElement<N, L, Element>::type;
static typename ElementType<I> (L list, int n) {
if (n == 0)
return std::tuple_element<I, L>::type;
constexpr bool isGreater = (I+1 > list.nbTypes) ? true : false;
return get_type<L, I+1, isGreater>::get_type(list, n);
}
};
template <typename L, int I>
struct get_type <L, I, false> {
template <size_t I, typename L, template <std::size_t I, typename L, typename T> class E, typename T>
using elementtype = typename TypelistElement<I, L, template <std::size_t I, typename L, typename T> class E, typename T>::type;
static typename elementtype (L list, int n) {
assert(false);
}
};
template <typename L,int I=0, bool=true>
struct typelist {
};
template <typename L, int I>
struct typelist<L, I, true> {
template <typename T>
static bool exists (L list, T type) {
if (std::is_same<T, decltype(get_type<L, 0, true>::element(list, I))>::value)
return true;
constexpr bool isGreater = (I+1 > list.nbTypes) ? true : false;
return typelist<L, I+1, isGreater>::exists(list, type);
}
};
template <typename L, int I>
struct typelist<L, I, false> {
template <typename T>
static bool exists (L list, T type) {
return false;
}
};
template <typename L, int I=0,bool B=true>
struct get_index {
};
template <typename L, int I>
struct get_index <L, I, true> {
template <typename T>
static int element (L list, T type) {
if (std::is_same<T, decltype(get_type<L, 0, true>::element(list, I))>::value) {
return I;
}
constexpr bool isGreater = (I+1 > list.nbTypes) ? true : false;
get_index <L, I+1, isGreater>::element(list, type);
}
};
template <typename L, int I>
struct get_index <L, I, false> {
template <typename T>
static int element (L list, T type) {
assert(false);
}
};
}
}
#endif // TUPLE |
Partager