Merge branch 'vendor/GCC44' into gcc441
[dragonfly.git] / contrib / gcc-4.4 / libstdc++-v3 / include / ext / typelist.h
1 // -*- C++ -*-
2
3 // Copyright (C) 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
24
25 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
26
27 // Permission to use, copy, modify, sell, and distribute this software
28 // is hereby granted without fee, provided that the above copyright
29 // notice appears in all copies, and that both that copyright notice and
30 // this permission notice appear in supporting documentation. None of
31 // the above authors, nor IBM Haifa Research Laboratories, make any
32 // representation about the suitability of this software for any
33 // purpose. It is provided "as is" without express or implied warranty.
34
35 /**
36  * @file typelist.h
37  * Contains typelist_chain definitions.
38  * Typelists are an idea by Andrei Alexandrescu.
39  */
40
41 #ifndef _TYPELIST_H
42 #define _TYPELIST_H 1
43
44 #include <ext/type_traits.h>
45
46 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
47
48 /** @namespace __gnu_cxx::typelist
49  *  @brief GNU typelist extensions for public compile-time use.
50 */
51 namespace typelist
52 {
53   struct null_type { };
54
55   template<typename Root>
56     struct node
57     {
58       typedef Root      root;
59     };
60
61   // Forward declarations of functors.
62   template<typename Hd, typename Typelist>
63     struct chain
64     {
65       typedef Hd        head;
66       typedef Typelist  tail;
67     };
68
69   // Apply all typelist types to unary functor.
70   template<typename Fn, typename Typelist>
71     void
72     apply(Fn&, Typelist);
73
74   /// Apply all typelist types to generator functor.
75   template<typename Gn, typename Typelist>
76     void
77     apply_generator(Gn&, Typelist);
78
79   // Apply all typelist types and values to generator functor.
80   template<typename Gn, typename TypelistT, typename TypelistV>
81     void
82     apply_generator(Gn&, TypelistT, TypelistV);
83
84   template<typename Typelist0, typename Typelist1>
85     struct append;
86
87   template<typename Typelist_Typelist>
88     struct append_typelist;
89
90   template<typename Typelist, typename T>
91     struct contains;
92  
93   template<typename Typelist, template<typename T> class Pred>
94     struct filter;
95
96   template<typename Typelist, int i>
97     struct at_index;
98
99   template<typename Typelist, template<typename T> class Transform>
100     struct transform;
101
102   template<typename Typelist_Typelist>
103     struct flatten;
104
105   template<typename Typelist>
106     struct from_first;
107
108   template<typename T1>
109     struct create1;
110
111   template<typename T1, typename T2>
112     struct create2;
113
114   template<typename T1, typename T2, typename T3>
115     struct create3;
116
117   template<typename T1, typename T2, typename T3, typename T4>
118     struct create4;
119
120   template<typename T1, typename T2, typename T3, typename T4, typename T5>
121     struct create5;
122
123   template<typename T1, typename T2, typename T3, 
124            typename T4, typename T5, typename T6>
125     struct create6;
126 } // namespace typelist
127
128 _GLIBCXX_END_NAMESPACE
129
130
131 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
132
133 namespace typelist 
134 {
135 namespace detail
136 {
137   template<typename Fn, typename Typelist_Chain>
138     struct apply_;
139
140   template<typename Fn, typename Hd, typename Tl>
141     struct apply_<Fn, chain<Hd, Tl> >
142     {
143       void
144       operator()(Fn& f)
145       {
146         f.operator()(Hd());
147         apply_<Fn, Tl> next;
148         next(f);
149       }
150     };
151
152   template<typename Fn>
153     struct apply_<Fn, null_type>
154     {
155       void
156       operator()(Fn&) { }
157     };
158
159   template<typename Gn, typename Typelist_Chain>
160     struct apply_generator1_;
161
162   template<typename Gn, typename Hd, typename Tl>
163     struct apply_generator1_<Gn, chain<Hd, Tl> >
164     {
165       void
166       operator()(Gn& g)
167       {
168         g.template operator()<Hd>();
169         apply_generator1_<Gn, Tl> next;
170         next(g);
171       }
172     };
173
174   template<typename Gn>
175     struct apply_generator1_<Gn, null_type>
176     {
177       void
178       operator()(Gn&) { }
179     };
180
181   template<typename Gn, typename TypelistT_Chain, typename TypelistV_Chain>
182     struct apply_generator2_;
183
184   template<typename Gn, typename Hd1, typename TlT, typename Hd2, typename TlV>
185     struct apply_generator2_<Gn, chain<Hd1, TlT>, chain<Hd2, TlV> >
186     {
187       void
188       operator()(Gn& g)
189       {
190         g.template operator()<Hd1, Hd2>();
191         apply_generator2_<Gn, TlT, TlV> next;
192         next(g);
193       }
194     };
195
196   template<typename Gn>
197     struct apply_generator2_<Gn, null_type, null_type>
198     {
199       void
200       operator()(Gn&) { }
201     };
202
203   template<typename Typelist_Chain0, typename Typelist_Chain1>
204     struct append_;
205
206   template<typename Hd, typename Tl, typename Typelist_Chain>
207     struct append_<chain<Hd, Tl>, Typelist_Chain>
208     {
209     private:
210       typedef append_<Tl, Typelist_Chain>                       append_type;
211
212     public:
213       typedef chain<Hd, typename append_type::type>             type;
214     };
215
216   template<typename Typelist_Chain>
217     struct append_<null_type, Typelist_Chain>
218     {
219       typedef Typelist_Chain                                    type;
220     };
221
222   template<typename Typelist_Chain>
223     struct append_<Typelist_Chain, null_type>
224     {
225       typedef Typelist_Chain                                    type;
226     };
227
228   template<>
229     struct append_<null_type, null_type>
230     {
231       typedef null_type                                         type;
232     };
233
234   template<typename Typelist_Typelist_Chain>
235     struct append_typelist_;
236
237   template<typename Hd>
238     struct append_typelist_<chain<Hd, null_type> >
239     {
240       typedef chain<Hd, null_type>                              type;
241     };
242
243   template<typename Hd, typename Tl>
244     struct append_typelist_<chain< Hd, Tl> >
245     {
246     private:
247       typedef typename append_typelist_<Tl>::type               rest_type;
248       
249     public:
250       typedef typename append<Hd, node<rest_type> >::type::root type;
251     };
252
253   template<typename Typelist_Chain, typename T>
254     struct contains_;
255
256   template<typename T>
257     struct contains_<null_type, T>
258     {
259       enum
260         {
261           value = false
262         };
263     };
264
265   template<typename Hd, typename Tl, typename T>
266     struct contains_<chain<Hd, Tl>, T>
267     {
268       enum
269         {
270           value = contains_<Tl, T>::value
271         };
272     };
273   
274   template<typename Tl, typename T>
275     struct contains_<chain<T, Tl>, T>
276     {
277       enum
278         {
279           value = true
280         };
281     };
282
283   template<typename Typelist_Chain, template<typename T> class Pred>
284     struct chain_filter_;
285
286   template<template<typename T> class Pred>
287     struct chain_filter_<null_type, Pred>
288     {
289       typedef null_type                                         type;
290   };
291
292   template<typename Hd, typename Tl, template<typename T> class Pred>
293     struct chain_filter_<chain<Hd, Tl>, Pred>
294     {
295     private:
296       enum
297         {
298           include_hd = Pred<Hd>::value
299         };
300       
301       typedef typename chain_filter_<Tl, Pred>::type            rest_type;
302       typedef chain<Hd, rest_type>                              chain_type;
303
304     public:
305       typedef typename __conditional_type<include_hd, chain_type, rest_type>::__type type;
306   };
307
308   template<typename Typelist_Chain, int i>
309     struct chain_at_index_;
310
311   template<typename Hd, typename Tl>
312     struct chain_at_index_<chain<Hd, Tl>, 0>
313     {
314       typedef Hd                                                type;
315     };
316   
317   template<typename Hd, typename Tl, int i>
318     struct chain_at_index_<chain<Hd, Tl>, i>
319     {
320       typedef typename chain_at_index_<Tl, i - 1>::type         type;
321     };
322
323   template<class Typelist_Chain, template<typename T> class Transform>
324     struct chain_transform_;
325
326   template<template<typename T> class Transform>
327     struct chain_transform_<null_type, Transform>
328     {
329       typedef null_type                                         type;
330     };
331   
332   template<class Hd, class Tl, template<typename T> class Transform>
333     struct chain_transform_<chain<Hd, Tl>, Transform>
334     {
335     private:
336       typedef typename chain_transform_<Tl, Transform>::type    rest_type;
337       typedef typename Transform<Hd>::type                      transform_type;
338
339     public:
340       typedef chain<transform_type, rest_type>                  type;
341     };
342
343   template<typename Typelist_Typelist_Chain>
344     struct chain_flatten_;
345
346   template<typename Hd_Tl>
347     struct chain_flatten_<chain<Hd_Tl, null_type> >
348     {
349       typedef typename Hd_Tl::root                              type;
350     };
351
352   template<typename Hd_Typelist, class Tl_Typelist>
353     struct chain_flatten_<chain<Hd_Typelist, Tl_Typelist> >
354     {
355     private:
356       typedef typename chain_flatten_<Tl_Typelist>::type        rest_type;
357       typedef append<Hd_Typelist, node<rest_type> >             append_type;
358     public:
359       typedef typename append_type::type::root                  type;
360     };
361 } // namespace detail
362 } // namespace typelist
363
364 _GLIBCXX_END_NAMESPACE
365
366 #define _GLIBCXX_TYPELIST_CHAIN1(X0) __gnu_cxx::typelist::chain<X0, __gnu_cxx::typelist::null_type>
367 #define _GLIBCXX_TYPELIST_CHAIN2(X0, X1) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN1(X1) >
368 #define _GLIBCXX_TYPELIST_CHAIN3(X0, X1, X2) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN2(X1, X2) >
369 #define _GLIBCXX_TYPELIST_CHAIN4(X0, X1, X2, X3) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN3(X1, X2, X3) >
370 #define _GLIBCXX_TYPELIST_CHAIN5(X0, X1, X2, X3, X4) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN4(X1, X2, X3, X4) >
371 #define _GLIBCXX_TYPELIST_CHAIN6(X0, X1, X2, X3, X4, X5) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN5(X1, X2, X3, X4, X5) >
372 #define _GLIBCXX_TYPELIST_CHAIN7(X0, X1, X2, X3, X4, X5, X6) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN6(X1, X2, X3, X4, X5, X6) >
373 #define _GLIBCXX_TYPELIST_CHAIN8(X0, X1, X2, X3, X4, X5, X6, X7) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN7(X1, X2, X3, X4, X5, X6, X7) >
374 #define _GLIBCXX_TYPELIST_CHAIN9(X0, X1, X2, X3, X4, X5, X6, X7, X8) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN8(X1, X2, X3, X4, X5, X6, X7, X8) >
375 #define _GLIBCXX_TYPELIST_CHAIN10(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN9(X1, X2, X3, X4, X5, X6, X7, X8, X9) >
376 #define _GLIBCXX_TYPELIST_CHAIN11(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN10(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10) >
377 #define _GLIBCXX_TYPELIST_CHAIN12(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN11(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11) >
378 #define _GLIBCXX_TYPELIST_CHAIN13(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN12(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12) >
379 #define _GLIBCXX_TYPELIST_CHAIN14(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN13(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13) >
380 #define _GLIBCXX_TYPELIST_CHAIN15(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN14(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14) >
381
382 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
383
384 namespace typelist
385 {
386   template<typename Fn, typename Typelist>
387     void
388     apply(Fn& fn, Typelist)
389     {
390       detail::apply_<Fn, typename Typelist::root> a;
391       a(fn);
392     }
393
394   template<typename Fn, typename Typelist>
395     void
396     apply_generator(Fn& fn, Typelist)
397     {
398       detail::apply_generator1_<Fn, typename Typelist::root> a;
399       a(fn);
400     }
401
402   template<typename Fn, typename TypelistT, typename TypelistV>
403     void
404     apply_generator(Fn& fn, TypelistT, TypelistV)
405     {
406       typedef typename TypelistT::root rootT;
407       typedef typename TypelistV::root rootV;
408       detail::apply_generator2_<Fn, rootT, rootV> a;
409       a(fn);
410     }
411
412   template<typename Typelist0, typename Typelist1>
413     struct append
414     {
415     private:
416       typedef typename Typelist0::root                          root0_type;
417       typedef typename Typelist1::root                          root1_type;
418       typedef detail::append_<root0_type, root1_type>           append_type;
419
420     public:
421       typedef node<typename append_type::type>                  type;
422     };
423
424   template<typename Typelist_Typelist>
425     struct append_typelist
426     {
427     private:
428       typedef typename Typelist_Typelist::root                  root_type;
429       typedef detail::append_typelist_<root_type>               append_type;
430
431     public:
432       typedef node<typename append_type::type>                  type;
433     };
434
435   template<typename Typelist, typename T>
436     struct contains
437     {
438     private:
439       typedef typename Typelist::root                           root_type;
440
441     public:
442       enum
443         {
444           value = detail::contains_<root_type, T>::value
445         };
446     };
447
448   template<typename Typelist, template<typename T> class Pred>
449     struct filter
450     {
451     private:
452       typedef typename Typelist::root                           root_type;
453       typedef detail::chain_filter_<root_type, Pred>            filter_type;
454
455     public:
456       typedef node<typename filter_type::type>                  type;
457     };
458
459   template<typename Typelist, int i>
460     struct at_index
461     {
462     private:
463       typedef typename Typelist::root                           root_type;
464       typedef detail::chain_at_index_<root_type, i>             index_type;
465       
466     public:
467       typedef typename index_type::type                         type;
468     };
469
470   template<typename Typelist, template<typename T> class Transform>
471     struct transform
472     {
473     private:
474       typedef typename Typelist::root                           root_type;
475       typedef detail::chain_transform_<root_type, Transform>    transform_type;
476
477     public:
478       typedef node<typename transform_type::type>               type;
479     };
480
481   template<typename Typelist_Typelist>
482     struct flatten
483     {
484     private:
485       typedef typename Typelist_Typelist::root                  root_type;
486       typedef typename detail::chain_flatten_<root_type>::type  flatten_type;
487
488     public:
489       typedef node<flatten_type>                                type;
490     };
491
492   template<typename Typelist>
493     struct from_first
494     {
495     private:
496       typedef typename at_index<Typelist, 0>::type              first_type;
497
498     public:
499       typedef node<chain<first_type, null_type> >               type;
500     };
501
502   template<typename T1>
503     struct create1
504     {
505       typedef node<_GLIBCXX_TYPELIST_CHAIN1(T1)>                type;
506     };
507
508   template<typename T1, typename T2>
509     struct create2
510     {
511       typedef node<_GLIBCXX_TYPELIST_CHAIN2(T1,T2)>             type;
512     };
513
514   template<typename T1, typename T2, typename T3>
515     struct create3
516     {
517       typedef node<_GLIBCXX_TYPELIST_CHAIN3(T1,T2,T3)>          type;
518     };
519
520   template<typename T1, typename T2, typename T3, typename T4>
521     struct create4
522     {
523       typedef node<_GLIBCXX_TYPELIST_CHAIN4(T1,T2,T3,T4)>       type;
524     };
525
526   template<typename T1, typename T2, typename T3, 
527            typename T4, typename T5>
528     struct create5
529     {
530       typedef node<_GLIBCXX_TYPELIST_CHAIN5(T1,T2,T3,T4,T5)>    type;
531     };
532
533   template<typename T1, typename T2, typename T3, 
534            typename T4, typename T5, typename T6>
535     struct create6
536     {
537       typedef node<_GLIBCXX_TYPELIST_CHAIN6(T1,T2,T3,T4,T5,T6)> type;
538     };
539 } // namespace typelist
540 _GLIBCXX_END_NAMESPACE
541
542
543 #endif
544