假设你有若干个类,现在你希望给每个类分配一个唯一的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_