libstdc++
|
00001 // -*- C++ -*- 00002 00003 // Copyright (C) 2005, 2006, 2008, 2009 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. 00026 00027 // Permission to use, copy, modify, sell, and distribute this software 00028 // is hereby granted without fee, provided that the above copyright 00029 // notice appears in all copies, and that both that copyright notice and 00030 // this permission notice appear in supporting documentation. None of 00031 // the above authors, nor IBM Haifa Research Laboratories, make any 00032 // representation about the suitability of this software for any 00033 // purpose. It is provided "as is" without express or implied warranty. 00034 00035 /** 00036 * @file typelist.h 00037 * Contains typelist_chain definitions. 00038 * Typelists are an idea by Andrei Alexandrescu. 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 /** @namespace __gnu_cxx::typelist 00049 * @brief GNU typelist extensions for public compile-time use. 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 // Forward declarations of functors. 00062 template<typename Hd, typename Typelist> 00063 struct chain 00064 { 00065 typedef Hd head; 00066 typedef Typelist tail; 00067 }; 00068 00069 // Apply all typelist types to unary functor. 00070 template<typename Fn, typename Typelist> 00071 void 00072 apply(Fn&, Typelist); 00073 00074 /// Apply all typelist types to generator functor. 00075 template<typename Gn, typename Typelist> 00076 void 00077 apply_generator(Gn&, Typelist); 00078 00079 // Apply all typelist types and values to generator functor. 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 } // namespace typelist 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 } // namespace detail 00362 } // namespace typelist 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 } // namespace typelist 00540 _GLIBCXX_END_NAMESPACE 00541 00542 00543 #endif 00544