00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #ifndef _TYPELIST_H
00042 #define _TYPELIST_H 1
00043
00044 #include <ext/type_traits.h>
00045
00046 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
00047
00048
00049
00050
00051 namespace typelist
00052 {
00053 struct null_type { };
00054
00055 template<typename Root>
00056 struct node
00057 {
00058 typedef Root root;
00059 };
00060
00061
00062 template<typename Hd, typename Typelist>
00063 struct chain
00064 {
00065 typedef Hd head;
00066 typedef Typelist tail;
00067 };
00068
00069
00070 template<typename Fn, typename Typelist>
00071 void
00072 apply(Fn&, Typelist);
00073
00074
00075 template<typename Gn, typename Typelist>
00076 void
00077 apply_generator(Gn&, Typelist);
00078
00079
00080 template<typename Gn, typename TypelistT, typename TypelistV>
00081 void
00082 apply_generator(Gn&, TypelistT, TypelistV);
00083
00084 template<typename Typelist0, typename Typelist1>
00085 struct append;
00086
00087 template<typename Typelist_Typelist>
00088 struct append_typelist;
00089
00090 template<typename Typelist, typename T>
00091 struct contains;
00092
00093 template<typename Typelist, template<typename T> class Pred>
00094 struct filter;
00095
00096 template<typename Typelist, int i>
00097 struct at_index;
00098
00099 template<typename Typelist, template<typename T> class Transform>
00100 struct transform;
00101
00102 template<typename Typelist_Typelist>
00103 struct flatten;
00104
00105 template<typename Typelist>
00106 struct from_first;
00107
00108 template<typename T1>
00109 struct create1;
00110
00111 template<typename T1, typename T2>
00112 struct create2;
00113
00114 template<typename T1, typename T2, typename T3>
00115 struct create3;
00116
00117 template<typename T1, typename T2, typename T3, typename T4>
00118 struct create4;
00119
00120 template<typename T1, typename T2, typename T3, typename T4, typename T5>
00121 struct create5;
00122
00123 template<typename T1, typename T2, typename T3,
00124 typename T4, typename T5, typename T6>
00125 struct create6;
00126 }
00127
00128 _GLIBCXX_END_NAMESPACE
00129
00130
00131 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
00132
00133 namespace typelist
00134 {
00135 namespace detail
00136 {
00137 template<typename Fn, typename Typelist_Chain>
00138 struct apply_;
00139
00140 template<typename Fn, typename Hd, typename Tl>
00141 struct apply_<Fn, chain<Hd, Tl> >
00142 {
00143 void
00144 operator()(Fn& f)
00145 {
00146 f.operator()(Hd());
00147 apply_<Fn, Tl> next;
00148 next(f);
00149 }
00150 };
00151
00152 template<typename Fn>
00153 struct apply_<Fn, null_type>
00154 {
00155 void
00156 operator()(Fn&) { }
00157 };
00158
00159 template<typename Gn, typename Typelist_Chain>
00160 struct apply_generator1_;
00161
00162 template<typename Gn, typename Hd, typename Tl>
00163 struct apply_generator1_<Gn, chain<Hd, Tl> >
00164 {
00165 void
00166 operator()(Gn& g)
00167 {
00168 g.template operator()<Hd>();
00169 apply_generator1_<Gn, Tl> next;
00170 next(g);
00171 }
00172 };
00173
00174 template<typename Gn>
00175 struct apply_generator1_<Gn, null_type>
00176 {
00177 void
00178 operator()(Gn&) { }
00179 };
00180
00181 template<typename Gn, typename TypelistT_Chain, typename TypelistV_Chain>
00182 struct apply_generator2_;
00183
00184 template<typename Gn, typename Hd1, typename TlT, typename Hd2, typename TlV>
00185 struct apply_generator2_<Gn, chain<Hd1, TlT>, chain<Hd2, TlV> >
00186 {
00187 void
00188 operator()(Gn& g)
00189 {
00190 g.template operator()<Hd1, Hd2>();
00191 apply_generator2_<Gn, TlT, TlV> next;
00192 next(g);
00193 }
00194 };
00195
00196 template<typename Gn>
00197 struct apply_generator2_<Gn, null_type, null_type>
00198 {
00199 void
00200 operator()(Gn&) { }
00201 };
00202
00203 template<typename Typelist_Chain0, typename Typelist_Chain1>
00204 struct append_;
00205
00206 template<typename Hd, typename Tl, typename Typelist_Chain>
00207 struct append_<chain<Hd, Tl>, Typelist_Chain>
00208 {
00209 private:
00210 typedef append_<Tl, Typelist_Chain> append_type;
00211
00212 public:
00213 typedef chain<Hd, typename append_type::type> type;
00214 };
00215
00216 template<typename Typelist_Chain>
00217 struct append_<null_type, Typelist_Chain>
00218 {
00219 typedef Typelist_Chain type;
00220 };
00221
00222 template<typename Typelist_Chain>
00223 struct append_<Typelist_Chain, null_type>
00224 {
00225 typedef Typelist_Chain type;
00226 };
00227
00228 template<>
00229 struct append_<null_type, null_type>
00230 {
00231 typedef null_type type;
00232 };
00233
00234 template<typename Typelist_Typelist_Chain>
00235 struct append_typelist_;
00236
00237 template<typename Hd>
00238 struct append_typelist_<chain<Hd, null_type> >
00239 {
00240 typedef chain<Hd, null_type> type;
00241 };
00242
00243 template<typename Hd, typename Tl>
00244 struct append_typelist_<chain< Hd, Tl> >
00245 {
00246 private:
00247 typedef typename append_typelist_<Tl>::type rest_type;
00248
00249 public:
00250 typedef typename append<Hd, node<rest_type> >::type::root type;
00251 };
00252
00253 template<typename Typelist_Chain, typename T>
00254 struct contains_;
00255
00256 template<typename T>
00257 struct contains_<null_type, T>
00258 {
00259 enum
00260 {
00261 value = false
00262 };
00263 };
00264
00265 template<typename Hd, typename Tl, typename T>
00266 struct contains_<chain<Hd, Tl>, T>
00267 {
00268 enum
00269 {
00270 value = contains_<Tl, T>::value
00271 };
00272 };
00273
00274 template<typename Tl, typename T>
00275 struct contains_<chain<T, Tl>, T>
00276 {
00277 enum
00278 {
00279 value = true
00280 };
00281 };
00282
00283 template<typename Typelist_Chain, template<typename T> class Pred>
00284 struct chain_filter_;
00285
00286 template<template<typename T> class Pred>
00287 struct chain_filter_<null_type, Pred>
00288 {
00289 typedef null_type type;
00290 };
00291
00292 template<typename Hd, typename Tl, template<typename T> class Pred>
00293 struct chain_filter_<chain<Hd, Tl>, Pred>
00294 {
00295 private:
00296 enum
00297 {
00298 include_hd = Pred<Hd>::value
00299 };
00300
00301 typedef typename chain_filter_<Tl, Pred>::type rest_type;
00302 typedef chain<Hd, rest_type> chain_type;
00303
00304 public:
00305 typedef typename __conditional_type<include_hd, chain_type, rest_type>::__type type;
00306 };
00307
00308 template<typename Typelist_Chain, int i>
00309 struct chain_at_index_;
00310
00311 template<typename Hd, typename Tl>
00312 struct chain_at_index_<chain<Hd, Tl>, 0>
00313 {
00314 typedef Hd type;
00315 };
00316
00317 template<typename Hd, typename Tl, int i>
00318 struct chain_at_index_<chain<Hd, Tl>, i>
00319 {
00320 typedef typename chain_at_index_<Tl, i - 1>::type type;
00321 };
00322
00323 template<class Typelist_Chain, template<typename T> class Transform>
00324 struct chain_transform_;
00325
00326 template<template<typename T> class Transform>
00327 struct chain_transform_<null_type, Transform>
00328 {
00329 typedef null_type type;
00330 };
00331
00332 template<class Hd, class Tl, template<typename T> class Transform>
00333 struct chain_transform_<chain<Hd, Tl>, Transform>
00334 {
00335 private:
00336 typedef typename chain_transform_<Tl, Transform>::type rest_type;
00337 typedef typename Transform<Hd>::type transform_type;
00338
00339 public:
00340 typedef chain<transform_type, rest_type> type;
00341 };
00342
00343 template<typename Typelist_Typelist_Chain>
00344 struct chain_flatten_;
00345
00346 template<typename Hd_Tl>
00347 struct chain_flatten_<chain<Hd_Tl, null_type> >
00348 {
00349 typedef typename Hd_Tl::root type;
00350 };
00351
00352 template<typename Hd_Typelist, class Tl_Typelist>
00353 struct chain_flatten_<chain<Hd_Typelist, Tl_Typelist> >
00354 {
00355 private:
00356 typedef typename chain_flatten_<Tl_Typelist>::type rest_type;
00357 typedef append<Hd_Typelist, node<rest_type> > append_type;
00358 public:
00359 typedef typename append_type::type::root type;
00360 };
00361 }
00362 }
00363
00364 _GLIBCXX_END_NAMESPACE
00365
00366 #define _GLIBCXX_TYPELIST_CHAIN1(X0) __gnu_cxx::typelist::chain<X0, __gnu_cxx::typelist::null_type>
00367 #define _GLIBCXX_TYPELIST_CHAIN2(X0, X1) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN1(X1) >
00368 #define _GLIBCXX_TYPELIST_CHAIN3(X0, X1, X2) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN2(X1, X2) >
00369 #define _GLIBCXX_TYPELIST_CHAIN4(X0, X1, X2, X3) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN3(X1, X2, X3) >
00370 #define _GLIBCXX_TYPELIST_CHAIN5(X0, X1, X2, X3, X4) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN4(X1, X2, X3, X4) >
00371 #define _GLIBCXX_TYPELIST_CHAIN6(X0, X1, X2, X3, X4, X5) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN5(X1, X2, X3, X4, X5) >
00372 #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) >
00373 #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) >
00374 #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) >
00375 #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) >
00376 #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) >
00377 #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) >
00378 #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) >
00379 #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) >
00380 #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) >
00381
00382 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
00383
00384 namespace typelist
00385 {
00386 template<typename Fn, typename Typelist>
00387 void
00388 apply(Fn& fn, Typelist)
00389 {
00390 detail::apply_<Fn, typename Typelist::root> a;
00391 a(fn);
00392 }
00393
00394 template<typename Fn, typename Typelist>
00395 void
00396 apply_generator(Fn& fn, Typelist)
00397 {
00398 detail::apply_generator1_<Fn, typename Typelist::root> a;
00399 a(fn);
00400 }
00401
00402 template<typename Fn, typename TypelistT, typename TypelistV>
00403 void
00404 apply_generator(Fn& fn, TypelistT, TypelistV)
00405 {
00406 typedef typename TypelistT::root rootT;
00407 typedef typename TypelistV::root rootV;
00408 detail::apply_generator2_<Fn, rootT, rootV> a;
00409 a(fn);
00410 }
00411
00412 template<typename Typelist0, typename Typelist1>
00413 struct append
00414 {
00415 private:
00416 typedef typename Typelist0::root root0_type;
00417 typedef typename Typelist1::root root1_type;
00418 typedef detail::append_<root0_type, root1_type> append_type;
00419
00420 public:
00421 typedef node<typename append_type::type> type;
00422 };
00423
00424 template<typename Typelist_Typelist>
00425 struct append_typelist
00426 {
00427 private:
00428 typedef typename Typelist_Typelist::root root_type;
00429 typedef detail::append_typelist_<root_type> append_type;
00430
00431 public:
00432 typedef node<typename append_type::type> type;
00433 };
00434
00435 template<typename Typelist, typename T>
00436 struct contains
00437 {
00438 private:
00439 typedef typename Typelist::root root_type;
00440
00441 public:
00442 enum
00443 {
00444 value = detail::contains_<root_type, T>::value
00445 };
00446 };
00447
00448 template<typename Typelist, template<typename T> class Pred>
00449 struct filter
00450 {
00451 private:
00452 typedef typename Typelist::root root_type;
00453 typedef detail::chain_filter_<root_type, Pred> filter_type;
00454
00455 public:
00456 typedef node<typename filter_type::type> type;
00457 };
00458
00459 template<typename Typelist, int i>
00460 struct at_index
00461 {
00462 private:
00463 typedef typename Typelist::root root_type;
00464 typedef detail::chain_at_index_<root_type, i> index_type;
00465
00466 public:
00467 typedef typename index_type::type type;
00468 };
00469
00470 template<typename Typelist, template<typename T> class Transform>
00471 struct transform
00472 {
00473 private:
00474 typedef typename Typelist::root root_type;
00475 typedef detail::chain_transform_<root_type, Transform> transform_type;
00476
00477 public:
00478 typedef node<typename transform_type::type> type;
00479 };
00480
00481 template<typename Typelist_Typelist>
00482 struct flatten
00483 {
00484 private:
00485 typedef typename Typelist_Typelist::root root_type;
00486 typedef typename detail::chain_flatten_<root_type>::type flatten_type;
00487
00488 public:
00489 typedef node<flatten_type> type;
00490 };
00491
00492 template<typename Typelist>
00493 struct from_first
00494 {
00495 private:
00496 typedef typename at_index<Typelist, 0>::type first_type;
00497
00498 public:
00499 typedef node<chain<first_type, null_type> > type;
00500 };
00501
00502 template<typename T1>
00503 struct create1
00504 {
00505 typedef node<_GLIBCXX_TYPELIST_CHAIN1(T1)> type;
00506 };
00507
00508 template<typename T1, typename T2>
00509 struct create2
00510 {
00511 typedef node<_GLIBCXX_TYPELIST_CHAIN2(T1,T2)> type;
00512 };
00513
00514 template<typename T1, typename T2, typename T3>
00515 struct create3
00516 {
00517 typedef node<_GLIBCXX_TYPELIST_CHAIN3(T1,T2,T3)> type;
00518 };
00519
00520 template<typename T1, typename T2, typename T3, typename T4>
00521 struct create4
00522 {
00523 typedef node<_GLIBCXX_TYPELIST_CHAIN4(T1,T2,T3,T4)> type;
00524 };
00525
00526 template<typename T1, typename T2, typename T3,
00527 typename T4, typename T5>
00528 struct create5
00529 {
00530 typedef node<_GLIBCXX_TYPELIST_CHAIN5(T1,T2,T3,T4,T5)> type;
00531 };
00532
00533 template<typename T1, typename T2, typename T3,
00534 typename T4, typename T5, typename T6>
00535 struct create6
00536 {
00537 typedef node<_GLIBCXX_TYPELIST_CHAIN6(T1,T2,T3,T4,T5,T6)> type;
00538 };
00539 }
00540 _GLIBCXX_END_NAMESPACE
00541
00542
00543 #endif
00544