假设你有若干个类,现在你希望给每个类分配一个唯一的ID。最简单的方法无非是手工的为这个类添加一个id,前提是你确信给这个类的id与其它类的id没有冲突,为此你需要查看其它所有类的代码。
稍微好一点的办法是使用GUID产生器产生的GUID,这样就可以保证每个类的id都是唯一的了。但是GUID128位的长度似乎又有一些浪费。
其实还有这样的一个思路:我们到一个地方将这些类进行注册,注册的同时返回一个数值作为类的id。那么用什么作为这些类进行注册的容器呢?
Loki库中的TypeList就是一个理想的选择。TypeList就象一个普通的List,但是它里面“存储”的是一个一个的Type,而不是具体的数据(其实TypeList是借助模板元编程实现的,所以在编译之后,TypeList也就不存在了,因此“存储”二字需要加上引号)。
我们可以将所有的类都添加到TypeList中,然后使用IndexOf返回每个类在TypeList中的索引,从而达到取得唯一ID的目的。
下面给出Loki库中的Typelist.h的内容,供大家参考:
00001
00002 // The Loki Library
00003 // Copyright (c) 2001 by Andrei Alexandrescu
00004 // This code accompanies the book:
00005 // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
00006 // Patterns Applied". Copyright (c) 2001. Addison-Wesley.
00007 // Permission to use, copy, modify, distribute and sell this software for any
00008 // purpose is hereby granted without fee, provided that the above copyright
00009 // notice appear in all copies and that both that copyright notice and this
00010 // permission notice appear in supporting documentation.
00011 // The author or Addison-Welsey Longman make no representations about the
00012 // suitability of this software for any purpose. It is provided "as is"
00013 // without express or implied warranty.
00015
00016 // Last update: October 10, 2002
00017 //Reference
00018
00019 #ifndef TYPELIST_INC_
00020 #define TYPELIST_INC_
00021
00022 #include "NullType.h"
00023 #include "TypeManip.h"
00024
00026 // macros TYPELIST_1, TYPELIST_2, ... TYPELIST_50
00027 // Each takes a number of arguments equal to its numeric suffix
00028 // The arguments are type names. TYPELIST_NN generates a typelist containing
00029 // all types passed as arguments, in that order.
00030 // Example: TYPELIST_2(char, int) generates a type containing char and int.
00032
00033 #define TYPELIST_1(T1) ::Loki::Typelist<T1, ::Loki::NullType>
00034
00035 #define TYPELIST_2(T1, T2) ::Loki::Typelist<T1, TYPELIST_1(T2) >
00036
00037 #define TYPELIST_3(T1, T2, T3) ::Loki::Typelist<T1, TYPELIST_2(T2, T3) >
00038
00039 #define TYPELIST_4(T1, T2, T3, T4) \
00040 ::Loki::Typelist<T1, TYPELIST_3(T2, T3, T4) >
00041
00042 #define TYPELIST_5(T1, T2, T3, T4, T5) \
00043 ::Loki::Typelist<T1, TYPELIST_4(T2, T3, T4, T5) >
00044
00045 #define TYPELIST_6(T1, T2, T3, T4, T5, T6) \
00046 ::Loki::Typelist<T1, TYPELIST_5(T2, T3, T4, T5, T6) >
00047
00048 #define TYPELIST_7(T1, T2, T3, T4, T5, T6, T7) \
00049 ::Loki::Typelist<T1, TYPELIST_6(T2, T3, T4, T5, T6, T7) >
00050
00051 #define TYPELIST_8(T1, T2, T3, T4, T5, T6, T7, T8) \
00052 ::Loki::Typelist<T1, TYPELIST_7(T2, T3, T4, T5, T6, T7, T8) >
00053
00054 #define TYPELIST_9(T1, T2, T3, T4, T5, T6, T7, T8, T9) \
00055 ::Loki::Typelist<T1, TYPELIST_8(T2, T3, T4, T5, T6, T7, T8, T9) >
00056
00057 #define TYPELIST_10(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) \
00058 ::Loki::Typelist<T1, TYPELIST_9(T2, T3, T4, T5, T6, T7, T8, T9, T10) >
00059
00060 #define TYPELIST_11(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) \
00061 ::Loki::Typelist<T1, TYPELIST_10(T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) >
00062
00063 #define TYPELIST_12(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) \
00064 ::Loki::Typelist<T1, TYPELIST_11(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00065 T11, T12) >
00066
00067 #define TYPELIST_13(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) \
00068 ::Loki::Typelist<T1, TYPELIST_12(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00069 T11, T12, T13) >
00070
00071 #define TYPELIST_14(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00072 T11, T12, T13, T14) \
00073 ::Loki::Typelist<T1, TYPELIST_13(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00074 T11, T12, T13, T14) >
00075
00076 #define TYPELIST_15(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00077 T11, T12, T13, T14, T15) \
00078 ::Loki::Typelist<T1, TYPELIST_14(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00079 T11, T12, T13, T14, T15) >
00080
00081 #define TYPELIST_16(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00082 T11, T12, T13, T14, T15, T16) \
00083 ::Loki::Typelist<T1, TYPELIST_15(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00084 T11, T12, T13, T14, T15, T16) >
00085
00086 #define TYPELIST_17(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00087 T11, T12, T13, T14, T15, T16, T17) \
00088 ::Loki::Typelist<T1, TYPELIST_16(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00089 T11, T12, T13, T14, T15, T16, T17) >
00090
00091 #define TYPELIST_18(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00092 T11, T12, T13, T14, T15, T16, T17, T18) \
00093 ::Loki::Typelist<T1, TYPELIST_17(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00094 T11, T12, T13, T14, T15, T16, T17, T18) >
00095
00096 #define TYPELIST_19(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00097 T11, T12, T13, T14, T15, T16, T17, T18, T19) \
00098 ::Loki::Typelist<T1, TYPELIST_18(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00099 T11, T12, T13, T14, T15, T16, T17, T18, T19) >
00100
00101 #define TYPELIST_20(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00102 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) \
00103 ::Loki::Typelist<T1, TYPELIST_19(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00104 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) >
00105
00106 #define TYPELIST_21(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00107 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) \
00108 ::Loki::Typelist<T1, TYPELIST_20(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00109 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) >
00110
00111 #define TYPELIST_22(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00112 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) \
00113 ::Loki::Typelist<T1, TYPELIST_21(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00114 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) >
00115
00116 #define TYPELIST_23(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00117 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23) \
00118 ::Loki::Typelist<T1, TYPELIST_22(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00119 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23) >
00120
00121 #define TYPELIST_24(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00122 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24) \
00123 ::Loki::Typelist<T1, TYPELIST_23(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00124 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24) >
00125
00126 #define TYPELIST_25(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00127 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25) \
00128 ::Loki::Typelist<T1, TYPELIST_24(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00129 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00130 T21, T22, T23, T24, T25) >
00131
00132 #define TYPELIST_26(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00133 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00134 T21, T22, T23, T24, T25, T26) \
00135 ::Loki::Typelist<T1, TYPELIST_25(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00136 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00137 T21, T22, T23, T24, T25, T26) >
00138
00139 #define TYPELIST_27(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00140 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00141 T21, T22, T23, T24, T25, T26, T27) \
00142 ::Loki::Typelist<T1, TYPELIST_26(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00143 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00144 T21, T22, T23, T24, T25, T26, T27) >
00145
00146 #define TYPELIST_28(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00147 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00148 T21, T22, T23, T24, T25, T26, T27, T28) \
00149 ::Loki::Typelist<T1, TYPELIST_27(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00150 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00151 T21, T22, T23, T24, T25, T26, T27, T28) >
00152
00153 #define TYPELIST_29(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00154 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00155 T21, T22, T23, T24, T25, T26, T27, T28, T29) \
00156 ::Loki::Typelist<T1, TYPELIST_28(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00157 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00158 T21, T22, T23, T24, T25, T26, T27, T28, T29) >
00159
00160 #define TYPELIST_30(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00161 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00162 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30) \
00163 ::Loki::Typelist<T1, TYPELIST_29(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00164 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00165 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30) >
00166
00167 #define TYPELIST_31(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00168 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00169 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31) \
00170 ::Loki::Typelist<T1, TYPELIST_30(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00171 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00172 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31) >
00173
00174 #define TYPELIST_32(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00175 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00176 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32) \
00177 ::Loki::Typelist<T1, TYPELIST_31(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00178 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00179 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32) >
00180
00181 #define TYPELIST_33(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00182 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00183 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33) \
00184 ::Loki::Typelist<T1, TYPELIST_32(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00185 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00186 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33) >
00187
00188 #define TYPELIST_34(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00189 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00190 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33, T34) \
00191 ::Loki::Typelist<T1, TYPELIST_33(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00192 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00193 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33, T34) >
00194
00195 #define TYPELIST_35(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00196 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00197 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00198 T31, T32, T33, T34, T35) \
00199 ::Loki::Typelist<T1, TYPELIST_34(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00200 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00201 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00202 T31, T32, T33, T34, T35) >
00203
00204 #define TYPELIST_36(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00205 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00206 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00207 T31, T32, T33, T34, T35, T36) \
00208 ::Loki::Typelist<T1, TYPELIST_35(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00209 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00210 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00211 T31, T32, T33, T34, T35, T36) >
00212
00213 #define TYPELIST_37(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00214 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00215 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00216 T31, T32, T33, T34, T35, T36, T37) \
00217 ::Loki::Typelist<T1, TYPELIST_36(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00218 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00219 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00220 T31, T32, T33, T34, T35, T36, T37) >
00221
00222 #define TYPELIST_38(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00223 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00224 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00225 T31, T32, T33, T34, T35, T36, T37, T38) \
00226 ::Loki::Typelist<T1, TYPELIST_37(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00227 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00228 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00229 T31, T32, T33, T34, T35, T36, T37, T38) >
00230
00231 #define TYPELIST_39(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00232 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00233 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00234 T31, T32, T33, T34, T35, T36, T37, T38, T39) \
00235 ::Loki::Typelist<T1, TYPELIST_38(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00236 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00237 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00238 T31, T32, T33, T34, T35, T36, T37, T38, T39) >
00239
00240 #define TYPELIST_40(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00241 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00242 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00243 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40) \
00244 ::Loki::Typelist<T1, TYPELIST_39(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00245 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00246 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00247 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40) >
00248
00249 #define TYPELIST_41(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00250 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00251 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00252 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41) \
00253 ::Loki::Typelist<T1, TYPELIST_40(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00254 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00255 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00256 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41) >
00257
00258 #define TYPELIST_42(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00259 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00260 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00261 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42) \
00262 ::Loki::Typelist<T1, TYPELIST_41(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00263 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00264 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00265 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42) >
00266
00267 #define TYPELIST_43(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00268 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00269 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00270 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43) \
00271 ::Loki::Typelist<T1, TYPELIST_42(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00272 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00273 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00274 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43) >
00275
00276 #define TYPELIST_44(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00277 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00278 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00279 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44) \
00280 ::Loki::Typelist<T1, TYPELIST_43(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00281 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00282 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00283 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44) >
00284
00285 #define TYPELIST_45(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00286 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00287 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00288 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
00289 T41, T42, T43, T44, T45) \
00290 ::Loki::Typelist<T1, TYPELIST_44(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00291 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00292 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00293 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
00294 T41, T42, T43, T44, T45) >
00295
00296 #define TYPELIST_46(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00297 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00298 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00299 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
00300 T41, T42, T43, T44, T45, T46) \
00301 ::Loki::Typelist<T1, TYPELIST_45(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00302 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00303 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00304 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
00305 T41, T42, T43, T44, T45, T46) >
00306
00307 #define TYPELIST_47(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00308 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00309 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00310 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
00311 T41, T42, T43, T44, T45, T46, T47) \
00312 ::Loki::Typelist<T1, TYPELIST_46(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00313 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00314 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00315 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
00316 T41, T42, T43, T44, T45, T46, T47) >
00317
00318 #define TYPELIST_48(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00319 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00320 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00321 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
00322 T41, T42, T43, T44, T45, T46, T47, T48) \
00323 ::Loki::Typelist<T1, TYPELIST_47(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00324 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00325 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00326 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
00327 T41, T42, T43, T44, T45, T46, T47, T48) >
00328
00329 #define TYPELIST_49(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00330 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00331 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00332 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
00333 T41, T42, T43, T44, T45, T46, T47, T48, T49) \
00334 ::Loki::Typelist<T1, TYPELIST_48(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00335 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00336 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00337 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
00338 T41, T42, T43, T44, T45, T46, T47, T48, T49) >
00339
00340 #define TYPELIST_50(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00341 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00342 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00343 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
00344 T41, T42, T43, T44, T45, T46, T47, T48, T49, T50) \
00345 ::Loki::Typelist<T1, TYPELIST_49(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
00346 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
00347 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
00348 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
00349 T41, T42, T43, T44, T45, T46, T47, T48, T49, T50) >
00350
00351 namespace Loki
00352 {
00354 // class template Typelist
00355 // The building block of typelists of any length
00356 // Use it through the TYPELIST_NN macros
00357 // Defines nested types:
00358 // Head (first element, a non-typelist type by convention)
00359 // Tail (second element, can be another typelist)
00361
00362 template <class T, class U>
00363 struct Typelist
00364 {
00365 typedef T Head;
00366 typedef U Tail;
00367 };
00368
00369 // Typelist utility algorithms
00370
00371 namespace TL
00372 {
00373
00375 // class template MakeTypelist
00376 // Takes a number of arguments equal to its numeric suffix
00377 // The arguments are type names.
00378 // MakeTypelist<T1, T2, ...>::Result
00379 // returns a typelist that is of T1, T2, ...
00381
00382 template
00383 <
00384 typename T1 = NullType, typename T2 = NullType, typename T3 = NullType,
00385 typename T4 = NullType, typename T5 = NullType, typename T6 = NullType,
00386 typename T7 = NullType, typename T8 = NullType, typename T9 = NullType,
00387 typename T10 = NullType, typename T11 = NullType, typename T12 = NullType,
00388 typename T13 = NullType, typename T14 = NullType, typename T15 = NullType,
00389 typename T16 = NullType, typename T17 = NullType, typename T18 = NullType
00390 >
00391 struct MakeTypelist
00392 {
00393 private:
00394 typedef typename MakeTypelist
00395 <
00396 T2 , T3 , T4 ,
00397 T5 , T6 , T7 ,
00398 T8 , T9 , T10,
00399 T11, T12, T13,
00400 T14, T15, T16,
00401 T17, T18
00402 >
00403 ::Result TailResult;
00404
00405 public:
00406 typedef Typelist<T1, TailResult> Result;
00407 };
00408
00409 template<>
00410 struct MakeTypelist<>
00411 {
00412 typedef NullType Result;
00413 };
00414
00416 // class template Length
00417 // Computes the length of a typelist
00418 // Invocation (TList is a typelist):
00419 // Length<TList>::value
00420 // returns a compile-time constant containing the length of TList, not counting
00421 // the end terminator (which by convention is NullType)
00423
00424 template <class TList> struct Length;
00425 template <> struct Length<NullType>
00426 {
00427 enum { value = 0 };
00428 };
00429
00430 template <class T, class U>
00431 struct Length< Typelist<T, U> >
00432 {
00433 enum { value = 1 + Length<U>::value };
00434 };
00435
00437 // class template TypeAt
00438 // Finds the type at a given index in a typelist
00439 // Invocation (TList is a typelist and index is a compile-time integral
00440 // constant):
00441 // TypeAt<TList, index>::Result
00442 // returns the type in position 'index' in TList
00443 // If you pass an out-of-bounds index, the result is a compile-time error
00445
00446 template <class TList, unsigned int index> struct TypeAt;
00447
00448 template <class Head, class Tail>
00449 struct TypeAt<Typelist<Head, Tail>, 0>
00450 {
00451 typedef Head Result;
00452 };
00453
00454 template <class Head, class Tail, unsigned int i>
00455 struct TypeAt<Typelist<Head, Tail>, i>
00456 {
00457 typedef typename TypeAt<Tail, i - 1>::Result Result;
00458 };
00459
00461 // class template TypeAtNonStrict
00462 // Finds the type at a given index in a typelist
00463 // Invocations (TList is a typelist and index is a compile-time integral
00464 // constant):
00465 // a) TypeAt<TList, index>::Result
00466 // returns the type in position 'index' in TList, or NullType if index is
00467 // out-of-bounds
00468 // b) TypeAt<TList, index, D>::Result
00469 // returns the type in position 'index' in TList, or D if index is out-of-bounds
00471
00472 template <class TList, unsigned int index,
00473 typename DefaultType = NullType>
00474 struct TypeAtNonStrict
00475 {
00476 typedef DefaultType Result;
00477 };
00478
00479 template <class Head, class Tail, typename DefaultType>
00480 struct TypeAtNonStrict<Typelist<Head, Tail>, 0, DefaultType>
00481 {
00482 typedef Head Result;
00483 };
00484
00485 template <class Head, class Tail, unsigned int i, typename DefaultType>
00486 struct TypeAtNonStrict<Typelist<Head, Tail>, i, DefaultType>
00487 {
00488 typedef typename
00489 TypeAtNonStrict<Tail, i - 1, DefaultType>::Result Result;
00490 };
00491
00493 // class template IndexOf
00494 // Finds the index of a type in a typelist
00495 // Invocation (TList is a typelist and T is a type):
00496 // IndexOf<TList, T>::value
00497 // returns the position of T in TList, or NullType if T is not found in TList
00499
00500 template <class TList, class T> struct IndexOf;
00501
00502 template <class T>
00503 struct IndexOf<NullType, T>
00504 {
00505 enum { value = -1 };
00506 };
00507
00508 template <class T, class Tail>
00509 struct IndexOf<Typelist<T, Tail>, T>
00510 {
00511 enum { value = 0 };
00512 };
00513
00514 template <class Head, class Tail, class T>
00515 struct IndexOf<Typelist<Head, Tail>, T>
00516 {
00517 private:
00518 enum { temp = IndexOf<Tail, T>::value };
00519 public:
00520 enum { value = (temp == -1 ? -1 : 1 + temp) };
00521 };
00522
00524 // class template Append
00525 // Appends a type or a typelist to another
00526 // Invocation (TList is a typelist and T is either a type or a typelist):
00527 // Append<TList, T>::Result
00528 // returns a typelist that is TList followed by T and NullType-terminated
00530
00531 template <class TList, class T> struct Append;
00532
00533 template <> struct Append<NullType, NullType>
00534 {
00535 typedef NullType Result;
00536 };
00537
00538 template <class T> struct Append<NullType, T>
00539 {
00540 typedef TYPELIST_1(T) Result;
00541 };
00542
00543 template <class Head, class Tail>
00544 struct Append<NullType, Typelist<Head, Tail> >
00545 {
00546 typedef Typelist<Head, Tail> Result;
00547 };
00548
00549 template <class Head, class Tail, class T>
00550 struct Append<Typelist<Head, Tail>, T>
00551 {
00552 typedef Typelist<Head,
00553 typename Append<Tail, T>::Result>
00554 Result;
00555 };
00556
00558 // class template Erase
00559 // Erases the first occurence, if any, of a type in a typelist
00560 // Invocation (TList is a typelist and T is a type):
00561 // Erase<TList, T>::Result
00562 // returns a typelist that is TList without the first occurence of T
00564
00565 template <class TList, class T> struct Erase;
00566
00567 template <class T> // Specialization 1
00568 struct Erase<NullType, T>
00569 {
00570 typedef NullType Result;
00571 };
00572
00573 template <class T, class Tail> // Specialization 2
00574 struct Erase<Typelist<T, Tail>, T>
00575 {
00576 typedef Tail Result;
00577 };
00578
00579 template <class Head, class Tail, class T> // Specialization 3
00580 struct Erase<Typelist<Head, Tail>, T>
00581 {
00582 typedef Typelist<Head,
00583 typename Erase<Tail, T>::Result>
00584 Result;
00585 };
00586
00588 // class template EraseAll
00589 // Erases all first occurences, if any, of a type in a typelist
00590 // Invocation (TList is a typelist and T is a type):
00591 // EraseAll<TList, T>::Result
00592 // returns a typelist that is TList without any occurence of T
00594
00595 template <class TList, class T> struct EraseAll;
00596 template <class T>
00597 struct EraseAll<NullType, T>
00598 {
00599 typedef NullType Result;
00600 };
00601 template <class T, class Tail>
00602 struct EraseAll<Typelist<T, Tail>, T>
00603 {
00604 // Go all the way down the list removing the type
00605 typedef typename EraseAll<Tail, T>::Result Result;
00606 };
00607 template <class Head, class Tail, class T>
00608 struct EraseAll<Typelist<Head, Tail>, T>
00609 {
00610 // Go all the way down the list removing the type
00611 typedef Typelist<Head,
00612 typename EraseAll<Tail, T>::Result>
00613 Result;
00614 };
00615
00617 // class template NoDuplicates
00618 // Removes all duplicate types in a typelist
00619 // Invocation (TList is a typelist):
00620 // NoDuplicates<TList, T>::Result
00622
00623 template <class TList> struct NoDuplicates;
00624
00625 template <> struct NoDuplicates<NullType>
00626 {
00627 typedef NullType Result;
00628 };
00629
00630 template <class Head, class Tail>
00631 struct NoDuplicates< Typelist<Head, Tail> >
00632 {
00633 private:
00634 typedef typename NoDuplicates<Tail>::Result L1;
00635 typedef typename Erase<L1, Head>::Result L2;
00636 public:
00637 typedef Typelist<Head, L2> Result;
00638 };
00639
00641 // class template Replace
00642 // Replaces the first occurence of a type in a typelist, with another type
00643 // Invocation (TList is a typelist, T, U are types):
00644 // Replace<TList, T, U>::Result
00645 // returns a typelist in which the first occurence of T is replaced with U
00647
00648 template <class TList, class T, class U> struct Replace;
00649
00650 template <class T, class U>
00651 struct Replace<NullType, T, U>
00652 {
00653 typedef NullType Result;
00654 };
00655
00656 template <class T, class Tail, class U>
00657 struct Replace<Typelist<T, Tail>, T, U>
00658 {
00659 typedef Typelist<U, Tail> Result;
00660 };
00661
00662 template <class Head, class Tail, class T, class U>
00663 struct Replace<Typelist<Head, Tail>, T, U>
00664 {
00665 typedef Typelist<Head,
00666 typename Replace<Tail, T, U>::Result>
00667 Result;
00668 };
00669
00671 // class template ReplaceAll
00672 // Replaces all occurences of a type in a typelist, with another type
00673 // Invocation (TList is a typelist, T, U are types):
00674 // Replace<TList, T, U>::Result
00675 // returns a typelist in which all occurences of T is replaced with U
00677
00678 template <class TList, class T, class U> struct ReplaceAll;
00679
00680 template <class T, class U>
00681 struct ReplaceAll<NullType, T, U>
00682 {
00683 typedef NullType Result;
00684 };
00685
00686 template <class T, class Tail, class U>
00687 struct ReplaceAll<Typelist<T, Tail>, T, U>
00688 {
00689 typedef Typelist<U, typename ReplaceAll<Tail, T, U>::Result> Result;
00690 };
00691
00692 template <class Head, class Tail, class T, class U>
00693 struct ReplaceAll<Typelist<Head, Tail>, T, U>
00694 {
00695 typedef Typelist<Head,
00696 typename ReplaceAll<Tail, T, U>::Result>
00697 Result;
00698 };
00699
00701 // class template Reverse
00702 // Reverses a typelist
00703 // Invocation (TList is a typelist):
00704 // Reverse<TList>::Result
00705 // returns a typelist that is TList reversed
00707
00708 template <class TList> struct Reverse;
00709
00710 template <>
00711 struct Reverse<NullType>
00712 {
00713 typedef NullType Result;
00714 };
00715
00716 template <class Head, class Tail>
00717 struct Reverse< Typelist<Head, Tail> >
00718 {
00719 typedef typename Append<
00720 typename Reverse<Tail>::Result, Head>::Result Result;
00721 };
00722
00724 // class template MostDerived
00725 // Finds the type in a typelist that is the most derived from a given type
00726 // Invocation (TList is a typelist, T is a type):
00727 // MostDerived<TList, T>::Result
00728 // returns the type in TList that's the most derived from T
00730
00731 template <class TList, class T> struct MostDerived;
00732
00733 template <class T>
00734 struct MostDerived<NullType, T>
00735 {
00736 typedef T Result;
00737 };
00738
00739 template <class Head, class Tail, class T>
00740 struct MostDerived<Typelist<Head, Tail>, T>
00741 {
00742 private:
00743 typedef typename MostDerived<Tail, T>::Result Candidate;
00744 public:
00745 typedef typename Select<
00746 SuperSubclass<Candidate,Head>::value,
00747 Head, Candidate>::Result Result;
00748 };
00749
00751 // class template DerivedToFront
00752 // Arranges the types in a typelist so that the most derived types appear first
00753 // Invocation (TList is a typelist):
00754 // DerivedToFront<TList>::Result
00755 // returns the reordered TList
00757
00758 template <class TList> struct DerivedToFront;
00759
00760 template <>
00761 struct DerivedToFront<NullType>
00762 {
00763 typedef NullType Result;
00764 };
00765
00766 template <class Head, class Tail>
00767 struct DerivedToFront< Typelist<Head, Tail> >
00768 {
00769 private:
00770 typedef typename MostDerived<Tail, Head>::Result
00771 TheMostDerived;
00772 typedef typename Replace<Tail,
00773 TheMostDerived, Head>::Result Temp;
00774 typedef typename DerivedToFront<Temp>::Result L;
00775 public:
00776 typedef Typelist<TheMostDerived, L> Result;
00777 };
00778
00779 } // namespace TL
00780 } // namespace Loki
00781
00783 // Change log:
00784 // June 09, 2001: Fix bug in parameter list of macros TYPELIST_23 to TYPELIST_27
00785 // (credit due to Dave Taylor)
00786 // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
00787 // November 22, 2001: fixed bug in DerivedToFront
00788 // (credit due to Gianni Luciani who noticed the bug first;
00789 // Adam Wilkshire;
00790 // Friedrik Hedman who fixed the bug but didn't send the fix;
00791 // Kevin Cline who sent the first actual fix)
00792 // May 13, 2002: TYPELIST_46 called TYPELIST_45 with only 44 parameters.
00793 // Credit due to Robert Minsk
00794 // September 16, 2002: Changed MostDerived to use the new SuperSubclass template
00795 // (rather than the SUPERSUBCLASS macro).
00796 // Minor fix in Reverse, adding support for empty lists, like all the other
00797 // algorithms.
00798 // Fixed DerivedToFront, to use Replace, rather than ReplaceAll. T.S.
00799 // Oct 10, 2002: added MakeTypelist (SGB/MKH)
00801
00802 #endif // TYPELIST_INC_
本文地址:http://com.8s8s.com/it/it26930.htm