C++: TypeList
#include <stdio.h>
#include <typeinfo.h>
//
// TypeList
//
template <class T, class U>
struct TypeList
{
typedef T Head;
typedef U Tail;
};
struct NullType
{
};
#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) >
//
// Length
//
template <class TList> struct Length;
template <> struct Length<NullType >
{
enum {value = 0};
};
template <class T,class U>
struct Length<TypeList<T,U> >
{
enum {value = 1 + Length<U>::value};
};
//
// TypeAt
//
template <class TList, unsigned int index> struct TypeAt;
template <class Head, class Tail> struct TypeAt< TypeList<Head,Tail>,0 >
{
typedef Head Result;
};
template <class Head, class Tail, unsigned int index> struct TypeAt< TypeList<Head,Tail>,index >
{
typedef typename TypeAt<Tail, index-1>::Result Result;
};
//
// IndexOf
//
template <class TList, class T> struct IndexOf;
template <class T> struct IndexOf< NullType, T >
{
enum {value = -1};
};
template <class T,class Tail> struct IndexOf< TypeList<T, Tail>, T >
{
enum {value = 0};
};
template <class Head,class Tail, class T> struct IndexOf< TypeList<Head, Tail>, T >
{
private:
enum { temp = IndexOf<Tail,T>::value };
public:
enum { value = temp==-1 ? -1 : 1 + temp};
};
//
// Append
//
template <class TList, class T> struct Append;
//
// push_front
//
template <class TList, class T> struct push_front
{
typedef TypeList<T, >
};
int main(int argc, char *argv[])
{
printf("Hello, world\n");
typedef TYPELIST_3(int, float,char) MyTypeList;
printf("MyTypeList length %d\n", Length<MyTypeList>::value);
printf("MyTypeList TypeAt 0 %s\n", typeid(TypeAt<MyTypeList,0>::Result).name());
printf("MyTypeList IndexOf<int> %d\n", IndexOf<MyTypeList, float>::value);
return 0;
}
#include <typeinfo.h>
//
// TypeList
//
template <class T, class U>
struct TypeList
{
typedef T Head;
typedef U Tail;
};
struct NullType
{
};
#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) >
//
// Length
//
template <class TList> struct Length;
template <> struct Length<NullType >
{
enum {value = 0};
};
template <class T,class U>
struct Length<TypeList<T,U> >
{
enum {value = 1 + Length<U>::value};
};
//
// TypeAt
//
template <class TList, unsigned int index> struct TypeAt;
template <class Head, class Tail> struct TypeAt< TypeList<Head,Tail>,0 >
{
typedef Head Result;
};
template <class Head, class Tail, unsigned int index> struct TypeAt< TypeList<Head,Tail>,index >
{
typedef typename TypeAt<Tail, index-1>::Result Result;
};
//
// IndexOf
//
template <class TList, class T> struct IndexOf;
template <class T> struct IndexOf< NullType, T >
{
enum {value = -1};
};
template <class T,class Tail> struct IndexOf< TypeList<T, Tail>, T >
{
enum {value = 0};
};
template <class Head,class Tail, class T> struct IndexOf< TypeList<Head, Tail>, T >
{
private:
enum { temp = IndexOf<Tail,T>::value };
public:
enum { value = temp==-1 ? -1 : 1 + temp};
};
//
// Append
//
template <class TList, class T> struct Append;
//
// push_front
//
template <class TList, class T> struct push_front
{
typedef TypeList<T, >
};
int main(int argc, char *argv[])
{
printf("Hello, world\n");
typedef TYPELIST_3(int, float,char) MyTypeList;
printf("MyTypeList length %d\n", Length<MyTypeList>::value);
printf("MyTypeList TypeAt 0 %s\n", typeid(TypeAt<MyTypeList,0>::Result).name());
printf("MyTypeList IndexOf<int> %d\n", IndexOf<MyTypeList, float>::value);
return 0;
}