为多个类分配ID——Loki库的Typelist的一个小应用

类别:编程语言 点击:0 评论:0 推荐:
    假设你有若干个类,现在你希望给每个类分配一个唯一的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