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