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