1 #ifndef TYPE_LISTS_H_
2 #define TYPE_LISTS_H_
3
4
5 #include <iostream>
6 #include <string>
7 #include "typetraits.h"
8
9 /*
10 TypeLists 內部沒有任何數值(value),他們的實體是空的,不含有任何狀態,也未定義任何函數。
11 執行期間TypeLists也不帶任何數值,他們存在的理由只是為了攜帶型別信息。TypeLists 并未打算被具
12 現化。因此,當我們說“a TypeListL”,實際指的是一個typelist型別,不是一個typelist 對象。
13 規定 typelist 必須以NullType(類)結尾,NullType可被視為一個結束符號,類似于c字符串的\0功能,
14 定義一個只有一個元素的typelist如下:
15 typedef Typelist<int,NullType> OneTypeOnly.
16 */
17 template<class T,class U>
18 struct Typelist
19 {
20 typedef T Head;
21 typedef U Tail;
22 };
23 //通過定義宏 將typelist線性化
24 #define TYPELIST_0() NullType
25 #define TYPELIST_1(T1) Typelist<T1,TYPELIST_0()>
26 #define TYPELIST_2(T1,T2) Typelist<T1,TYPELIST_1(T2)>
27 #define TYPELIST_3(T1,T2,T3) Typelist<T1,TYPELIST_2(T2,T3)>
28 #define TYPELIST_4(T1,T2,T3,T4) Typelist<T1,TYPELIST_3(T2,T3,T4)>
29 #define TYPELIST_5(T1,T2,T3,T4,T5) Typelist<T1,TYPELIST_4(T2,T3,T4,T5)>
30
31 //計算TypeList長度
32 //大多數Typelist的操作都是基于遞歸,遞歸終止條件通過模板特化實現。
33 template<class TList>struct Length;
34 template<>struct Length<NullType>//Length的全特化,即,只匹配NullType。
35 {
36 enum{value = 0};
37 };
38 template<class T,class U>
39 struct Length<Typelist<T,U> >//Length的扁特化,可匹配任何TypeList<T,U>類型,包括U同時也是Typelist的復合情況。
40 {
41 enum{value = 1+Length<U>::value};
42 };
43 //2 索引式訪問
44 template <class TList,unsigned int index> struct TypeAt;
45 template<class Head,class Tail>
46 struct TypeAt<Typelist<Head,Tail>,0>
47 {
48 typedef Head Result;
49 };
50 template<class Head,class Tail,unsigned int i>
51 struct TypeAt<Typelist<Head,Tail> ,i>
52 {
53 typedef typename TypeAt<Tail,i-1>::Result Result;
54 };
55
56 //類似TypeAt功能,不過TypeAtNonStrict對逾界訪問更加寬容。
57 //比如TypeList的個數是3,那么你不能使用TypeAt<TL3,3>::Result,這樣會編譯錯誤。
58 //但是TypeAtNonStrict<TL3,3,NullType>::Result可以,如果不存在索引為3的type,那么結果是第三個引數即NullType
59 template <class TList, unsigned int i, typename DefType = NullType>
60 struct TypeAtNonStrict
61 {
62 typedef DefType Result;
63 };
64 template <class T, class U, typename DefType>
65 struct TypeAtNonStrict< Typelist<T, U>, 0, DefType >
66 {
67 typedef T Result;
68 };
69 template <class T, class U, unsigned int i, typename DefType>
70 struct TypeAtNonStrict< Typelist<T, U>, i, DefType >
71 {
72 typedef typename TypeAtNonStrict<U, i - 1, DefType>::Result Result;
73 };
74
75 //3 查找TypeList
76 template<class TList,class T> struct IndexOf;//聲明
77 template<class T>
78 struct IndexOf<NullType,T>//如果TList為NullType,那么令value = -1;
79 {
80 enum{value = -1};
81 };
82 template<class Tail,class T>
83 struct IndexOf<Typelist<T,Tail> ,T>//如果T是TList中的頭端,那么令value= 0;
84 {
85 enum{value = 0};
86 };
87 template<class Head,class Tail,class T>//將IndexOf施于TList尾端和T,并將結果置于一個臨時變量temp
88 struct IndexOf<Typelist<Head,Tail> ,T>//如果temp為-1,令value為-1,否則令value為1+temp
89 {
90 private:
91 enum{temp = IndexOf<Tail,T>::value};//temp要先于value聲明定義。
92 public:
93 enum{value = temp == -1 ? -1 : temp + 1};
94 };
95
96 //4 附加元素到typelist
97 template <class Tlist,class T>struct Append;//聲明
98 template<>struct Append<NullType,NullType>//如果TList是NULL而且T是NULL,那么令Result為NullType
99 {
100 typedef NullType Result;
101 };
102 template <class T> struct Append<NullType,T> //如果TList是NullType,且T是type(非typelist),
103 { //那么Result將是"只含有唯一元素的T";
104 typedef TYPELIST_1(T) Result;
105 };
106 template <class Head,class Tail>
107 struct Append<NullType,Typelist<Head,Tail> >// 如果TList是NullType,且T是一個typelist,那么Result便是T本身
108 {
109 typedef Typelist<Head,Tail> Result;
110 };
111 template<class Head,class Tail,class T>//否則,如果Tlist是non-null,那么result將是個typelist,以TList::Head
112 struct Append<Typelist<Head,Tail>,T> //為起頭端,并以T附加到TList::Tail的結果為其尾端。
113 {
114 typedef Typelist<Head,typename Append<Tail,T>::Result> Result;
115 };
116
117 //5 Reverse
118 template <class TList> struct Reverse;
119 template <>struct Reverse<NullType>
120 {
121 typedef NullType Result;
122 };
123 template <class Head, class Tail>
124 struct Reverse< Typelist<Head, Tail> >
125 {
126 typedef typename Append<
127 typename Reverse<Tail>::Result, Head>::Result Result;
128 };
129
130
131 #endif
132 1 void typelists_test()
2 {
3 typedef TYPELIST_0() TL0;
4 typedef TYPELIST_3(char,int,double) TL3;
5 typedef TYPELIST_3(char,int,double) TL3_1;
6 //Length
7 std::cout<<Length<TL0>::value<<std::endl;
8 std::cout<<Length<TL3>::value<<std::endl;
9
10 //TypeAt
11 typedef TypeAt<TL3,0>::Result Parm1;
12 typedef TypeAt<TL3,1>::Result Parm2;
13 typedef TypeAt<TL3,2>::Result Parm3;
14
15 typedef TypeAtNonStrict<TL3,3,EmptyType>::Result TEST_TYPE;
16
17 std::cout<<"Parm1 Type:"<<typeid(Parm1).name() <<" sizeof : "<< sizeof(Parm1)<<std::endl;
18 std::cout<<"Parm2 Type:"<<typeid(Parm2).name() <<" sizeof : "<< sizeof(Parm2)<<std::endl;
19 std::cout<<"Parm3 Type:"<<typeid(Parm3).name() <<" sizeof : "<< sizeof(Parm3)<<std::endl;
20 std::cout<<"TEST_TYPE Type:"<<typeid(TEST_TYPE).name() <<" sizeof : "<< sizeof(TEST_TYPE)<<std::endl;
21
22 //IndexOf
23 std::cout<<"char indexof TL3 :"<<IndexOf<TL3,char>::value<<std::endl;
24 std::cout<<"int indexof TL3 :"<<IndexOf<TL3,int>::value<<std::endl;
25 std::cout<<"float indexof TL3 :"<<IndexOf<TL3,float>::value<<std::endl;
26
27 //Append
28 typedef Append<TL3,int> TL4;//TL4不是一個TypeList
29 typedef Append<TL3_1,TYPELIST_2(float,double)> TL5;
30 std::cout<<"TL4 Length :"<<Length<TL4::Result>::value<<std::endl;
31 std::cout<<"TL5 Length :"<<Length<TL5::Result>::value<<std::endl;
32
33 //Reverse
34 std::cout<<"Reverse result:"<<typeid(Reverse<TL3>::Result).name()<<std::endl;
35 }
轉載 http://blog.csdn.net/zhuyingqingfen/article/details/43938713
寫的非常詳細