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
422namespace 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 */
452template <class T, class U>
453struct 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 */
485template <class TList> struct KTypeListLength;
486
487template <>
488struct KTypeListLength<KDE::NullType>
489{
490/**
491 * Zero length type list.
492 */
493 enum { Value = 0 };
494};
495
496template <class T, class U>
497struct 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 */
535template <class TList, class T> struct KTypeListIndexOf;
536
537template <class T>
538struct KTypeListIndexOf<KDE::NullType, T>
539{
540 enum { value = -1 };
541};
542
543template <class T, class Tail>
544struct KTypeListIndexOf< KTypeList<T, Tail>, T >
545{
546 enum { value = 0 };
547};
548
549template <class Head, class Tail, class T>
550struct KTypeListIndexOf< KTypeList<Head, Tail>, T >
551{
552private:
553 enum { temp = KTypeListIndexOf<Tail, T>::value };
554public:
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 */
577template<
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 >
585struct KMakeTypeList{
586private:
587typedef 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
597public:
598 /**
599 * The resulting KTypeList calculated by this compile-time
600 * algorithm.
601 */
602 typedef KTypeList<T1, TailResult> Result;
603};
604
605template<
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 >
613struct 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
618template<>
619struct KMakeTypeList<>
620{
621 typedef KDE::NullType Result;
622};
623
624
625#endif
626
627