1 ////////////////////////////////////////////////////////////////////////////////
2 // The Loki Library
3 // Copyright (c) 2001 by Andrei Alexandrescu
4 // This code accompanies the book:
5 // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
6 // Patterns Applied". Copyright (c) 2001. Addison-Wesley.
7 // Permission to use, copy, modify, distribute and sell this software for any
8 // purpose is hereby granted without fee, provided that the above copyright
9 // notice appear in all copies and that both that copyright notice and this
10 // permission notice appear in supporting documentation.
11 // The author or Addison-Welsey Longman make no representations about the
12 // suitability of this software for any purpose. It is provided "as is"
13 // without express or implied warranty.
14 ////////////////////////////////////////////////////////////////////////////////
15
16 // Last update: June 20, 2001
17
18 #ifndef TYPELIST_INC_
19 #define TYPELIST_INC_
20
21 #include "NullType.h"
22 #include "TypeManip.h"
23
24 ////////////////////////////////////////////////////////////////////////////////
25 // macros TYPELIST_1, TYPELIST_2, ... TYPELIST_50
26 // Each takes a number of arguments equal to its numeric suffix
27 // The arguments are type names. TYPELIST_NN generates a typelist containing
28 // all types passed as arguments, in that order.
29 // Example: TYPELIST_2(char, int) generates a type containing char and int.
30 ////////////////////////////////////////////////////////////////////////////////
31
32 #define TYPELIST_1(T1) ::Loki::Typelist<T1, ::Loki::NullType>
33
34 #define TYPELIST_2(T1, T2) ::Loki::Typelist<T1, TYPELIST_1(T2) >
35
36 #define TYPELIST_3(T1, T2, T3) ::Loki::Typelist<T1, TYPELIST_2(T2, T3) >
37
38 #define TYPELIST_4(T1, T2, T3, T4) \
39 ::Loki::Typelist<T1, TYPELIST_3(T2, T3, T4) >
40
41 #define TYPELIST_5(T1, T2, T3, T4, T5) \
42 ::Loki::Typelist<T1, TYPELIST_4(T2, T3, T4, T5) >
43
44 #define TYPELIST_6(T1, T2, T3, T4, T5, T6) \
45 ::Loki::Typelist<T1, TYPELIST_5(T2, T3, T4, T5, T6) >
46
47 #define TYPELIST_7(T1, T2, T3, T4, T5, T6, T7) \
48 ::Loki::Typelist<T1, TYPELIST_6(T2, T3, T4, T5, T6, T7) >
49
50 #define TYPELIST_8(T1, T2, T3, T4, T5, T6, T7, T8) \
51 ::Loki::Typelist<T1, TYPELIST_7(T2, T3, T4, T5, T6, T7, T8) >
52
53 #define TYPELIST_9(T1, T2, T3, T4, T5, T6, T7, T8, T9) \
54 ::Loki::Typelist<T1, TYPELIST_8(T2, T3, T4, T5, T6, T7, T8, T9) >
55
56 #define TYPELIST_10(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) \
57 ::Loki::Typelist<T1, TYPELIST_9(T2, T3, T4, T5, T6, T7, T8, T9, T10) >
58
59 #define TYPELIST_11(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) \
60 ::Loki::Typelist<T1, TYPELIST_10(T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) >
61
62 #define TYPELIST_12(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) \
63 ::Loki::Typelist<T1, TYPELIST_11(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
64 T11, T12) >
65
66 #define TYPELIST_13(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) \
67 ::Loki::Typelist<T1, TYPELIST_12(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
68 T11, T12, T13) >
69
70 #define TYPELIST_14(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
71 T11, T12, T13, T14) \
72 ::Loki::Typelist<T1, TYPELIST_13(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
73 T11, T12, T13, T14) >
74
75 #define TYPELIST_15(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
76 T11, T12, T13, T14, T15) \
77 ::Loki::Typelist<T1, TYPELIST_14(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
78 T11, T12, T13, T14, T15) >
79
80 #define TYPELIST_16(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
81 T11, T12, T13, T14, T15, T16) \
82 ::Loki::Typelist<T1, TYPELIST_15(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
83 T11, T12, T13, T14, T15, T16) >
84
85 #define TYPELIST_17(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
86 T11, T12, T13, T14, T15, T16, T17) \
87 ::Loki::Typelist<T1, TYPELIST_16(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
88 T11, T12, T13, T14, T15, T16, T17) >
89
90 #define TYPELIST_18(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
91 T11, T12, T13, T14, T15, T16, T17, T18) \
92 ::Loki::Typelist<T1, TYPELIST_17(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
93 T11, T12, T13, T14, T15, T16, T17, T18) >
94
95 #define TYPELIST_19(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
96 T11, T12, T13, T14, T15, T16, T17, T18, T19) \
97 ::Loki::Typelist<T1, TYPELIST_18(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
98 T11, T12, T13, T14, T15, T16, T17, T18, T19) >
99
100 #define TYPELIST_20(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
101 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) \
102 ::Loki::Typelist<T1, TYPELIST_19(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
103 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) >
104
105 #define TYPELIST_21(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
106 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) \
107 ::Loki::Typelist<T1, TYPELIST_20(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
108 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) >
109
110 #define TYPELIST_22(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
111 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) \
112 ::Loki::Typelist<T1, TYPELIST_21(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
113 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) >
114
115 #define TYPELIST_23(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
116 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23) \
117 ::Loki::Typelist<T1, TYPELIST_22(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
118 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23) >
119
120 #define TYPELIST_24(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
121 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24) \
122 ::Loki::Typelist<T1, TYPELIST_23(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
123 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24) >
124
125 #define TYPELIST_25(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
126 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25) \
127 ::Loki::Typelist<T1, TYPELIST_24(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
128 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
129 T21, T22, T23, T24, T25) >
130
131 #define TYPELIST_26(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
132 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
133 T21, T22, T23, T24, T25, T26) \
134 ::Loki::Typelist<T1, TYPELIST_25(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
135 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
136 T21, T22, T23, T24, T25, T26) >
137
138 #define TYPELIST_27(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
139 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
140 T21, T22, T23, T24, T25, T26, T27) \
141 ::Loki::Typelist<T1, TYPELIST_26(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
142 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
143 T21, T22, T23, T24, T25, T26, T27) >
144
145 #define TYPELIST_28(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
146 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
147 T21, T22, T23, T24, T25, T26, T27, T28) \
148 ::Loki::Typelist<T1, TYPELIST_27(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
149 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
150 T21, T22, T23, T24, T25, T26, T27, T28) >
151
152 #define TYPELIST_29(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
153 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
154 T21, T22, T23, T24, T25, T26, T27, T28, T29) \
155 ::Loki::Typelist<T1, TYPELIST_28(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
156 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
157 T21, T22, T23, T24, T25, T26, T27, T28, T29) >
158
159 #define TYPELIST_30(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
160 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
161 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30) \
162 ::Loki::Typelist<T1, TYPELIST_29(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
163 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
164 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30) >
165
166 #define TYPELIST_31(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
167 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
168 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31) \
169 ::Loki::Typelist<T1, TYPELIST_30(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
170 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
171 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31) >
172
173 #define TYPELIST_32(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
174 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
175 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32) \
176 ::Loki::Typelist<T1, TYPELIST_31(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
177 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
178 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32) >
179
180 #define TYPELIST_33(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
181 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
182 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33) \
183 ::Loki::Typelist<T1, TYPELIST_32(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
184 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
185 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33) >
186
187 #define TYPELIST_34(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
188 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
189 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33, T34) \
190 ::Loki::Typelist<T1, TYPELIST_33(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
191 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
192 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33, T34) >
193
194 #define TYPELIST_35(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
195 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
196 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
197 T31, T32, T33, T34, T35) \
198 ::Loki::Typelist<T1, TYPELIST_34(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
199 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
200 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
201 T31, T32, T33, T34, T35) >
202
203 #define TYPELIST_36(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
204 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
205 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
206 T31, T32, T33, T34, T35, T36) \
207 ::Loki::Typelist<T1, TYPELIST_35(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
208 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
209 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
210 T31, T32, T33, T34, T35, T36) >
211
212 #define TYPELIST_37(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
213 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
214 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
215 T31, T32, T33, T34, T35, T36, T37) \
216 ::Loki::Typelist<T1, TYPELIST_36(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
217 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
218 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
219 T31, T32, T33, T34, T35, T36, T37) >
220
221 #define TYPELIST_38(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
222 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
223 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
224 T31, T32, T33, T34, T35, T36, T37, T38) \
225 ::Loki::Typelist<T1, TYPELIST_37(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
226 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
227 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
228 T31, T32, T33, T34, T35, T36, T37, T38) >
229
230 #define TYPELIST_39(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
231 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
232 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
233 T31, T32, T33, T34, T35, T36, T37, T38, T39) \
234 ::Loki::Typelist<T1, TYPELIST_38(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
235 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
236 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
237 T31, T32, T33, T34, T35, T36, T37, T38, T39) >
238
239 #define TYPELIST_40(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
240 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
241 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
242 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40) \
243 ::Loki::Typelist<T1, TYPELIST_39(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
244 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
245 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
246 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40) >
247
248 #define TYPELIST_41(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
249 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
250 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
251 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41) \
252 ::Loki::Typelist<T1, TYPELIST_40(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
253 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
254 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
255 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41) >
256
257 #define TYPELIST_42(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
258 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
259 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
260 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42) \
261 ::Loki::Typelist<T1, TYPELIST_41(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
262 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
263 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
264 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42) >
265
266 #define TYPELIST_43(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
267 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
268 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
269 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43) \
270 ::Loki::Typelist<T1, TYPELIST_42(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
271 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
272 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
273 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43) >
274
275 #define TYPELIST_44(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
276 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
277 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
278 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44) \
279 ::Loki::Typelist<T1, TYPELIST_43(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
280 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
281 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
282 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44) >
283
284 #define TYPELIST_45(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
285 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
286 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
287 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
288 T41, T42, T43, T44, T45) \
289 ::Loki::Typelist<T1, TYPELIST_44(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
290 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
291 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
292 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
293 T41, T42, T43, T44, T45) >
294
295 #define TYPELIST_46(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
296 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
297 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
298 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
299 T41, T42, T43, T44, T45, T46) \
300 ::Loki::Typelist<T1, TYPELIST_45(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
301 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
302 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
303 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
304 T41, T42, T43, T44, T45) >
305
306 #define TYPELIST_47(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
307 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
308 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
309 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
310 T41, T42, T43, T44, T45, T46, T47) \
311 ::Loki::Typelist<T1, TYPELIST_46(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
312 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
313 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
314 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
315 T41, T42, T43, T44, T45, T46, T47) >
316
317 #define TYPELIST_48(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
318 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
319 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
320 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
321 T41, T42, T43, T44, T45, T46, T47, T48) \
322 ::Loki::Typelist<T1, TYPELIST_47(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
323 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
324 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
325 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
326 T41, T42, T43, T44, T45, T46, T47, T48) >
327
328 #define TYPELIST_49(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
329 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
330 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
331 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
332 T41, T42, T43, T44, T45, T46, T47, T48, T49) \
333 ::Loki::Typelist<T1, TYPELIST_48(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
334 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
335 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
336 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
337 T41, T42, T43, T44, T45, T46, T47, T48, T49) >
338
339 #define TYPELIST_50(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
340 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
341 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
342 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
343 T41, T42, T43, T44, T45, T46, T47, T48, T49, T50) \
344 ::Loki::Typelist<T1, TYPELIST_49(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
345 T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
346 T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
347 T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
348 T41, T42, T43, T44, T45, T46, T47, T48, T49, T50) >
349
350 namespace Loki
351 {
352 ////////////////////////////////////////////////////////////////////////////////
353 // class template Typelist
354 // The building block of typelists of any length
355 // Use it through the TYPELIST_NN macros
356 // Defines nested types:
357 // Head (first element, a non-typelist type by convention)
358 // Tail (second element, can be another typelist)
359 ////////////////////////////////////////////////////////////////////////////////
360
361 template <class T, class U>
362 struct Typelist
363 {
364 typedef T Head;
365 typedef U Tail;
366 };
367
368 namespace TL
369 {
370 ////////////////////////////////////////////////////////////////////////////////
371 // class template Length
372 // Computes the length of a typelist
373 // Invocation (TList is a typelist):
374 // Length<TList>::value
375 // returns a compile-time constant containing the length of TList, not counting
376 // the end terminator (which by convention is NullType)
377 ////////////////////////////////////////////////////////////////////////////////
378
379 template <class TList> struct Length;
380 template <> struct Length<NullType>
381 {
382 enum { value = 0 };
383 };
384
385 template <class T, class U>
386 struct Length< Typelist<T, U> >
387 {
388 enum { value = 1 + Length<U>::value };
389 };
390
391 ////////////////////////////////////////////////////////////////////////////////
392 // class template TypeAt
393 // Finds the type at a given index in a typelist
394 // Invocation (TList is a typelist and index is a compile-time integral
395 // constant):
396 // TypeAt<TList, index>::Result
397 // returns the type in position 'index' in TList
398 // If you pass an out-of-bounds index, the result is a compile-time error
399 ////////////////////////////////////////////////////////////////////////////////
400
401 template <class TList, unsigned int index> struct TypeAt;
402
403 template <class Head, class Tail>
404 struct TypeAt<Typelist<Head, Tail>, 0>
405 {
406 typedef Head Result;
407 };
408
409 template <class Head, class Tail, unsigned int i>
410 struct TypeAt<Typelist<Head, Tail>, i>
411 {
412 typedef typename TypeAt<Tail, i - 1>::Result Result;
413 };
414
415 ////////////////////////////////////////////////////////////////////////////////
416 // class template TypeAtNonStrict
417 // Finds the type at a given index in a typelist
418 // Invocations (TList is a typelist and index is a compile-time integral
419 // constant):
420 // a) TypeAt<TList, index>::Result
421 // returns the type in position 'index' in TList, or NullType if index is
422 // out-of-bounds
423 // b) TypeAt<TList, index, D>::Result
424 // returns the type in position 'index' in TList, or D if index is out-of-bounds
425 ////////////////////////////////////////////////////////////////////////////////
426
427 template <class TList, unsigned int index,
428 typename DefaultType = NullType>
429 struct TypeAtNonStrict
430 {
431 typedef DefaultType Result;
432 };
433
434 template <class Head, class Tail, typename DefaultType>
435 struct TypeAtNonStrict<Typelist<Head, Tail>, 0, DefaultType>
436 {
437 typedef Head Result;
438 };
439
440 template <class Head, class Tail, unsigned int i, typename DefaultType>
441 struct TypeAtNonStrict<Typelist<Head, Tail>, i, DefaultType>
442 {
443 typedef typename
444 TypeAtNonStrict<Tail, i - 1, DefaultType>::Result Result;
445 };
446
447 ////////////////////////////////////////////////////////////////////////////////
448 // class template IndexOf
449 // Finds the index of a type in a typelist
450 // Invocation (TList is a typelist and T is a type):
451 // IndexOf<TList, T>::value
452 // returns the position of T in TList, or NullType if T is not found in TList
453 ////////////////////////////////////////////////////////////////////////////////
454
455 template <class TList, class T> struct IndexOf;
456
457 template <class T>
458 struct IndexOf<NullType, T>
459 {
460 enum { value = -1 };
461 };
462
463 template <class T, class Tail>
464 struct IndexOf<Typelist<T, Tail>, T>
465 {
466 enum { value = 0 };
467 };
468
469 template <class Head, class Tail, class T>
470 struct IndexOf<Typelist<Head, Tail>, T>
471 {
472 private:
473 enum { temp = IndexOf<Tail, T>::value };
474 public:
475 enum { value = (temp == -1 ? -1 : 1 + temp) };
476 };
477
478 ////////////////////////////////////////////////////////////////////////////////
479 // class template Append
480 // Appends a type or a typelist to another
481 // Invocation (TList is a typelist and T is either a type or a typelist):
482 // Append<TList, T>::Result
483 // returns a typelist that is TList followed by T and NullType-terminated
484 ////////////////////////////////////////////////////////////////////////////////
485
486 template <class TList, class T> struct Append;
487
488 template <> struct Append<NullType, NullType>
489 {
490 typedef NullType Result;
491 };
492
493 template <class T> struct Append<NullType, T>
494 {
495 typedef TYPELIST_1(T) Result;
496 };
497
498 template <class Head, class Tail>
499 struct Append<NullType, Typelist<Head, Tail> >
500 {
501 typedef Typelist<Head, Tail> Result;
502 };
503
504 template <class Head, class Tail, class T>
505 struct Append<Typelist<Head, Tail>, T>
506 {
507 typedef Typelist<Head,
508 typename Append<Tail, T>::Result>
509 Result;
510 };
511
512 ////////////////////////////////////////////////////////////////////////////////
513 // class template Erase
514 // Erases the first occurence, if any, of a type in a typelist
515 // Invocation (TList is a typelist and T is a type):
516 // Erase<TList, T>::Result
517 // returns a typelist that is TList without the first occurence of T
518 ////////////////////////////////////////////////////////////////////////////////
519
520 template <class TList, class T> struct Erase;
521
522 template <class T> // Specialization 1
523 struct Erase<NullType, T>
524 {
525 typedef NullType Result;
526 };
527
528 template <class T, class Tail> // Specialization 2
529 struct Erase<Typelist<T, Tail>, T>
530 {
531 typedef Tail Result;
532 };
533
534 template <class Head, class Tail, class T> // Specialization 3
535 struct Erase<Typelist<Head, Tail>, T>
536 {
537 typedef Typelist<Head,
538 typename Erase<Tail, T>::Result>
539 Result;
540 };
541
542 ////////////////////////////////////////////////////////////////////////////////
543 // class template EraseAll
544 // Erases all first occurences, if any, of a type in a typelist
545 // Invocation (TList is a typelist and T is a type):
546 // EraseAll<TList, T>::Result
547 // returns a typelist that is TList without any occurence of T
548 ////////////////////////////////////////////////////////////////////////////////
549
550 template <class TList, class T> struct EraseAll;
551 template <class T>
552 struct EraseAll<NullType, T>
553 {
554 typedef NullType Result;
555 };
556 template <class T, class Tail>
557 struct EraseAll<Typelist<T, Tail>, T>
558 {
559 // Go all the way down the list removing the type
560 typedef typename EraseAll<Tail, T>::Result Result;
561 };
562 template <class Head, class Tail, class T>
563 struct EraseAll<Typelist<Head, Tail>, T>
564 {
565 // Go all the way down the list removing the type
566 typedef Typelist<Head,
567 typename EraseAll<Tail, T>::Result>
568 Result;
569 };
570
571 ////////////////////////////////////////////////////////////////////////////////
572 // class template NoDuplicates
573 // Removes all duplicate types in a typelist
574 // Invocation (TList is a typelist):
575 // NoDuplicates<TList, T>::Result
576 ////////////////////////////////////////////////////////////////////////////////
577
578 template <class TList> struct NoDuplicates;
579
580 template <> struct NoDuplicates<NullType>
581 {
582 typedef NullType Result;
583 };
584
585 template <class Head, class Tail>
586 struct NoDuplicates< Typelist<Head, Tail> >
587 {
588 private:
589 typedef typename NoDuplicates<Tail>::Result L1;
590 typedef typename Erase<L1, Head>::Result L2;
591 public:
592 typedef Typelist<Head, L2> Result;
593 };
594
595 ////////////////////////////////////////////////////////////////////////////////
596 // class template Replace
597 // Replaces the first occurence of a type in a typelist, with another type
598 // Invocation (TList is a typelist, T, U are types):
599 // Replace<TList, T, U>::Result
600 // returns a typelist in which the first occurence of T is replaced with U
601 ////////////////////////////////////////////////////////////////////////////////
602
603 template <class TList, class T, class U> struct Replace;
604
605 template <class T, class U>
606 struct Replace<NullType, T, U>
607 {
608 typedef NullType Result;
609 };
610
611 template <class T, class Tail, class U>
612 struct Replace<Typelist<T, Tail>, T, U>
613 {
614 typedef Typelist<U, Tail> Result;
615 };
616
617 template <class Head, class Tail, class T, class U>
618 struct Replace<Typelist<Head, Tail>, T, U>
619 {
620 typedef Typelist<Head,
621 typename Replace<Tail, T, U>::Result>
622 Result;
623 };
624
625 ////////////////////////////////////////////////////////////////////////////////
626 // class template ReplaceAll
627 // Replaces all occurences of a type in a typelist, with another type
628 // Invocation (TList is a typelist, T, U are types):
629 // Replace<TList, T, U>::Result
630 // returns a typelist in which all occurences of T is replaced with U
631 ////////////////////////////////////////////////////////////////////////////////
632
633 template <class TList, class T, class U> struct ReplaceAll;
634
635 template <class T, class U>
636 struct ReplaceAll<NullType, T, U>
637 {
638 typedef NullType Result;
639 };
640
641 template <class T, class Tail, class U>
642 struct ReplaceAll<Typelist<T, Tail>, T, U>
643 {
644 typedef Typelist<U, typename ReplaceAll<Tail, T, U>::Result> Result;
645 };
646
647 template <class Head, class Tail, class T, class U>
648 struct ReplaceAll<Typelist<Head, Tail>, T, U>
649 {
650 typedef Typelist<Head,
651 typename ReplaceAll<Tail, T, U>::Result>
652 Result;
653 };
654
655 ////////////////////////////////////////////////////////////////////////////////
656 // class template Reverse
657 // Reverses a typelist
658 // Invocation (TList is a typelist):
659 // Reverse<TList>::Result
660 // returns a typelist that is TList reversed
661 ////////////////////////////////////////////////////////////////////////////////
662
663 template <class TList> struct Reverse;
664
665 template <class T>
666 struct Reverse< TYPELIST_1(T) >
667 {
668 typedef TYPELIST_1(T) Result;
669 };
670
671 template <class Head, class Tail>
672 struct Reverse< Typelist<Head, Tail> >
673 {
674 typedef typename Append<
675 typename Reverse<Tail>::Result, Head>::Result Result;
676 };
677
678 ////////////////////////////////////////////////////////////////////////////////
679 // class template MostDerived
680 // Finds the type in a typelist that is the most derived from a given type
681 // Invocation (TList is a typelist, T is a type):
682 // Replace<TList, T>::Result
683 // returns the type in TList that's the most derived from T
684 ////////////////////////////////////////////////////////////////////////////////
685
686 template <class TList, class T> struct MostDerived;
687
688 template <class T>
689 struct MostDerived<NullType, T>
690 {
691 typedef T Result;
692 };
693
694 template <class Head, class Tail, class T>
695 struct MostDerived<Typelist<Head, Tail>, T>
696 {
697 private:
698 typedef typename MostDerived<Tail, T>::Result Candidate;
699 public:
700 typedef typename Select<
701 SUPERSUBCLASS(Candidate, Head),
702 Head, Candidate>::Result Result;
703 };
704
705 ////////////////////////////////////////////////////////////////////////////////
706 // class template DerivedToFront
707 // Arranges the types in a typelist so that the most derived types appear first
708 // Invocation (TList is a typelist):
709 // DerivedToFront<TList>::Result
710 // returns the reordered TList
711 ////////////////////////////////////////////////////////////////////////////////
712
713 template <class TList> struct DerivedToFront;
714
715 template <>
716 struct DerivedToFront<NullType>
717 {
718 typedef NullType Result;
719 };
720
721 template <class Head, class Tail>
722 struct DerivedToFront< Typelist<Head, Tail> >
723 {
724 private:
725 typedef typename MostDerived<Tail, Head>::Result
726 TheMostDerived;
727 typedef typename Replace<Tail,
728 TheMostDerived, Head>::Result L;
729 public:
730 typedef Typelist<TheMostDerived, L> Result;
731 };
732
733 } // namespace TL
734 } // namespace Loki
735
736 ////////////////////////////////////////////////////////////////////////////////
737 // Change log:
738 // June 09, 2001: Fix bug in parameter list of macros TYPELIST_23 to TYPELIST_27
739 // (credit due to Dave Taylor)
740 // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
741 ////////////////////////////////////////////////////////////////////////////////
742
743 #endif // TYPELIST_INC_