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;
}

posted on 2011-02-17 14:09  cutepig  阅读(1486)  评论(0编辑  收藏  举报

导航