root / Community Core Vision / Linux / libs / poco / include / Poco / TypeList.h @ 9

View | Annotate | Download (10.7 KB)

1
//
2
// TypeList.h
3
//
4
// $Id: //poco/1.3/Foundation/include/Poco/TypeList.h#6 $
5
//
6
// Library: Foundation
7
// Package: Core
8
// Module:  TypeList
9
//
10
// Implementation of the TypeList template.
11
//
12
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
13
// and Contributors.
14
//
15
// Portions extracted and adapted from
16
// The Loki Library
17
// Copyright (c) 2001 by Andrei Alexandrescu
18
//
19
// Permission is hereby granted, free of charge, to any person or organization
20
// obtaining a copy of the software and accompanying documentation covered by
21
// this license (the "Software") to use, reproduce, display, distribute,
22
// execute, and transmit the Software, and to prepare derivative works of the
23
// Software, and to permit third-parties to whom the Software is furnished to
24
// do so, all subject to the following:
25
// 
26
// The copyright notices in the Software and this entire statement, including
27
// the above license grant, this restriction and the following disclaimer,
28
// must be included in all copies of the Software, in whole or in part, and
29
// all derivative works of the Software, unless such copies or derivative
30
// works are solely in the form of machine-executable object code generated by
31
// a source language processor.
32
// 
33
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
36
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
37
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
38
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
39
// DEALINGS IN THE SOFTWARE.
40
//
41
42
43
#ifndef  Foundation_TypeList_INCLUDED
44
#define  Foundation_TypeList_INCLUDED
45
46
47
#include "Poco/Foundation.h"
48
#include "Poco/MetaProgramming.h"
49
50
51
namespace Poco {
52
53
54
template <class Head, class Tail> 
55
struct TypeList;
56
57
        
58
struct NullTypeList
59
{
60
        enum
61
        {
62
                length = 0
63
        };
64
65
        bool operator == (const NullTypeList&) const
66
        {
67
                return true;
68
        }
69
70
        bool operator != (const NullTypeList&) const
71
        {
72
                return false;
73
        }
74
75
        bool operator < (const NullTypeList&) const
76
        {
77
                return false;
78
        }
79
};
80
81
82
template <class Head, class Tail> 
83
struct TypeList
84
        /// Compile Time List of Types
85
{
86
        typedef Head HeadType;
87
        typedef Tail TailType;
88
        typedef typename TypeWrapper<HeadType>::CONSTTYPE ConstHeadType;
89
        typedef typename TypeWrapper<TailType>::CONSTTYPE ConstTailType;
90
        enum
91
        {
92
                length = TailType::length+1
93
        };
94
95
        TypeList():head(), tail()
96
        {
97
        }
98
99
        TypeList(ConstHeadType& h, ConstTailType& t):head(h), tail(t)
100
        {
101
        }
102
103
        TypeList(const TypeList& tl): head(tl.head), tail(tl.tail)
104
        {
105
        }
106
107
        TypeList& operator = (const TypeList& tl)
108
        {
109
                if (this != &tl)
110
                {
111
                        TypeList tmp(tl);
112
                        swap(tmp);
113
                }
114
                return *this;
115
        }
116
117
        bool operator == (const TypeList& tl) const
118
        {
119
                return tl.head == head && tl.tail == tail;
120
        }
121
122
        bool operator != (const TypeList& tl) const
123
        {
124
                return !(*this == tl);
125
        }
126
127
        bool operator < (const TypeList& tl) const
128
        {
129
                if (head < tl.head)
130
                        return true;
131
                else if (head == tl.head)
132
                        return tail < tl.tail;
133
                return false;
134
        }
135
136
        void swap(TypeList& tl)
137
        {
138
                std::swap(head, tl.head);
139
                std::swap(tail, tl.tail);
140
        }
141
        
142
        HeadType head;
143
        TailType tail;
144
};
145
146
147
template <typename T0  = NullTypeList, 
148
        typename T1  = NullTypeList, 
149
        typename T2  = NullTypeList,
150
        typename T3  = NullTypeList, 
151
        typename T4  = NullTypeList, 
152
        typename T5  = NullTypeList,
153
        typename T6  = NullTypeList, 
154
        typename T7  = NullTypeList, 
155
        typename T8  = NullTypeList,
156
        typename T9  = NullTypeList, 
157
        typename T10 = NullTypeList, 
158
        typename T11 = NullTypeList,
159
        typename T12 = NullTypeList, 
160
        typename T13 = NullTypeList, 
161
        typename T14 = NullTypeList,
162
        typename T15 = NullTypeList, 
163
        typename T16 = NullTypeList, 
164
        typename T17 = NullTypeList,
165
        typename T18 = NullTypeList,
166
        typename T19 = NullTypeList> 
167
struct TypeListType
168
        /// TypeListType takes 1 - 20 typename arguments.
169
        /// Usage:
170
        ///
171
        /// TypeListType<T0, T1, ... , Tn>::HeadType typeList;
172
        ///
173
        /// typeList is a TypeList of T0, T1, ... , Tn
174
{
175
private:
176
    typedef typename TypeListType<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19>::HeadType TailType;
177
178
public:
179
    typedef TypeList<T0, TailType> HeadType;
180
};
181
182
183
template <>
184
struct TypeListType<>
185
{
186
        typedef NullTypeList HeadType;
187
};
188
189
190
template <int n> 
191
struct Getter
192
{
193
        template <class Ret, class Head, class Tail>
194
        inline static Ret& get(TypeList<Head, Tail>& val)
195
        {
196
                return Getter<n-1>::template get<Ret, typename Tail::HeadType, typename Tail::TailType>(val.tail);
197
        }
198
199
        template <class Ret, class Head, class Tail>
200
        inline static const Ret& get(const TypeList<Head, Tail>& val)
201
        {
202
                return Getter<n-1>::template get<Ret, typename Tail::HeadType, typename Tail::TailType>(val.tail);
203
        }
204
};
205
206
207
template <> 
208
struct Getter<0>
209
{
210
        template <class Ret, class Head, class Tail>
211
        inline static Ret& get(TypeList<Head, Tail>& val)
212
        {
213
                return val.head;
214
        }
215
216
        template <class Ret, class Head, class Tail>
217
        inline static const Ret& get(const TypeList<Head, Tail>& val)
218
        {
219
                return val.head;
220
        }
221
};
222
223
224
template <int N, class Head> 
225
struct TypeGetter;
226
227
228
template <int N, class Head, class Tail> 
229
struct TypeGetter<N, TypeList<Head, Tail> >
230
{
231
        typedef typename TypeGetter<N-1, Tail>::HeadType HeadType;
232
        typedef typename TypeWrapper<HeadType>::CONSTTYPE ConstHeadType;
233
};
234
235
236
template <class Head, class Tail> 
237
struct TypeGetter<0, TypeList<Head, Tail> >
238
{
239
        typedef typename TypeList<Head, Tail>::HeadType HeadType;
240
        typedef typename TypeWrapper<HeadType>::CONSTTYPE ConstHeadType;
241
};
242
243
244
template <class Head, class T>
245
struct TypeLocator;
246
        /// TypeLocator returns the first occurrence of the type T in Head
247
        /// or -1 if the type is not found.
248
        ///
249
        /// Usage example:
250
        ///
251
        /// TypeLocator<Head, int>::HeadType TypeLoc;
252
        ///
253
        /// if (2 == TypeLoc.value) ...
254
        ///
255
        
256
257
template <class T>
258
struct TypeLocator<NullTypeList, T>
259
{
260
        enum { value = -1 };
261
};
262
263
264
template <class T, class Tail>
265
struct TypeLocator<TypeList<T, Tail>, T>
266
{
267
        enum { value = 0 };
268
};
269
270
271
template <class Head, class Tail, class T>
272
struct TypeLocator<TypeList<Head, Tail>, T>
273
{
274
private:
275
        enum { tmp = TypeLocator<Tail, T>::value };
276
public:
277
        enum { value = tmp == -1 ? -1 : 1 + tmp };
278
};
279
280
281
template <class Head, class T> 
282
struct TypeAppender;
283
        /// TypeAppender appends T (type or a TypeList) to Head.
284
        ///
285
        /// Usage:
286
        ///
287
        /// typedef TypeListType<char>::HeadType Type1;
288
        /// typedef TypeAppender<Type1, int>::HeadType Type2;
289
        /// (Type2 is a TypeList of char,int)
290
        ///
291
        ///        typedef TypeListType<float, double>::HeadType Type3;
292
        /// typedef TypeAppender<Type2, Type3>::HeadType Type4;
293
        /// (Type4 is a TypeList of char,int,float,double)
294
        ///
295
296
297
template <>
298
struct TypeAppender<NullTypeList, NullTypeList>
299
{
300
        typedef NullTypeList HeadType;
301
};
302
303
304
template <class T>
305
struct TypeAppender<NullTypeList, T>
306
{
307
        typedef TypeList<T, NullTypeList> HeadType;
308
};
309
310
311
template <class Head, class Tail>
312
struct TypeAppender<NullTypeList, TypeList<Head, Tail> >
313
{
314
        typedef TypeList<Head, Tail> HeadType;
315
};
316
317
318
template <class Head, class Tail, class T>
319
struct TypeAppender<TypeList<Head, Tail>, T>
320
{
321
        typedef TypeList<Head, typename TypeAppender<Tail, T>::HeadType> HeadType;
322
};
323
324
325
template <class Head, class T> 
326
struct TypeOneEraser;
327
        /// TypeOneEraser erases the first occurence of the type T in Head.
328
        /// Usage:
329
        ///
330
        /// typedef TypeListType<char, int, float>::HeadType Type3;
331
        /// typedef TypeOneEraser<Type3, int>::HeadType Type2;
332
        /// (Type2 is a TypeList of char,float)
333
        ///
334
335
336
template <class T>
337
struct TypeOneEraser<NullTypeList, T>
338
{
339
        typedef NullTypeList HeadType;
340
};
341
342
343
template <class T, class Tail>
344
struct TypeOneEraser<TypeList<T, Tail>, T>
345
{
346
        typedef Tail HeadType;
347
};
348
349
350
template <class Head, class Tail, class T>
351
struct TypeOneEraser<TypeList<Head, Tail>, T>
352
{
353
        typedef TypeList <Head, typename TypeOneEraser<Tail, T>::HeadType> HeadType;
354
};
355
356
357
template <class Head, class T> 
358
struct TypeAllEraser;
359
        /// TypeAllEraser erases all the occurences of the type T in Head.
360
        /// Usage:
361
        ///
362
        /// typedef TypeListType<char, int, float, int>::HeadType Type4;
363
        /// typedef TypeAllEraser<Type4, int>::HeadType Type2;
364
        /// (Type2 is a TypeList of char,float)
365
        ///
366
367
368
template <class T>
369
struct TypeAllEraser<NullTypeList, T>
370
{
371
        typedef NullTypeList HeadType;
372
};
373
374
375
template <class T, class Tail>
376
struct TypeAllEraser<TypeList<T, Tail>, T>
377
{
378
        typedef typename TypeAllEraser<Tail, T>::HeadType HeadType;
379
};
380
381
382
template <class Head, class Tail, class T>
383
struct TypeAllEraser<TypeList<Head, Tail>, T>
384
{
385
        typedef TypeList <Head, typename TypeAllEraser<Tail, T>::HeadType> HeadType;
386
};
387
388
389
template <class Head> 
390
struct TypeDuplicateEraser;
391
        /// TypeDuplicateEraser erases all but the first occurence of the type T in Head.
392
        /// Usage:
393
        ///
394
        /// typedef TypeListType<char, int, float, int>::HeadType Type4;
395
        /// typedef TypeDuplicateEraser<Type4, int>::HeadType Type3;
396
        /// (Type3 is a TypeList of char,int,float)
397
        ///
398
399
400
template <> 
401
struct TypeDuplicateEraser<NullTypeList>
402
{
403
        typedef NullTypeList HeadType;
404
};
405
406
407
template <class Head, class Tail>
408
struct TypeDuplicateEraser<TypeList<Head, Tail> >
409
{
410
private:
411
        typedef typename TypeDuplicateEraser<Tail>::HeadType L1;
412
        typedef typename TypeOneEraser<L1, Head>::HeadType L2;
413
public:
414
        typedef TypeList<Head, L2> HeadType;
415
};
416
417
418
template <class Head, class T, class R>
419
struct TypeOneReplacer;
420
        /// TypeOneReplacer replaces the first occurence 
421
        /// of the type T in Head with type R.
422
        /// Usage:
423
        ///
424
        /// typedef TypeListType<char, int, float, int>::HeadType Type4;
425
        /// typedef TypeOneReplacer<Type4, int, double>::HeadType TypeR;
426
        /// (TypeR is a TypeList of char,double,float,int)
427
        ///
428
429
430
template <class T, class R>
431
struct TypeOneReplacer<NullTypeList, T, R>
432
{
433
        typedef NullTypeList HeadType;
434
};
435
436
437
template <class T, class Tail, class R>
438
struct TypeOneReplacer<TypeList<T, Tail>, T, R>
439
{
440
        typedef TypeList<R, Tail> HeadType;
441
};
442
443
444
template <class Head, class Tail, class T, class R>
445
struct TypeOneReplacer<TypeList<Head, Tail>, T, R>
446
{
447
        typedef TypeList<Head, typename TypeOneReplacer<Tail, T, R>::HeadType> HeadType;
448
};
449
450
451
template <class Head, class T, class R>
452
struct TypeAllReplacer;
453
        /// TypeAllReplacer replaces all the occurences 
454
        /// of the type T in Head with type R.
455
        /// Usage:
456
        ///
457
        /// typedef TypeListType<char, int, float, int>::HeadType Type4;
458
        /// typedef TypeAllReplacer<Type4, int, double>::HeadType TypeR;
459
        /// (TypeR is a TypeList of char,double,float,double)
460
        ///
461
462
463
template <class T, class R>
464
struct TypeAllReplacer<NullTypeList, T, R>
465
{
466
        typedef NullTypeList HeadType;
467
};
468
469
470
template <class T, class Tail, class R>
471
struct TypeAllReplacer<TypeList<T, Tail>, T, R>
472
{
473
        typedef TypeList<R, typename TypeAllReplacer<Tail, T, R>::HeadType> HeadType;
474
};
475
476
477
template <class Head, class Tail, class T, class R>
478
struct TypeAllReplacer<TypeList<Head, Tail>, T, R>
479
{
480
        typedef TypeList<Head, typename TypeAllReplacer<Tail, T, R>::HeadType> HeadType;
481
};
482
483
484
} // namespace Poco
485
486
487
#endif