Skip to content

Instantly share code, notes, and snippets.

@IvanVergiliev
Created August 31, 2012 22:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IvanVergiliev/3559833 to your computer and use it in GitHub Desktop.
Save IvanVergiliev/3559833 to your computer and use it in GitHub Desktop.
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