Created
August 31, 2012 22:09
-
-
Save IvanVergiliev/3559833 to your computer and use it in GitHub Desktop.
Partial implementation of the TypeList functionality from Modern C++ Design
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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