typelist.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // Copyright (C) 2005, 2006 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 2, 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 // You should have received a copy of the GNU General Public License along
00017 // with this library; see the file COPYING.  If not, write to the Free
00018 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00019 // USA.
00020 
00021 // As a special exception, you may use this file as part of a free software
00022 // library without restriction.  Specifically, if other files instantiate
00023 // templates or use macros or inline functions from this file, or you compile
00024 // this file and link it with other files to produce an executable, this
00025 // file does not by itself cause the resulting executable to be covered by
00026 // the GNU General Public License.  This exception does not however
00027 // invalidate any other reasons why the executable file might be covered by
00028 // the GNU General Public License.
00029 
00030 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
00031 
00032 // Permission to use, copy, modify, sell, and distribute this software
00033 // is hereby granted without fee, provided that the above copyright
00034 // notice appears in all copies, and that both that copyright notice and
00035 // this permission notice appear in supporting documentation. None of
00036 // the above authors, nor IBM Haifa Research Laboratories, make any
00037 // representation about the suitability of this software for any
00038 // purpose. It is provided "as is" without express or implied warranty.
00039 
00040 /**
00041  * @file typelist.h
00042  * Contains typelist_chain definitions.
00043  * Typelists are an idea by Andrei Alexandrescu.
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   // Forward declarations of functors.
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 } // namespace typelist
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 } // namespace detail
00309 } // namespace typelist
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 } // namespace typelist
00469 _GLIBCXX_END_NAMESPACE
00470 
00471 
00472 #endif
00473 

Generated on Thu Nov 1 13:12:47 2007 for libstdc++ by  doxygen 1.5.1