libstdc++
|
00001 // -*- C++ -*- 00002 00003 // Copyright (C) 2005, 2006, 2008, 2009, 2010, 2011 00004 // Free Software Foundation, Inc. 00005 // 00006 // This file is part of the GNU ISO C++ Library. This library is free 00007 // software; you can redistribute it and/or modify it under the 00008 // terms of the GNU General Public License as published by the 00009 // Free Software Foundation; either version 3, or (at your option) 00010 // any later version. 00011 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 00017 // Under Section 7 of GPL version 3, you are granted additional 00018 // permissions described in the GCC Runtime Library Exception, version 00019 // 3.1, as published by the Free Software Foundation. 00020 00021 // You should have received a copy of the GNU General Public License and 00022 // a copy of the GCC Runtime Library Exception along with this program; 00023 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00024 // <http://www.gnu.org/licenses/>. 00025 00026 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. 00027 00028 // Permission to use, copy, modify, sell, and distribute this software 00029 // is hereby granted without fee, provided that the above copyright 00030 // notice appears in all copies, and that both that copyright notice and 00031 // this permission notice appear in supporting documentation. None of 00032 // the above authors, nor IBM Haifa Research Laboratories, make any 00033 // representation about the suitability of this software for any 00034 // purpose. It is provided "as is" without express or implied warranty. 00035 00036 /** 00037 * @file ext/typelist.h 00038 * This file is a GNU extension to the Standard C++ Library. 00039 * 00040 * Contains typelist_chain definitions. 00041 * Typelists are an idea by Andrei Alexandrescu. 00042 */ 00043 00044 #ifndef _TYPELIST_H 00045 #define _TYPELIST_H 1 00046 00047 #include <ext/type_traits.h> 00048 00049 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 00050 { 00051 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00052 00053 /** @namespace __gnu_cxx::typelist 00054 * @brief GNU typelist extensions for public compile-time use. 00055 */ 00056 namespace typelist 00057 { 00058 struct null_type { }; 00059 00060 template<typename Root> 00061 struct node 00062 { 00063 typedef Root root; 00064 }; 00065 00066 // Forward declarations of functors. 00067 template<typename Hd, typename Typelist> 00068 struct chain 00069 { 00070 typedef Hd head; 00071 typedef Typelist tail; 00072 }; 00073 00074 // Apply all typelist types to unary functor. 00075 template<typename Fn, typename Typelist> 00076 void 00077 apply(Fn&, Typelist); 00078 00079 /// Apply all typelist types to generator functor. 00080 template<typename Gn, typename Typelist> 00081 void 00082 apply_generator(Gn&, Typelist); 00083 00084 // Apply all typelist types and values to generator functor. 00085 template<typename Gn, typename TypelistT, typename TypelistV> 00086 void 00087 apply_generator(Gn&, TypelistT, TypelistV); 00088 00089 template<typename Typelist0, typename Typelist1> 00090 struct append; 00091 00092 template<typename Typelist_Typelist> 00093 struct append_typelist; 00094 00095 template<typename Typelist, typename T> 00096 struct contains; 00097 00098 template<typename Typelist, template<typename T> class Pred> 00099 struct filter; 00100 00101 template<typename Typelist, int i> 00102 struct at_index; 00103 00104 template<typename Typelist, template<typename T> class Transform> 00105 struct transform; 00106 00107 template<typename Typelist_Typelist> 00108 struct flatten; 00109 00110 template<typename Typelist> 00111 struct from_first; 00112 00113 template<typename T1> 00114 struct create1; 00115 00116 template<typename T1, typename T2> 00117 struct create2; 00118 00119 template<typename T1, typename T2, typename T3> 00120 struct create3; 00121 00122 template<typename T1, typename T2, typename T3, typename T4> 00123 struct create4; 00124 00125 template<typename T1, typename T2, typename T3, typename T4, typename T5> 00126 struct create5; 00127 00128 template<typename T1, typename T2, typename T3, 00129 typename T4, typename T5, typename T6> 00130 struct create6; 00131 } // namespace typelist 00132 00133 _GLIBCXX_END_NAMESPACE_VERSION 00134 } // namespace 00135 00136 00137 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 00138 { 00139 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00140 00141 namespace typelist 00142 { 00143 namespace detail 00144 { 00145 template<typename Fn, typename Typelist_Chain> 00146 struct apply_; 00147 00148 template<typename Fn, typename Hd, typename Tl> 00149 struct apply_<Fn, chain<Hd, Tl> > 00150 { 00151 void 00152 operator()(Fn& f) 00153 { 00154 f.operator()(Hd()); 00155 apply_<Fn, Tl> next; 00156 next(f); 00157 } 00158 }; 00159 00160 template<typename Fn> 00161 struct apply_<Fn, null_type> 00162 { 00163 void 00164 operator()(Fn&) { } 00165 }; 00166 00167 template<typename Gn, typename Typelist_Chain> 00168 struct apply_generator1_; 00169 00170 template<typename Gn, typename Hd, typename Tl> 00171 struct apply_generator1_<Gn, chain<Hd, Tl> > 00172 { 00173 void 00174 operator()(Gn& g) 00175 { 00176 g.template operator()<Hd>(); 00177 apply_generator1_<Gn, Tl> next; 00178 next(g); 00179 } 00180 }; 00181 00182 template<typename Gn> 00183 struct apply_generator1_<Gn, null_type> 00184 { 00185 void 00186 operator()(Gn&) { } 00187 }; 00188 00189 template<typename Gn, typename TypelistT_Chain, typename TypelistV_Chain> 00190 struct apply_generator2_; 00191 00192 template<typename Gn, typename Hd1, typename TlT, typename Hd2, typename TlV> 00193 struct apply_generator2_<Gn, chain<Hd1, TlT>, chain<Hd2, TlV> > 00194 { 00195 void 00196 operator()(Gn& g) 00197 { 00198 g.template operator()<Hd1, Hd2>(); 00199 apply_generator2_<Gn, TlT, TlV> next; 00200 next(g); 00201 } 00202 }; 00203 00204 template<typename Gn> 00205 struct apply_generator2_<Gn, null_type, null_type> 00206 { 00207 void 00208 operator()(Gn&) { } 00209 }; 00210 00211 template<typename Typelist_Chain0, typename Typelist_Chain1> 00212 struct append_; 00213 00214 template<typename Hd, typename Tl, typename Typelist_Chain> 00215 struct append_<chain<Hd, Tl>, Typelist_Chain> 00216 { 00217 private: 00218 typedef append_<Tl, Typelist_Chain> append_type; 00219 00220 public: 00221 typedef chain<Hd, typename append_type::type> type; 00222 }; 00223 00224 template<typename Typelist_Chain> 00225 struct append_<null_type, Typelist_Chain> 00226 { 00227 typedef Typelist_Chain type; 00228 }; 00229 00230 template<typename Typelist_Chain> 00231 struct append_<Typelist_Chain, null_type> 00232 { 00233 typedef Typelist_Chain type; 00234 }; 00235 00236 template<> 00237 struct append_<null_type, null_type> 00238 { 00239 typedef null_type type; 00240 }; 00241 00242 template<typename Typelist_Typelist_Chain> 00243 struct append_typelist_; 00244 00245 template<typename Hd> 00246 struct append_typelist_<chain<Hd, null_type> > 00247 { 00248 typedef chain<Hd, null_type> type; 00249 }; 00250 00251 template<typename Hd, typename Tl> 00252 struct append_typelist_<chain< Hd, Tl> > 00253 { 00254 private: 00255 typedef typename append_typelist_<Tl>::type rest_type; 00256 00257 public: 00258 typedef typename append<Hd, node<rest_type> >::type::root type; 00259 }; 00260 00261 template<typename Typelist_Chain, typename T> 00262 struct contains_; 00263 00264 template<typename T> 00265 struct contains_<null_type, T> 00266 { 00267 enum 00268 { 00269 value = false 00270 }; 00271 }; 00272 00273 template<typename Hd, typename Tl, typename T> 00274 struct contains_<chain<Hd, Tl>, T> 00275 { 00276 enum 00277 { 00278 value = contains_<Tl, T>::value 00279 }; 00280 }; 00281 00282 template<typename Tl, typename T> 00283 struct contains_<chain<T, Tl>, T> 00284 { 00285 enum 00286 { 00287 value = true 00288 }; 00289 }; 00290 00291 template<typename Typelist_Chain, template<typename T> class Pred> 00292 struct chain_filter_; 00293 00294 template<template<typename T> class Pred> 00295 struct chain_filter_<null_type, Pred> 00296 { 00297 typedef null_type type; 00298 }; 00299 00300 template<typename Hd, typename Tl, template<typename T> class Pred> 00301 struct chain_filter_<chain<Hd, Tl>, Pred> 00302 { 00303 private: 00304 enum 00305 { 00306 include_hd = Pred<Hd>::value 00307 }; 00308 00309 typedef typename chain_filter_<Tl, Pred>::type rest_type; 00310 typedef chain<Hd, rest_type> chain_type; 00311 00312 public: 00313 typedef typename __conditional_type<include_hd, chain_type, rest_type>::__type type; 00314 }; 00315 00316 template<typename Typelist_Chain, int i> 00317 struct chain_at_index_; 00318 00319 template<typename Hd, typename Tl> 00320 struct chain_at_index_<chain<Hd, Tl>, 0> 00321 { 00322 typedef Hd type; 00323 }; 00324 00325 template<typename Hd, typename Tl, int i> 00326 struct chain_at_index_<chain<Hd, Tl>, i> 00327 { 00328 typedef typename chain_at_index_<Tl, i - 1>::type type; 00329 }; 00330 00331 template<class Typelist_Chain, template<typename T> class Transform> 00332 struct chain_transform_; 00333 00334 template<template<typename T> class Transform> 00335 struct chain_transform_<null_type, Transform> 00336 { 00337 typedef null_type type; 00338 }; 00339 00340 template<class Hd, class Tl, template<typename T> class Transform> 00341 struct chain_transform_<chain<Hd, Tl>, Transform> 00342 { 00343 private: 00344 typedef typename chain_transform_<Tl, Transform>::type rest_type; 00345 typedef typename Transform<Hd>::type transform_type; 00346 00347 public: 00348 typedef chain<transform_type, rest_type> type; 00349 }; 00350 00351 template<typename Typelist_Typelist_Chain> 00352 struct chain_flatten_; 00353 00354 template<typename Hd_Tl> 00355 struct chain_flatten_<chain<Hd_Tl, null_type> > 00356 { 00357 typedef typename Hd_Tl::root type; 00358 }; 00359 00360 template<typename Hd_Typelist, class Tl_Typelist> 00361 struct chain_flatten_<chain<Hd_Typelist, Tl_Typelist> > 00362 { 00363 private: 00364 typedef typename chain_flatten_<Tl_Typelist>::type rest_type; 00365 typedef append<Hd_Typelist, node<rest_type> > append_type; 00366 public: 00367 typedef typename append_type::type::root type; 00368 }; 00369 } // namespace detail 00370 } // namespace typelist 00371 00372 _GLIBCXX_END_NAMESPACE_VERSION 00373 } // namespace 00374 00375 #define _GLIBCXX_TYPELIST_CHAIN1(X0) __gnu_cxx::typelist::chain<X0, __gnu_cxx::typelist::null_type> 00376 #define _GLIBCXX_TYPELIST_CHAIN2(X0, X1) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN1(X1) > 00377 #define _GLIBCXX_TYPELIST_CHAIN3(X0, X1, X2) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN2(X1, X2) > 00378 #define _GLIBCXX_TYPELIST_CHAIN4(X0, X1, X2, X3) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN3(X1, X2, X3) > 00379 #define _GLIBCXX_TYPELIST_CHAIN5(X0, X1, X2, X3, X4) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN4(X1, X2, X3, X4) > 00380 #define _GLIBCXX_TYPELIST_CHAIN6(X0, X1, X2, X3, X4, X5) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN5(X1, X2, X3, X4, X5) > 00381 #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) > 00382 #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) > 00383 #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) > 00384 #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) > 00385 #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) > 00386 #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) > 00387 #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) > 00388 #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) > 00389 #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) > 00390 #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) > 00391 #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) > 00392 #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) > 00393 #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) > 00394 #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) > 00395 00396 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 00397 { 00398 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00399 00400 namespace typelist 00401 { 00402 template<typename Fn, typename Typelist> 00403 void 00404 apply(Fn& fn, Typelist) 00405 { 00406 detail::apply_<Fn, typename Typelist::root> a; 00407 a(fn); 00408 } 00409 00410 template<typename Fn, typename Typelist> 00411 void 00412 apply_generator(Fn& fn, Typelist) 00413 { 00414 detail::apply_generator1_<Fn, typename Typelist::root> a; 00415 a(fn); 00416 } 00417 00418 template<typename Fn, typename TypelistT, typename TypelistV> 00419 void 00420 apply_generator(Fn& fn, TypelistT, TypelistV) 00421 { 00422 typedef typename TypelistT::root rootT; 00423 typedef typename TypelistV::root rootV; 00424 detail::apply_generator2_<Fn, rootT, rootV> a; 00425 a(fn); 00426 } 00427 00428 template<typename Typelist0, typename Typelist1> 00429 struct append 00430 { 00431 private: 00432 typedef typename Typelist0::root root0_type; 00433 typedef typename Typelist1::root root1_type; 00434 typedef detail::append_<root0_type, root1_type> append_type; 00435 00436 public: 00437 typedef node<typename append_type::type> type; 00438 }; 00439 00440 template<typename Typelist_Typelist> 00441 struct append_typelist 00442 { 00443 private: 00444 typedef typename Typelist_Typelist::root root_type; 00445 typedef detail::append_typelist_<root_type> append_type; 00446 00447 public: 00448 typedef node<typename append_type::type> type; 00449 }; 00450 00451 template<typename Typelist, typename T> 00452 struct contains 00453 { 00454 private: 00455 typedef typename Typelist::root root_type; 00456 00457 public: 00458 enum 00459 { 00460 value = detail::contains_<root_type, T>::value 00461 }; 00462 }; 00463 00464 template<typename Typelist, template<typename T> class Pred> 00465 struct filter 00466 { 00467 private: 00468 typedef typename Typelist::root root_type; 00469 typedef detail::chain_filter_<root_type, Pred> filter_type; 00470 00471 public: 00472 typedef node<typename filter_type::type> type; 00473 }; 00474 00475 template<typename Typelist, int i> 00476 struct at_index 00477 { 00478 private: 00479 typedef typename Typelist::root root_type; 00480 typedef detail::chain_at_index_<root_type, i> index_type; 00481 00482 public: 00483 typedef typename index_type::type type; 00484 }; 00485 00486 template<typename Typelist, template<typename T> class Transform> 00487 struct transform 00488 { 00489 private: 00490 typedef typename Typelist::root root_type; 00491 typedef detail::chain_transform_<root_type, Transform> transform_type; 00492 00493 public: 00494 typedef node<typename transform_type::type> type; 00495 }; 00496 00497 template<typename Typelist_Typelist> 00498 struct flatten 00499 { 00500 private: 00501 typedef typename Typelist_Typelist::root root_type; 00502 typedef typename detail::chain_flatten_<root_type>::type flatten_type; 00503 00504 public: 00505 typedef node<flatten_type> type; 00506 }; 00507 00508 template<typename Typelist> 00509 struct from_first 00510 { 00511 private: 00512 typedef typename at_index<Typelist, 0>::type first_type; 00513 00514 public: 00515 typedef node<chain<first_type, null_type> > type; 00516 }; 00517 00518 template<typename T1> 00519 struct create1 00520 { 00521 typedef node<_GLIBCXX_TYPELIST_CHAIN1(T1)> type; 00522 }; 00523 00524 template<typename T1, typename T2> 00525 struct create2 00526 { 00527 typedef node<_GLIBCXX_TYPELIST_CHAIN2(T1,T2)> type; 00528 }; 00529 00530 template<typename T1, typename T2, typename T3> 00531 struct create3 00532 { 00533 typedef node<_GLIBCXX_TYPELIST_CHAIN3(T1,T2,T3)> type; 00534 }; 00535 00536 template<typename T1, typename T2, typename T3, typename T4> 00537 struct create4 00538 { 00539 typedef node<_GLIBCXX_TYPELIST_CHAIN4(T1,T2,T3,T4)> type; 00540 }; 00541 00542 template<typename T1, typename T2, typename T3, 00543 typename T4, typename T5> 00544 struct create5 00545 { 00546 typedef node<_GLIBCXX_TYPELIST_CHAIN5(T1,T2,T3,T4,T5)> type; 00547 }; 00548 00549 template<typename T1, typename T2, typename T3, 00550 typename T4, typename T5, typename T6> 00551 struct create6 00552 { 00553 typedef node<_GLIBCXX_TYPELIST_CHAIN6(T1,T2,T3,T4,T5,T6)> type; 00554 }; 00555 } // namespace typelist 00556 _GLIBCXX_END_NAMESPACE_VERSION 00557 } // namespace 00558 00559 00560 #endif