1 | //krazy:excludeall=license (minor variation on MIT license) |
2 | /* |
3 | This work is derived from: |
4 | ---- |
5 | The Loki Library |
6 | Copyright (c) 2001 by Andrei Alexandrescu //krazy:exclude=copyright |
7 | This code accompanies the book: |
8 | Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design |
9 | Patterns Applied". Copyright (c) 2001. Addison-Wesley. //krazy:exclude=copyright |
10 | Permission to use, copy, modify, distribute and sell this software for any |
11 | purpose is hereby granted without fee, provided that the above copyright |
12 | notice appear in all copies and that both that copyright notice and this |
13 | permission notice appear in supporting documentation. |
14 | The author or Addison-Welsey Longman make no representations about the |
15 | suitability of this software for any purpose. It is provided "as is" |
16 | without express or implied warranty. |
17 | ---- |
18 | |
19 | Simon: Actually we could put a lot more of typelist stuff in here, like |
20 | real list management (append, erase, ...) or other things, but |
21 | for now I just added the basic typelist and a length template, |
22 | to keep compile time at a minimum. If we really need more we can |
23 | still add it :) |
24 | Holger: Now we add a Template to create the TypeList |
25 | */ |
26 | |
27 | /** |
28 | * @file ktypelist.h |
29 | * |
30 | * This file defines typelist structures as well as convenience macros |
31 | * to create typelists. Additionally, a few typelist compile-time |
32 | * algorithms are provided. |
33 | */ |
34 | |
35 | /** |
36 | * @defgroup ktypelist Typelist classes, algorithms and macros |
37 | * |
38 | * Typelists are lists of C++ types of arbitrary length. They are used |
39 | * to carry type information at compile-time. |
40 | * |
41 | * Internally, typelists are represented by the KTypeList template |
42 | * class. The KTypeList class uses the recursive structure of |
43 | * singly-linked lists which is common in functional programming |
44 | * languages: |
45 | * |
46 | * - an empty list is of type KDE::NullType (the terminal marker) |
47 | * - a one-element list with element @c T is of type |
48 | * KTypeList\<T, KDE::NullType\>. |
49 | * - a two-element list with elements @c T and @c U is of type |
50 | * KTypeList\<T, KTypeList\<U, KDE::NullType\> \>. |
51 | * - an N-Element list with the first element @c T and the remaining |
52 | * elements @c Rest is of type KTypeList\<T, Rest\>. |
53 | * |
54 | * Note that the last element of a typelist is always KDE::NullType. |
55 | * Also note that this is only a convention, it is not enforced by |
56 | * anything. But if these rules are broken, the compile-time algorithms |
57 | * defined for typelists don't work. |
58 | * |
59 | * To ease the definition of typelists, there are some macros which |
60 | * expand to nested KTypeList definitions. These macros have the form |
61 | * |
62 | * @code |
63 | * K_TYPELIST_N(T1, T2, ..., TN) |
64 | * @endcode |
65 | * |
66 | * where @c N is the number of types in the list (e.g. K_TYPELIST_3()) |
67 | * |
68 | * In addition to that, and also as the preferred way, there is the |
69 | * KMakeTypeList template which takes an arbitrary number of type |
70 | * arguments (up to 18) and exports a nested typedef called @c Result |
71 | * which equals a KTypeList with the list of provided arguments. |
72 | * |
73 | * To work with typelists, several compile-time algorithms are provided: |
74 | * |
75 | * - KTypeListLength: determine the number of elements in a typelist |
76 | * - KTypeListIndexOf: find a given type in a typelist |
77 | * |
78 | * For a detailed discussion about typelists, see the book "Modern C++ |
79 | * Design: Generic Programming and Design Patterns Applied" by Andrei |
80 | * Alexandrescu, and/or the Loki Library at |
81 | * <a href="http://sourceforge.net/projects/loki-lib/">http://sourceforge.net/projects/loki-lib/</a> |
82 | */ |
83 | |
84 | #ifndef ktypelist_h |
85 | #define ktypelist_h |
86 | |
87 | /** |
88 | * @name Typelist macros |
89 | * |
90 | * Convenience macros for transforming flat type enumerations into the |
91 | * recursive typelist structure. For a typelist with @c N items, the |
92 | * @c K_TYPELIST_N macro is used. For example: |
93 | * |
94 | * @code |
95 | * typedef K_TYPELIST_4(char, short, int, long) IntegralTypes; |
96 | * @endcode |
97 | * |
98 | * However, the preferred way is to use the KMakeTypeList template. |
99 | * |
100 | * @ingroup ktypelist |
101 | */ |
102 | //@{ |
103 | #define K_TYPELIST_1(T1) KTypeList<T1, ::KDE::NullType> |
104 | |
105 | #define K_TYPELIST_2(T1, T2) KTypeList<T1, K_TYPELIST_1(T2) > |
106 | |
107 | #define K_TYPELIST_3(T1, T2, T3) KTypeList<T1, K_TYPELIST_2(T2, T3) > |
108 | |
109 | #define K_TYPELIST_4(T1, T2, T3, T4) \ |
110 | KTypeList<T1, K_TYPELIST_3(T2, T3, T4) > |
111 | |
112 | #define K_TYPELIST_5(T1, T2, T3, T4, T5) \ |
113 | KTypeList<T1, K_TYPELIST_4(T2, T3, T4, T5) > |
114 | |
115 | #define K_TYPELIST_6(T1, T2, T3, T4, T5, T6) \ |
116 | KTypeList<T1, K_TYPELIST_5(T2, T3, T4, T5, T6) > |
117 | |
118 | #define K_TYPELIST_7(T1, T2, T3, T4, T5, T6, T7) \ |
119 | KTypeList<T1, K_TYPELIST_6(T2, T3, T4, T5, T6, T7) > |
120 | |
121 | #define K_TYPELIST_8(T1, T2, T3, T4, T5, T6, T7, T8) \ |
122 | KTypeList<T1, K_TYPELIST_7(T2, T3, T4, T5, T6, T7, T8) > |
123 | |
124 | #define K_TYPELIST_9(T1, T2, T3, T4, T5, T6, T7, T8, T9) \ |
125 | KTypeList<T1, K_TYPELIST_8(T2, T3, T4, T5, T6, T7, T8, T9) > |
126 | |
127 | #define K_TYPELIST_10(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) \ |
128 | KTypeList<T1, K_TYPELIST_9(T2, T3, T4, T5, T6, T7, T8, T9, T10) > |
129 | |
130 | #define K_TYPELIST_11(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) \ |
131 | KTypeList<T1, K_TYPELIST_10(T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) > |
132 | |
133 | #define K_TYPELIST_12(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) \ |
134 | KTypeList<T1, K_TYPELIST_11(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
135 | T11, T12) > |
136 | |
137 | #define K_TYPELIST_13(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) \ |
138 | KTypeList<T1, K_TYPELIST_12(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
139 | T11, T12, T13) > |
140 | |
141 | #define K_TYPELIST_14(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
142 | T11, T12, T13, T14) \ |
143 | KTypeList<T1, K_TYPELIST_13(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
144 | T11, T12, T13, T14) > |
145 | |
146 | #define K_TYPELIST_15(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
147 | T11, T12, T13, T14, T15) \ |
148 | KTypeList<T1, K_TYPELIST_14(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
149 | T11, T12, T13, T14, T15) > |
150 | |
151 | #define K_TYPELIST_16(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
152 | T11, T12, T13, T14, T15, T16) \ |
153 | KTypeList<T1, K_TYPELIST_15(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
154 | T11, T12, T13, T14, T15, T16) > |
155 | |
156 | #define K_TYPELIST_17(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
157 | T11, T12, T13, T14, T15, T16, T17) \ |
158 | KTypeList<T1, K_TYPELIST_16(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
159 | T11, T12, T13, T14, T15, T16, T17) > |
160 | |
161 | #define K_TYPELIST_18(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
162 | T11, T12, T13, T14, T15, T16, T17, T18) \ |
163 | KTypeList<T1, K_TYPELIST_17(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
164 | T11, T12, T13, T14, T15, T16, T17, T18) > |
165 | |
166 | #define K_TYPELIST_19(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
167 | T11, T12, T13, T14, T15, T16, T17, T18, T19) \ |
168 | KTypeList<T1, K_TYPELIST_18(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
169 | T11, T12, T13, T14, T15, T16, T17, T18, T19) > |
170 | |
171 | #define K_TYPELIST_20(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
172 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) \ |
173 | KTypeList<T1, K_TYPELIST_19(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
174 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) > |
175 | |
176 | #define K_TYPELIST_21(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
177 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) \ |
178 | KTypeList<T1, K_TYPELIST_20(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
179 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) > |
180 | |
181 | #define K_TYPELIST_22(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
182 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) \ |
183 | KTypeList<T1, K_TYPELIST_21(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
184 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) > |
185 | |
186 | #define K_TYPELIST_23(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
187 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23) \ |
188 | KTypeList<T1, K_TYPELIST_22(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
189 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23) > |
190 | |
191 | #define K_TYPELIST_24(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
192 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24) \ |
193 | KTypeList<T1, K_TYPELIST_23(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
194 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24) > |
195 | |
196 | #define K_TYPELIST_25(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
197 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25) \ |
198 | KTypeList<T1, K_TYPELIST_24(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) > |
201 | |
202 | #define K_TYPELIST_26(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
203 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
204 | T21, T22, T23, T24, T25, T26) \ |
205 | KTypeList<T1, K_TYPELIST_25(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
206 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
207 | T21, T22, T23, T24, T25, T26) > |
208 | |
209 | #define K_TYPELIST_27(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
210 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
211 | T21, T22, T23, T24, T25, T26, T27) \ |
212 | KTypeList<T1, K_TYPELIST_26(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) > |
215 | |
216 | #define K_TYPELIST_28(T1, 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) \ |
219 | KTypeList<T1, K_TYPELIST_27(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
220 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
221 | T21, T22, T23, T24, T25, T26, T27, T28) > |
222 | |
223 | #define K_TYPELIST_29(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
224 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
225 | T21, T22, T23, T24, T25, T26, T27, T28, T29) \ |
226 | KTypeList<T1, K_TYPELIST_28(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
227 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
228 | T21, T22, T23, T24, T25, T26, T27, T28, T29) > |
229 | |
230 | #define K_TYPELIST_30(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 | KTypeList<T1, K_TYPELIST_29(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
234 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
235 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30) > |
236 | |
237 | #define K_TYPELIST_31(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
238 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
239 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31) \ |
240 | KTypeList<T1, K_TYPELIST_30(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
241 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
242 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31) > |
243 | |
244 | #define K_TYPELIST_32(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
245 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
246 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32) \ |
247 | KTypeList<T1, K_TYPELIST_31(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
248 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
249 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32) > |
250 | |
251 | #define K_TYPELIST_33(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
252 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
253 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33) \ |
254 | KTypeList<T1, K_TYPELIST_32(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
255 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
256 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33) > |
257 | |
258 | #define K_TYPELIST_34(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
259 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
260 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33, T34) \ |
261 | KTypeList<T1, K_TYPELIST_33(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, T31, T32, T33, T34) > |
264 | |
265 | #define K_TYPELIST_35(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
266 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
267 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
268 | T31, T32, T33, T34, T35) \ |
269 | KTypeList<T1, K_TYPELIST_34(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
270 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
271 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
272 | T31, T32, T33, T34, T35) > |
273 | |
274 | #define K_TYPELIST_36(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
275 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
276 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
277 | T31, T32, T33, T34, T35, T36) \ |
278 | KTypeList<T1, K_TYPELIST_35(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
279 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
280 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
281 | T31, T32, T33, T34, T35, T36) > |
282 | |
283 | #define K_TYPELIST_37(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
284 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
285 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
286 | T31, T32, T33, T34, T35, T36, T37) \ |
287 | KTypeList<T1, K_TYPELIST_36(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
288 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
289 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
290 | T31, T32, T33, T34, T35, T36, T37) > |
291 | |
292 | #define K_TYPELIST_38(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
293 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
294 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
295 | T31, T32, T33, T34, T35, T36, T37, T38) \ |
296 | KTypeList<T1, K_TYPELIST_37(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
297 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
298 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
299 | T31, T32, T33, T34, T35, T36, T37, T38) > |
300 | |
301 | #define K_TYPELIST_39(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
302 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
303 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
304 | T31, T32, T33, T34, T35, T36, T37, T38, T39) \ |
305 | KTypeList<T1, K_TYPELIST_38(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
306 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
307 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
308 | T31, T32, T33, T34, T35, T36, T37, T38, T39) > |
309 | |
310 | #define K_TYPELIST_40(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
311 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
312 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
313 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40) \ |
314 | KTypeList<T1, K_TYPELIST_39(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
315 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
316 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
317 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40) > |
318 | |
319 | #define K_TYPELIST_41(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
320 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
321 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
322 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41) \ |
323 | KTypeList<T1, K_TYPELIST_40(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
324 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
325 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
326 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41) > |
327 | |
328 | #define K_TYPELIST_42(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, T41, T42) \ |
332 | KTypeList<T1, K_TYPELIST_41(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
333 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
334 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
335 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42) > |
336 | |
337 | #define K_TYPELIST_43(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
338 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
339 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
340 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43) \ |
341 | KTypeList<T1, K_TYPELIST_42(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
342 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
343 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
344 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43) > |
345 | |
346 | #define K_TYPELIST_44(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
347 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
348 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
349 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44) \ |
350 | KTypeList<T1, K_TYPELIST_43(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
351 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
352 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
353 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44) > |
354 | |
355 | #define K_TYPELIST_45(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
356 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
357 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
358 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ |
359 | T41, T42, T43, T44, T45) \ |
360 | KTypeList<T1, K_TYPELIST_44(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
361 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
362 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
363 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ |
364 | T41, T42, T43, T44, T45) > |
365 | |
366 | #define K_TYPELIST_46(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
367 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
368 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
369 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ |
370 | T41, T42, T43, T44, T45, T46) \ |
371 | KTypeList<T1, K_TYPELIST_45(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
372 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
373 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
374 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ |
375 | T41, T42, T43, T44, T45, T46) > |
376 | |
377 | #define K_TYPELIST_47(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
378 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
379 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
380 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ |
381 | T41, T42, T43, T44, T45, T46, T47) \ |
382 | KTypeList<T1, K_TYPELIST_46(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
383 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
384 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
385 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ |
386 | T41, T42, T43, T44, T45, T46, T47) > |
387 | |
388 | #define K_TYPELIST_48(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
389 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
390 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
391 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ |
392 | T41, T42, T43, T44, T45, T46, T47, T48) \ |
393 | KTypeList<T1, K_TYPELIST_47(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
394 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
395 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
396 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ |
397 | T41, T42, T43, T44, T45, T46, T47, T48) > |
398 | |
399 | #define K_TYPELIST_49(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
400 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
401 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
402 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ |
403 | T41, T42, T43, T44, T45, T46, T47, T48, T49) \ |
404 | KTypeList<T1, K_TYPELIST_48(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
405 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
406 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
407 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ |
408 | T41, T42, T43, T44, T45, T46, T47, T48, T49) > |
409 | |
410 | #define K_TYPELIST_50(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
411 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
412 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
413 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ |
414 | T41, T42, T43, T44, T45, T46, T47, T48, T49, T50) \ |
415 | KTypeList<T1, K_TYPELIST_49(T2, T3, T4, T5, T6, T7, T8, T9, T10, \ |
416 | T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ |
417 | T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ |
418 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ |
419 | T41, T42, T43, T44, T45, T46, T47, T48, T49, T50) > |
420 | //@} |
421 | |
422 | namespace KDE |
423 | { |
424 | /** |
425 | * @class KDE::NullType |
426 | * |
427 | * This empty class serves as a terminal marker for typelists. |
428 | * The last element in a KTypeList is always this class. |
429 | * |
430 | * @ingroup ktypelist |
431 | */ |
432 | class NullType; |
433 | } |
434 | |
435 | /** |
436 | * The building block of typelists of any length. |
437 | * Rather than using it directly, you should use it through the |
438 | * KMakeTypeList template class or one of the K_TYPELIST_NN macros, |
439 | * such as K_TYPELIST_3(). |
440 | * |
441 | * This struct defines two nested types: |
442 | * @li Head (first element, a non-typelist type by convention), |
443 | * is the same as the type parameter @p T. |
444 | * @li Tail (second element, must be either another typelist |
445 | * or KDE::NullType), is the same as the type parameter @p U. |
446 | * |
447 | * @param T the head of the type list |
448 | * @param U the tail of the type list |
449 | * |
450 | * @ingroup ktypelist |
451 | */ |
452 | template <class T, class U> |
453 | struct KTypeList |
454 | { |
455 | /// first element, a non-typelist type by convention |
456 | typedef T Head; |
457 | /// second element, must be either another typelist or KDE::NullType |
458 | typedef U Tail; |
459 | }; |
460 | |
461 | // forward decl. |
462 | /** |
463 | * @class KTypeListLength |
464 | * |
465 | * This class template implements a compile-time algorithm |
466 | * for processing typelists. It expects one type argument: |
467 | * @p TList. |
468 | * |
469 | * KTypeListLength determines the number of elements (the |
470 | * length) of the typelist @p TList and exports it through |
471 | * the member @c Value. The length of KDE::NullType is 0. |
472 | * Example: |
473 | * |
474 | * @code |
475 | * typedef KMakeTypeList<char, short, int, long>::Result IntegralTypes; |
476 | * assert(KTypeListLength<IntegralTypes>::Value == 4); |
477 | * assert(KTypeListLength<KDE::NullType>::Value == 0); |
478 | * @endcode |
479 | * |
480 | * @param TList the typelist of which the length is to be |
481 | * calculated |
482 | * |
483 | * @ingroup ktypelist |
484 | */ |
485 | template <class TList> struct KTypeListLength; |
486 | |
487 | template <> |
488 | struct KTypeListLength<KDE::NullType> |
489 | { |
490 | /** |
491 | * Zero length type list. |
492 | */ |
493 | enum { Value = 0 }; |
494 | }; |
495 | |
496 | template <class T, class U> |
497 | struct KTypeListLength< KTypeList<T, U> > |
498 | { |
499 | /** |
500 | * The length of the type list. |
501 | */ |
502 | enum { Value = 1 + KTypeListLength<U>::Value }; |
503 | }; |
504 | |
505 | /////////////////////////////////////////////////////////////////////////////// |
506 | // class template IndexOf |
507 | // Finds the index of a type in a typelist |
508 | // Invocation (TList is a typelist and T is a type): |
509 | // IndexOf<TList, T>::value |
510 | // returns the position of T in TList, or NullType if T is not found in TList |
511 | //////////////////////////////////////////////////////////////////////////////// |
512 | |
513 | /** |
514 | * @class KTypeListIndexOf |
515 | * |
516 | * This class template implements a compile-time algorithm |
517 | * for processing typelists. It expects two type arguments: |
518 | * @p TList and @p T. |
519 | * |
520 | * KTypeListIndexOf finds the index of @p T in @p TList |
521 | * starting at 0 and exports it through the @c value member. |
522 | * If @p T is not found, @c value is -1. Example: |
523 | * |
524 | * @code |
525 | * typedef KMakeTypeList<char, short, int, long>::Result IntegralTypes; |
526 | * assert(KTypeListIndexOf<IntegralTypes, int>::value == 3); |
527 | * assert(KTypeListIndexOf<IntegralTypes, double>::value == -1); |
528 | * @endcode |
529 | * |
530 | * @param TList either a KTypeList or KDE::NullType |
531 | * @param T the type to search for in the typelist |
532 | * |
533 | * @ingroup ktypelist |
534 | */ |
535 | template <class TList, class T> struct KTypeListIndexOf; |
536 | |
537 | template <class T> |
538 | struct KTypeListIndexOf<KDE::NullType, T> |
539 | { |
540 | enum { value = -1 }; |
541 | }; |
542 | |
543 | template <class T, class Tail> |
544 | struct KTypeListIndexOf< KTypeList<T, Tail>, T > |
545 | { |
546 | enum { value = 0 }; |
547 | }; |
548 | |
549 | template <class Head, class Tail, class T> |
550 | struct KTypeListIndexOf< KTypeList<Head, Tail>, T > |
551 | { |
552 | private: |
553 | enum { temp = KTypeListIndexOf<Tail, T>::value }; |
554 | public: |
555 | enum { value = (temp == -1 ? -1 : 1 + temp) }; |
556 | }; |
557 | |
558 | |
559 | |
560 | /** |
561 | * This class template implements a compile-time algorithm |
562 | * for generating typelists. |
563 | * |
564 | * KMakeTypeList the preferred way to create a typelist for you. |
565 | * You can specify up to 18 types for the typelist. This template |
566 | * class calculates the desired typelist and stores it in the |
567 | * nested @c Result typedef. Example: |
568 | * |
569 | * \code |
570 | * typedef KMakeTypeList<MyType1,MyWidget,MyQobject,MyKoffice>::Result Products; |
571 | * K_EXPORT_COMPONENT_FACTORY( libmyplugin, KGenericFactory<Products> ) |
572 | * \endcode |
573 | * |
574 | * @author Holger Freyther based on the Loki library. See copyright statement at the top |
575 | * @ingroup ktypelist |
576 | */ |
577 | template< |
578 | typename T1 = KDE::NullType, typename T2 = KDE::NullType, typename T3 = KDE::NullType, |
579 | typename T4 = KDE::NullType, typename T5 = KDE::NullType, typename T6 = KDE::NullType, |
580 | typename T7 = KDE::NullType, typename T8 = KDE::NullType, typename T9 = KDE::NullType, |
581 | typename T10 = KDE::NullType, typename T11 = KDE::NullType, typename T12 = KDE::NullType, |
582 | typename T13 = KDE::NullType, typename T14 = KDE::NullType, typename T15 = KDE::NullType, |
583 | typename T16 = KDE::NullType, typename T17 = KDE::NullType, typename T18 = KDE::NullType |
584 | > |
585 | struct KMakeTypeList{ |
586 | private: |
587 | typedef typename KMakeTypeList |
588 | < |
589 | T2 , T3 , T4 , |
590 | T5 , T6 , T7 , |
591 | T8 , T9 , T10, |
592 | T11, T12, T13, |
593 | T14, T15, T16, |
594 | T17, T18 |
595 | >::Result TailResult; |
596 | |
597 | public: |
598 | /** |
599 | * The resulting KTypeList calculated by this compile-time |
600 | * algorithm. |
601 | */ |
602 | typedef KTypeList<T1, TailResult> Result; |
603 | }; |
604 | |
605 | template< |
606 | typename T2 , typename T3 , |
607 | typename T4 , typename T5 , typename T6 , |
608 | typename T7 , typename T8 , typename T9 , |
609 | typename T10, typename T11, typename T12, |
610 | typename T13, typename T14, typename T15, |
611 | typename T16, typename T17, typename T18 |
612 | > |
613 | struct KMakeTypeList<KDE::NullType, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18> |
614 | { |
615 | typedef KDE::NullType Result; |
616 | }; |
617 | |
618 | template<> |
619 | struct KMakeTypeList<> |
620 | { |
621 | typedef KDE::NullType Result; |
622 | }; |
623 | |
624 | |
625 | #endif |
626 | |
627 | |