Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Partial implementation of the TypeList functionality from Modern C++ Design
#include <cstdio>
#include <limits>
#include <iostream>
using namespace std;
class NullType {};
template<typename T, typename U>
class TypeList {
typedef T Head;
typedef U Tail;
};
#define Typelist_1(T1) TypeList<T1, NullType>
#define Typelist_2(T1, T2) TypeList<T1, Typelist_1(T2)>
#define Typelist_3(T1, T2, T3) TypeList<T1, Typelist_2(T2, T3)>
typedef Typelist_1(int) int_list;
typedef Typelist_3(char, unsigned char, signed char) chars;
template<typename T>
struct Length;
template<>
struct Length<NullType> {
enum { value = 0 };
};
template<typename T1, typename T2>
struct Length<TypeList<T1, T2> > {
enum { value = 1 + Length<T2>::value };
};
template<class TList, unsigned int index>
struct TypeAt;
template<class T1, class T2>
struct TypeAt<TypeList<T1, T2>, 0> {
typedef T1 result;
};
template<class T1, class T2, unsigned int index>
struct TypeAt<TypeList<T1, T2>, index> {
typedef typename TypeAt<T2, index - 1>::result result;
};
typedef Typelist_3(short, int, long long) ints;
template<class TList, unsigned int index, class Default>
struct TypeAtDefault;
template<unsigned int index, class Default>
struct TypeAtDefault<NullType, index, Default> {
typedef Default result;
};
template<class Head, class Tail, class Default>
struct TypeAtDefault<TypeList<Head, Tail>, 0, Default> {
typedef Head result;
};
template<class Head, class Tail, unsigned int index, class Default>
struct TypeAtDefault<TypeList<Head, Tail>, index, Default> {
typedef typename TypeAtDefault<Tail, index - 1, Default>::result result;
};
template<int Cond, int V1, int V2>
struct StaticIf {
enum { value = V1 };
};
template<int V1, int V2>
struct StaticIf<0, V1, V2> {
enum { value = V2 };
};
template<class TList, class Type>
struct IndexOf;
template<class Type>
struct IndexOf<NullType, Type> {
enum { value = -1 };
};
template<class Head, class Tail>
struct IndexOf<TypeList<Head, Tail>, Head> {
enum { value = 0 };
};
template<class Head, class Tail, class Type>
class IndexOf<TypeList<Head, Tail>, Type> {
enum { value_ = IndexOf<Tail, Type>::value };
public:
enum { value = StaticIf<value_ == -1, -1, IndexOf<Tail, Type>::value + 1>::value };
};
template<class TList, class Type>
struct Append;
template<class Type>
struct Append<NullType, Type> {
typedef Typelist_1(Type) result;
};
template<class Head, class Tail, class Type>
struct Append<TypeList<Head, Tail>, Type> {
typedef TypeList<Head, typename Append<Tail, Type>::result> result;
};
int main() {
cout << "max val is " << numeric_limits<TypeAtDefault<ints, 3, int>::result >::max() << "\n";
cout << "index is " << IndexOf<ints, char>::value << "\n";
typedef Append<ints, double>::result intsDouble;
cout << "max val is " << numeric_limits<TypeAtDefault<intsDouble, 3, int>::result >::max() << "\n";
cout << "index is " << IndexOf<intsDouble, double>::value << "\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment