dune-common  2.2.0
tupleutility.hh
Go to the documentation of this file.
00001 // -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
00002 // vi: set ts=8 sw=2 et sts=2:
00003 
00004 #ifndef DUNE_TUPLE_UTILITY_HH
00005 #define DUNE_TUPLE_UTILITY_HH
00006 
00007 #include <cstddef>
00008 
00009 #include <dune/common/static_assert.hh>
00010 #include <dune/common/typetraits.hh>
00011 
00012 #include "tuples.hh"
00013 
00014 namespace Dune {
00015 
00033   template <class Tuple>
00034   class NullPointerInitialiser {
00035     dune_static_assert(AlwaysFalse<Tuple>::value, "Attempt to use the "
00036                        "unspecialized version of NullPointerInitialiser.  "
00037                        "NullPointerInitialiser needs to be specialized for "
00038                        "each possible tuple size.  Naturally the number of "
00039                        "pre-defined specializations is limited arbitrarily.  "
00040                        "Maybe you need to raise this limit by defining some "
00041                        "more specializations?  Also check that the tuple this "
00042                        "is applied to really is a tuple of pointers only.");
00043   public:
00045     typedef Tuple ResultType;
00047     static ResultType apply();
00048   };
00049 
00050 #ifndef DOXYGEN
00051   template<class Tuple>
00052   struct NullPointerInitialiser<const Tuple>
00053     : public NullPointerInitialiser<Tuple>
00054   {
00055     typedef const Tuple ResultType;
00056   };
00057 
00058   template<>
00059   struct NullPointerInitialiser<tuple<> > {
00060     typedef tuple<> ResultType;
00061     static ResultType apply() {
00062       return ResultType();
00063     }
00064   };
00065 
00066   template<class T0>
00067   struct NullPointerInitialiser<tuple<T0*> > {
00068     typedef tuple<T0*> ResultType;
00069     static ResultType apply() {
00070       return ResultType(static_cast<T0*>(0));
00071     }
00072   };
00073 
00074   template<class T0, class T1>
00075   struct NullPointerInitialiser<tuple<T0*, T1*> > {
00076     typedef tuple<T0*, T1*> ResultType;
00077     static ResultType apply() {
00078       return ResultType(static_cast<T0*>(0), static_cast<T1*>(0));
00079     }
00080   };
00081 
00082   template<class T0, class T1, class T2>
00083   struct NullPointerInitialiser<tuple<T0*, T1*, T2*> > {
00084     typedef tuple<T0*, T1*, T2*> ResultType;
00085     static ResultType apply() {
00086       return ResultType(static_cast<T0*>(0), static_cast<T1*>(0),
00087                         static_cast<T2*>(0));
00088     }
00089   };
00090 
00091   template<class T0, class T1, class T2, class T3>
00092   struct NullPointerInitialiser<tuple<T0*, T1*, T2*, T3*> > {
00093     typedef tuple<T0*, T1*, T2*, T3*> ResultType;
00094     static ResultType apply() {
00095       return ResultType(static_cast<T0*>(0), static_cast<T1*>(0),
00096                         static_cast<T2*>(0), static_cast<T3*>(0));
00097     }
00098   };
00099 
00100   template<class T0, class T1, class T2, class T3, class T4>
00101   struct NullPointerInitialiser<tuple<T0*, T1*, T2*, T3*, T4*> > {
00102     typedef tuple<T0*, T1*, T2*, T3*, T4*> ResultType;
00103     static ResultType apply() {
00104       return ResultType(static_cast<T0*>(0), static_cast<T1*>(0),
00105                         static_cast<T2*>(0), static_cast<T3*>(0),
00106                         static_cast<T4*>(0));
00107     }
00108   };
00109 
00110   template<class T0, class T1, class T2, class T3, class T4, class T5>
00111   struct NullPointerInitialiser<tuple<T0*, T1*, T2*, T3*, T4*, T5*> > {
00112     typedef tuple<T0*, T1*, T2*, T3*, T4*, T5*> ResultType;
00113     static ResultType apply() {
00114       return ResultType(static_cast<T0*>(0), static_cast<T1*>(0),
00115                         static_cast<T2*>(0), static_cast<T3*>(0),
00116                         static_cast<T4*>(0), static_cast<T5*>(0));
00117     }
00118   };
00119 
00120   template<class T0, class T1, class T2, class T3, class T4, class T5,
00121            class T6>
00122   struct NullPointerInitialiser<tuple<T0*, T1*, T2*, T3*, T4*, T5*, T6*> > {
00123     typedef tuple<T0*, T1*, T2*, T3*, T4*, T5*, T6*> ResultType;
00124     static ResultType apply() {
00125       return ResultType(static_cast<T0*>(0), static_cast<T1*>(0),
00126                         static_cast<T2*>(0), static_cast<T3*>(0),
00127                         static_cast<T4*>(0), static_cast<T5*>(0),
00128                         static_cast<T6*>(0));
00129     }
00130   };
00131 
00132   template<class T0, class T1, class T2, class T3, class T4, class T5,
00133            class T6, class T7>
00134   struct NullPointerInitialiser<tuple<T0*, T1*, T2*, T3*, T4*, T5*, T6*,
00135                                       T7*> > {
00136     typedef tuple<T0*, T1*, T2*, T3*, T4*, T5*, T6*, T7*> ResultType;
00137     static ResultType apply() {
00138       return ResultType(static_cast<T0*>(0), static_cast<T1*>(0),
00139                         static_cast<T2*>(0), static_cast<T3*>(0),
00140                         static_cast<T4*>(0), static_cast<T5*>(0),
00141                         static_cast<T6*>(0), static_cast<T7*>(0));
00142     }
00143   };
00144 
00145   template<class T0, class T1, class T2, class T3, class T4, class T5,
00146            class T6, class T7, class T8>
00147   struct NullPointerInitialiser<tuple<T0*, T1*, T2*, T3*, T4*, T5*, T6*,
00148                                       T7*, T8*> > {
00149     typedef tuple<T0*, T1*, T2*, T3*, T4*, T5*, T6*, T7*, T8*> ResultType;
00150     static ResultType apply() {
00151       return ResultType(static_cast<T0*>(0), static_cast<T1*>(0),
00152                         static_cast<T2*>(0), static_cast<T3*>(0),
00153                         static_cast<T4*>(0), static_cast<T5*>(0),
00154                         static_cast<T6*>(0), static_cast<T7*>(0),
00155                         static_cast<T8*>(0));
00156     }
00157   };
00158 
00159   // template<class T0, class T1, class T2, class T3, class T4, class T5,
00160   //          class T6, class T7, class T8, class T9>
00161   // struct NullPointerInitialiser<tuple<T0*, T1*, T2*, T3*, T4*, T5*, T6*,
00162   //                                     T7*, T8*, T9*> > {
00163   //   typedef tuple<T0*, T1*, T2*, T3*, T4*, T5*, T6*, T7*, T8*, T9*> ResultType;
00164   //   static ResultType apply() {
00165   //     return ResultType(static_cast<T0*>(0), static_cast<T1*>(0),
00166   //                       static_cast<T2*>(0), static_cast<T3*>(0),
00167   //                       static_cast<T4*>(0), static_cast<T5*>(0),
00168   //                       static_cast<T6*>(0), static_cast<T7*>(0),
00169   //                       static_cast<T8*>(0), static_cast<T9*>(0));
00170   //   }
00171   // };
00172 #endif // !defined(DOXYGEN)
00173   
00195   template <template <class> class TypeEvaluator, class TupleType>
00196   class ForEachType {
00197     dune_static_assert(AlwaysFalse<TupleType>::value, "Attempt to use the "
00198                        "unspecialized version of ForEachType.  ForEachType "
00199                        "needs to be specialized for each possible tuple "
00200                        "size.  Naturally the number of pre-defined "
00201                        "specializations is limited arbitrarily.  Maybe you "
00202                        "need to raise this limit by defining some more "
00203                        "specializations?");
00204     struct ImplementationDefined {};
00205   public:
00207     typedef ImplementationDefined Type;
00208   };
00209 
00210 #ifndef DOXYGEN
00211   template <template <class> class TE, class Tuple>
00212   struct ForEachType<TE, const Tuple> {
00213     typedef const typename ForEachType<TE, Tuple>::Type Type;
00214   };
00215 
00216   template <template <class> class TE>
00217   struct ForEachType<TE, tuple<> > {
00218     typedef tuple<> Type;
00219   };
00220 
00221   template <template <class> class TE, class T0>
00222   struct ForEachType<TE, tuple<T0> > {
00223     typedef tuple<typename TE<T0>::Type> Type;
00224   };
00225 
00226   template <template <class> class TE, class T0, class T1>
00227   struct ForEachType<TE, tuple<T0, T1> > {
00228     typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type> Type;
00229   };
00230 
00231   template <template <class> class TE, class T0, class T1, class T2>
00232   struct ForEachType<TE, tuple<T0, T1, T2> > {
00233     typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
00234                   typename TE<T2>::Type> Type;
00235   };
00236 
00237   template <template <class> class TE, class T0, class T1, class T2, class T3>
00238   struct ForEachType<TE, tuple<T0, T1, T2, T3> > {
00239     typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
00240                   typename TE<T2>::Type, typename TE<T3>::Type> Type;
00241   };
00242 
00243   template <template <class> class TE, class T0, class T1, class T2, class T3,
00244             class T4>
00245   struct ForEachType<TE, tuple<T0, T1, T2, T3, T4> > {
00246     typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
00247                   typename TE<T2>::Type, typename TE<T3>::Type,
00248                   typename TE<T4>::Type> Type;
00249   };
00250 
00251   template <template <class> class TE, class T0, class T1, class T2, class T3,
00252             class T4, class T5>
00253   struct ForEachType<TE, tuple<T0, T1, T2, T3, T4, T5> > {
00254     typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
00255                   typename TE<T2>::Type, typename TE<T3>::Type,
00256                   typename TE<T4>::Type, typename TE<T5>::Type> Type;
00257   };
00258 
00259   template <template <class> class TE, class T0, class T1, class T2, class T3,
00260             class T4, class T5, class T6>
00261   struct ForEachType<TE, tuple<T0, T1, T2, T3, T4, T5, T6> > {
00262     typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
00263                   typename TE<T2>::Type, typename TE<T3>::Type,
00264                   typename TE<T4>::Type, typename TE<T5>::Type,
00265                   typename TE<T6>::Type> Type;
00266   };
00267 
00268   template <template <class> class TE, class T0, class T1, class T2, class T3,
00269             class T4, class T5, class T6, class T7>
00270   struct ForEachType<TE, tuple<T0, T1, T2, T3, T4, T5, T6, T7> > {
00271     typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
00272                   typename TE<T2>::Type, typename TE<T3>::Type,
00273                   typename TE<T4>::Type, typename TE<T5>::Type,
00274                   typename TE<T6>::Type, typename TE<T7>::Type> Type;
00275   };
00276 
00277   template <template <class> class TE, class T0, class T1, class T2, class T3,
00278             class T4, class T5, class T6, class T7, class T8>
00279   struct ForEachType<TE, tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> > {
00280     typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
00281                   typename TE<T2>::Type, typename TE<T3>::Type,
00282                   typename TE<T4>::Type, typename TE<T5>::Type,
00283                   typename TE<T6>::Type, typename TE<T7>::Type,
00284                   typename TE<T8>::Type> Type;
00285   };
00286 
00287   // template <template <class> class TE, class T0, class T1, class T2, class T3,
00288   //           class T4, class T5, class T6, class T7, class T8, class T9>
00289   // struct ForEachType<TE, tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> > {
00290   //   typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
00291   //                 typename TE<T2>::Type, typename TE<T3>::Type,
00292   //                 typename TE<T4>::Type, typename TE<T5>::Type,
00293   //                 typename TE<T6>::Type, typename TE<T7>::Type,
00294   //                 typename TE<T8>::Type, typename TE<T9>::Type> Type;
00295   // };
00296 #endif // !defined(DOXYGEN)
00297 
00299   //
00300   // genericTransformTuple stuff
00301   //
00302 
00303   // genericTransformTuple() needs to be overloaded for each tuple size (we
00304   // limit ourselves to tuple_size <= 10 here).  For a given tuple size it
00305   // needs to be overloaded for all combinations of const and non-const
00306   // argument references.  (On the one hand, we want to allow modifyable
00307   // arguments, so const references alone are not sufficient.  On the other
00308   // hand, we also want to allow rvalues (literals) as argument, which do not
00309   // bind to non-const references.)
00310   //
00311   // We can half the number of specializations required by introducing a
00312   // function genericTransformTupleBackend(), which is overloaded for each
00313   // tuple size and for const and non-const tuple arguments; the functor
00314   // argument is always given as as (non-const) reference.  When
00315   // genericTransformTupleBackend() is called, the type of the Functor template
00316   // parameter is the deduced as either "SomeType" or "const SomeType",
00317   // depending on whether the function argument is a non-const or a const
00318   // lvalue of type "SomeType".  As explained above, this does not work for
00319   // rvalues (i.e. literals).
00320   //
00321   // To make it work for literals of functors as well, we wrap the call to
00322   // genericTransformTupleBackend() in a function genericTransformTuple().
00323   // genericTransformTuple() needs to be overloaded for non-const and const
00324   // tuples and functors -- 4 overloads only.  Inside genericTransformTuple()
00325   // the functor is an lvalue no matter whether the argument was an lvalue or
00326   // an rvalue.  There is no need need to overload genericTransformTuple() for
00327   // all tuple sizes -- this is done by the underlying
00328   // genericTransformTupleBackend().
00329 
00330   // genericTransformTupleBackend() is an implementation detail -- hide it
00331   // from Doxygen
00332 #ifndef DOXYGEN
00333   // 0-element tuple
00334   // This is a special case: we touch neither the tuple nor the functor, so
00335   // const references are sufficient and we don't need to overload
00336   template<class Functor>
00337   typename ForEachType<Functor::template TypeEvaluator,
00338                        tuple<> >::Type
00339   genericTransformTupleBackend
00340   (const tuple<>& t, const Functor& f)
00341   {
00342     return typename ForEachType<Functor::template TypeEvaluator,
00343       tuple<> >::Type
00344       ();
00345   }
00346 
00347   // 1-element tuple
00348   template<class T0, class Functor>
00349   typename ForEachType<Functor::template TypeEvaluator,
00350                        tuple<T0> >::Type
00351   genericTransformTupleBackend
00352   (tuple<T0>& t, Functor& f)
00353   {
00354     return typename ForEachType<Functor::template TypeEvaluator,
00355       tuple<T0> >::Type
00356       (f(get<0>(t)));
00357   }
00358   template<class T0, class Functor>
00359   typename ForEachType<Functor::template TypeEvaluator,
00360                        tuple<T0> >::Type
00361   genericTransformTupleBackend
00362   (const tuple<T0>& t, Functor& f)
00363   {
00364     return typename ForEachType<Functor::template TypeEvaluator,
00365       tuple<T0> >::Type
00366       (f(get<0>(t)));
00367   }
00368 
00369   // 2-element tuple
00370   template<class T0, class T1, class Functor>
00371   typename ForEachType<Functor::template TypeEvaluator,
00372                        tuple<T0, T1> >::Type
00373   genericTransformTupleBackend
00374   (tuple<T0, T1>& t, Functor& f)
00375   {
00376     return typename ForEachType<Functor::template TypeEvaluator,
00377       tuple<T0, T1> >::Type
00378       (f(get<0>(t)), f(get<1>(t)));
00379   }
00380   template<class T0, class T1, class Functor>
00381   typename ForEachType<Functor::template TypeEvaluator,
00382                        tuple<T0, T1> >::Type
00383   genericTransformTupleBackend
00384   (const tuple<T0, T1>& t, Functor& f)
00385   {
00386     return typename ForEachType<Functor::template TypeEvaluator,
00387       tuple<T0, T1> >::Type
00388       (f(get<0>(t)), f(get<1>(t)));
00389   }
00390 
00391   // 3-element tuple
00392   template<class T0, class T1, class T2, class Functor>
00393   typename ForEachType<Functor::template TypeEvaluator,
00394                        tuple<T0, T1, T2> >::Type
00395   genericTransformTupleBackend
00396   (tuple<T0, T1, T2>& t, Functor& f)
00397   {
00398     return typename ForEachType<Functor::template TypeEvaluator,
00399       tuple<T0, T1, T2> >::Type
00400       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)));
00401   }
00402   template<class T0, class T1, class T2, class Functor>
00403   typename ForEachType<Functor::template TypeEvaluator,
00404                        tuple<T0, T1, T2> >::Type
00405   genericTransformTupleBackend
00406   (const tuple<T0, T1, T2>& t, Functor& f)
00407   {
00408     return typename ForEachType<Functor::template TypeEvaluator,
00409       tuple<T0, T1, T2> >::Type
00410       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)));
00411   }
00412 
00413   // 4-element tuple
00414   template<class T0, class T1, class T2, class T3, class Functor>
00415   typename ForEachType<Functor::template TypeEvaluator,
00416                        tuple<T0, T1, T2, T3> >::Type
00417   genericTransformTupleBackend
00418   (tuple<T0, T1, T2, T3>& t, Functor& f)
00419   {
00420     return typename ForEachType<Functor::template TypeEvaluator,
00421       tuple<T0, T1, T2, T3> >::Type
00422       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)));
00423   }
00424   template<class T0, class T1, class T2, class T3, class Functor>
00425   typename ForEachType<Functor::template TypeEvaluator,
00426                        tuple<T0, T1, T2, T3> >::Type
00427   genericTransformTupleBackend
00428   (const tuple<T0, T1, T2, T3>& t, Functor& f)
00429   {
00430     return typename ForEachType<Functor::template TypeEvaluator,
00431       tuple<T0, T1, T2, T3> >::Type
00432       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)));
00433   }
00434 
00435   // 5-element tuple
00436   template<class T0, class T1, class T2, class T3, class T4, class Functor>
00437   typename ForEachType<Functor::template TypeEvaluator,
00438                        tuple<T0, T1, T2, T3, T4> >::Type
00439   genericTransformTupleBackend
00440   (tuple<T0, T1, T2, T3, T4>& t, Functor& f)
00441   {
00442     return typename ForEachType<Functor::template TypeEvaluator,
00443       tuple<T0, T1, T2, T3, T4> >::Type
00444       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)));
00445   }
00446   template<class T0, class T1, class T2, class T3, class T4, class Functor>
00447   typename ForEachType<Functor::template TypeEvaluator,
00448                        tuple<T0, T1, T2, T3, T4> >::Type
00449   genericTransformTupleBackend
00450   (const tuple<T0, T1, T2, T3, T4>& t, Functor& f)
00451   {
00452     return typename ForEachType<Functor::template TypeEvaluator,
00453       tuple<T0, T1, T2, T3, T4> >::Type
00454       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)));
00455   }
00456 
00457   // 6-element tuple
00458   template<class T0, class T1, class T2, class T3, class T4, class T5,
00459            class Functor>
00460   typename ForEachType<Functor::template TypeEvaluator,
00461                        tuple<T0, T1, T2, T3, T4, T5> >::Type
00462   genericTransformTupleBackend
00463   (tuple<T0, T1, T2, T3, T4, T5>& t, Functor& f)
00464   {
00465     return typename ForEachType<Functor::template TypeEvaluator,
00466       tuple<T0, T1, T2, T3, T4, T5> >::Type
00467       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
00468        f(get<5>(t)));
00469   }
00470   template<class T0, class T1, class T2, class T3, class T4, class T5,
00471            class Functor>
00472   typename ForEachType<Functor::template TypeEvaluator,
00473                        tuple<T0, T1, T2, T3, T4, T5> >::Type
00474   genericTransformTupleBackend
00475   (const tuple<T0, T1, T2, T3, T4, T5>& t, Functor& f)
00476   {
00477     return typename ForEachType<Functor::template TypeEvaluator,
00478       tuple<T0, T1, T2, T3, T4, T5> >::Type
00479       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
00480        f(get<5>(t)));
00481   }
00482 
00483   // 7-element tuple
00484   template<class T0, class T1, class T2, class T3, class T4, class T5,
00485            class T6, class Functor>
00486   typename ForEachType<Functor::template TypeEvaluator,
00487                        tuple<T0, T1, T2, T3, T4, T5, T6> >::Type
00488   genericTransformTupleBackend
00489   (tuple<T0, T1, T2, T3, T4, T5, T6>& t, Functor& f)
00490   {
00491     return typename ForEachType<Functor::template TypeEvaluator,
00492       tuple<T0, T1, T2, T3, T4, T5, T6> >::Type
00493       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
00494        f(get<5>(t)), f(get<6>(t)));
00495   }
00496   template<class T0, class T1, class T2, class T3, class T4, class T5,
00497            class T6, class Functor>
00498   typename ForEachType<Functor::template TypeEvaluator,
00499                        tuple<T0, T1, T2, T3, T4, T5, T6> >::Type
00500   genericTransformTupleBackend
00501   (const tuple<T0, T1, T2, T3, T4, T5, T6>& t, Functor& f)
00502   {
00503     return typename ForEachType<Functor::template TypeEvaluator,
00504       tuple<T0, T1, T2, T3, T4, T5, T6> >::Type
00505       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
00506        f(get<5>(t)), f(get<6>(t)));
00507   }
00508 
00509   // 8-element tuple
00510   template<class T0, class T1, class T2, class T3, class T4, class T5,
00511            class T6, class T7, class Functor>
00512   typename ForEachType<Functor::template TypeEvaluator,
00513                        tuple<T0, T1, T2, T3, T4, T5, T6, T7> >::Type
00514   genericTransformTupleBackend
00515   (tuple<T0, T1, T2, T3, T4, T5, T6, T7>& t, Functor& f)
00516   {
00517     return typename ForEachType<Functor::template TypeEvaluator,
00518       tuple<T0, T1, T2, T3, T4, T5, T6, T7> >::Type
00519       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
00520        f(get<5>(t)), f(get<6>(t)), f(get<7>(t)));
00521   }
00522   template<class T0, class T1, class T2, class T3, class T4, class T5,
00523            class T6, class T7, class Functor>
00524   typename ForEachType<Functor::template TypeEvaluator,
00525                        tuple<T0, T1, T2, T3, T4, T5, T6, T7> >::Type
00526   genericTransformTupleBackend
00527   (const tuple<T0, T1, T2, T3, T4, T5, T6, T7>& t, Functor& f)
00528   {
00529     return typename ForEachType<Functor::template TypeEvaluator,
00530       tuple<T0, T1, T2, T3, T4, T5, T6, T7> >::Type
00531       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
00532        f(get<5>(t)), f(get<6>(t)), f(get<7>(t)));
00533   }
00534 
00535   // 9-element tuple
00536   template<class T0, class T1, class T2, class T3, class T4, class T5,
00537            class T6, class T7, class T8, class Functor>
00538   typename ForEachType<Functor::template TypeEvaluator,
00539                        tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> >::Type
00540   genericTransformTupleBackend
00541   (tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8>& t, Functor& f)
00542   {
00543     return typename ForEachType<Functor::template TypeEvaluator,
00544       tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> >::Type
00545       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
00546        f(get<5>(t)), f(get<6>(t)), f(get<7>(t)), f(get<8>(t)));
00547   }
00548   template<class T0, class T1, class T2, class T3, class T4, class T5,
00549            class T6, class T7, class T8, class Functor>
00550   typename ForEachType<Functor::template TypeEvaluator,
00551                        tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> >::Type
00552   genericTransformTupleBackend
00553   (const tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8>& t, Functor& f)
00554   {
00555     return typename ForEachType<Functor::template TypeEvaluator,
00556       tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> >::Type
00557       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
00558        f(get<5>(t)), f(get<6>(t)), f(get<7>(t)), f(get<8>(t)));
00559   }
00560 
00561   // // 10-element tuple
00562   // template<class T0, class T1, class T2, class T3, class T4, class T5,
00563   //          class T6, class T7, class T8, class T9, class Functor>
00564   // typename ForEachType<Functor::template TypeEvaluator,
00565   //                      tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::Type
00566   // genericTransformTupleBackend
00567   // (tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& t, Functor& f)
00568   // {
00569   //   return typename ForEachType<Functor::template TypeEvaluator,
00570   //     tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::Type
00571   //     (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
00572   //      f(get<5>(t)), f(get<6>(t)), f(get<7>(t)), f(get<8>(t)), f(get<9>(t)));
00573   // }
00574   // template<class T0, class T1, class T2, class T3, class T4, class T5,
00575   //          class T6, class T7, class T8, class T9, class Functor>
00576   // typename ForEachType<Functor::template TypeEvaluator,
00577   //                      tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::Type
00578   // genericTransformTupleBackend
00579   // (const tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& t, Functor& f)
00580   // {
00581   //   return typename ForEachType<Functor::template TypeEvaluator,
00582   //     tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::Type
00583   //     (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
00584   //      f(get<5>(t)), f(get<6>(t)), f(get<7>(t)), f(get<8>(t)), f(get<9>(t)));
00585   // }
00586 #endif // ! defined(DOXYGEN)
00587 
00589 
00630   template<class Tuple, class Functor>
00631   typename ForEachType<Functor::template TypeEvaluator, Tuple>::Type
00632   genericTransformTuple(Tuple& t, Functor& f) {
00633     return genericTransformTupleBackend(t, f);
00634   }
00635 #ifndef DOXYGEN
00636   template<class Tuple, class Functor>
00637   typename ForEachType<Functor::template TypeEvaluator, Tuple>::Type
00638   genericTransformTuple(const Tuple& t, Functor& f) {
00639     return genericTransformTupleBackend(t, f);
00640   }
00641   template<class Tuple, class Functor>
00642   typename ForEachType<Functor::template TypeEvaluator, Tuple>::Type
00643   genericTransformTuple(Tuple& t, const Functor& f) {
00644     return genericTransformTupleBackend(t, f);
00645   }
00646   template<class Tuple, class Functor>
00647   typename ForEachType<Functor::template TypeEvaluator, Tuple>::Type
00648   genericTransformTuple(const Tuple& t, const Functor& f) {
00649     return genericTransformTupleBackend(t, f);
00650   }
00651 #endif // ! defined(DOXYGEN)
00652 
00654   //
00655   // transformTuple() related stuff
00656   //
00657 
00659 
00690   template<template<class> class TE, class A0 = void, class A1 = void,
00691            class A2 = void, class A3 = void, class A4 = void, class A5 = void,
00692            class A6 = void, class A7 = void, class A8 = void, class A9 = void>
00693   class TransformTupleFunctor {
00694     A0& a0; A1& a1; A2& a2; A3& a3; A4& a4; A5& a5; A6& a6; A7& a7; A8& a8;
00695     A9& a9;
00696 
00697   public:
00699     template<class T> struct TypeEvaluator : public TE<T> {};
00700 
00702 
00707     TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_, A3& a3_, A4& a4_, A5& a5_,
00708                           A6& a6_, A7& a7_, A8& a8_, A9& a9_)
00709       : a0(a0_), a1(a1_), a2(a2_), a3(a3_), a4(a4_), a5(a5_), a6(a6_), a7(a7_),
00710         a8(a8_), a9(a9_)
00711     { }
00712 
00714 
00722     template<class T>
00723     typename TE<T>::Type operator()(T& t) const {
00724       return TE<T>::apply(t, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
00725     }
00726   };
00727 
00729 
00781   template<template<class> class TE, class A0, class A1, class A2, class A3,
00782            class A4, class A5, class A6, class A7, class A8, class A9>
00783   TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9>
00784   makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
00785                             A6& a6, A7& a7, A8& a8, A9& a9) {
00786     return TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9>
00787       (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
00788   }
00789 
00790 #ifndef DOXYGEN
00791   // 0 argument
00792   template<template<class> class TE>
00793   struct TransformTupleFunctor<TE>
00794   {
00795     template<class T> struct TypeEvaluator : public TE<T> {};
00796 
00797     template<class T>
00798     typename TE<T>::Type operator()(T& t) const {
00799       return TE<T>::apply(t);
00800     }
00801   };
00802   template<template<class> class TE>
00803   TransformTupleFunctor<TE>
00804   makeTransformTupleFunctor() {
00805     return TransformTupleFunctor<TE>
00806       ();
00807   }
00808 
00809   // 1 argument
00810   template<template<class> class TE, class A0>
00811   class TransformTupleFunctor<TE, A0>
00812   {
00813     A0& a0;
00814 
00815   public:
00816     template<class T> struct TypeEvaluator : public TE<T> {};
00817 
00818     TransformTupleFunctor(A0& a0_)
00819       : a0(a0_)
00820     { }
00821 
00822     template<class T>
00823     typename TE<T>::Type operator()(T& t) const {
00824       return TE<T>::apply(t, a0);
00825     }
00826   };
00827   template<template<class> class TE, class A0>
00828   TransformTupleFunctor<TE, A0>
00829   makeTransformTupleFunctor(A0& a0) {
00830     return TransformTupleFunctor<TE, A0>
00831       (a0);
00832   }
00833 
00834   // 2 argument
00835   template<template<class> class TE, class A0, class A1>
00836   class TransformTupleFunctor<TE, A0, A1>
00837   {
00838     A0& a0; A1& a1;
00839 
00840   public:
00841     template<class T> struct TypeEvaluator : public TE<T> {};
00842 
00843     TransformTupleFunctor(A0& a0_, A1& a1_)
00844       : a0(a0_), a1(a1_)
00845     { }
00846 
00847     template<class T>
00848     typename TE<T>::Type operator()(T& t) const {
00849       return TE<T>::apply(t, a0, a1);
00850     }
00851   };
00852   template<template<class> class TE, class A0, class A1>
00853   TransformTupleFunctor<TE, A0, A1>
00854   makeTransformTupleFunctor(A0& a0, A1& a1) {
00855     return TransformTupleFunctor<TE, A0, A1>
00856       (a0, a1);
00857   }
00858 
00859   // 3 arguments
00860   template<template<class> class TE, class A0, class A1, class A2>
00861   class TransformTupleFunctor<TE, A0, A1, A2>
00862   {
00863     A0& a0; A1& a1; A2& a2;
00864 
00865   public:
00866     template<class T> struct TypeEvaluator : public TE<T> {};
00867 
00868     TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_)
00869       : a0(a0_), a1(a1_), a2(a2_)
00870     { }
00871 
00872     template<class T>
00873     typename TE<T>::Type operator()(T& t) const {
00874       return TE<T>::apply(t, a0, a1, a2);
00875     }
00876   };
00877   template<template<class> class TE, class A0, class A1, class A2>
00878   TransformTupleFunctor<TE, A0, A1, A2>
00879   makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2) {
00880     return TransformTupleFunctor<TE, A0, A1, A2>
00881       (a0, a1, a2);
00882   }
00883 
00884   // 4 arguments
00885   template<template<class> class TE, class A0, class A1, class A2, class A3>
00886   class TransformTupleFunctor<TE, A0, A1, A2, A3>
00887   {
00888     A0& a0; A1& a1; A2& a2; A3& a3;
00889 
00890   public:
00891     template<class T> struct TypeEvaluator : public TE<T> {};
00892 
00893     TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_, A3& a3_)
00894       : a0(a0_), a1(a1_), a2(a2_), a3(a3_)
00895     { }
00896 
00897     template<class T>
00898     typename TE<T>::Type operator()(T& t) const {
00899       return TE<T>::apply(t, a0, a1, a2, a3);
00900     }
00901   };
00902   template<template<class> class TE, class A0, class A1, class A2, class A3>
00903   TransformTupleFunctor<TE, A0, A1, A2, A3>
00904   makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2, A3& a3) {
00905     return TransformTupleFunctor<TE, A0, A1, A2, A3>
00906       (a0, a1, a2, a3);
00907   }
00908 
00909   // 5 arguments
00910   template<template<class> class TE, class A0, class A1, class A2, class A3,
00911            class A4>
00912   class TransformTupleFunctor<TE, A0, A1, A2, A3, A4>
00913   {
00914     A0& a0; A1& a1; A2& a2; A3& a3; A4& a4;
00915 
00916   public:
00917     template<class T> struct TypeEvaluator : public TE<T> {};
00918 
00919     TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_, A3& a3_, A4& a4_)
00920       : a0(a0_), a1(a1_), a2(a2_), a3(a3_), a4(a4_)
00921     { }
00922 
00923     template<class T>
00924     typename TE<T>::Type operator()(T& t) const {
00925       return TE<T>::apply(t, a0, a1, a2, a3, a4);
00926     }
00927   };
00928   template<template<class> class TE, class A0, class A1, class A2, class A3,
00929            class A4>
00930   TransformTupleFunctor<TE, A0, A1, A2, A3, A4>
00931   makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4) {
00932     return TransformTupleFunctor<TE, A0, A1, A2, A3, A4>
00933       (a0, a1, a2, a3, a4);
00934   }
00935 
00936   // 6 arguments
00937   template<template<class> class TE, class A0, class A1, class A2, class A3,
00938            class A4, class A5>
00939   class TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5>
00940   {
00941     A0& a0; A1& a1; A2& a2; A3& a3; A4& a4; A5& a5;
00942 
00943   public:
00944     template<class T> struct TypeEvaluator : public TE<T> {};
00945 
00946     TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_, A3& a3_, A4& a4_, A5& a5_)
00947       : a0(a0_), a1(a1_), a2(a2_), a3(a3_), a4(a4_), a5(a5_)
00948     { }
00949 
00950     template<class T>
00951     typename TE<T>::Type operator()(T& t) const {
00952       return TE<T>::apply(t, a0, a1, a2, a3, a4, a5);
00953     }
00954   };
00955   template<template<class> class TE, class A0, class A1, class A2, class A3,
00956            class A4, class A5>
00957   TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5>
00958   makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) {
00959     return TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5>
00960       (a0, a1, a2, a3, a4, a5);
00961   }
00962 
00963   // 7 arguments
00964   template<template<class> class TE, class A0, class A1, class A2, class A3,
00965            class A4, class A5, class A6>
00966   class TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6>
00967   {
00968     A0& a0; A1& a1; A2& a2; A3& a3; A4& a4; A5& a5; A6& a6;
00969 
00970   public:
00971     template<class T> struct TypeEvaluator : public TE<T> {};
00972 
00973     TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_, A3& a3_, A4& a4_, A5& a5_,
00974                           A6& a6_)
00975       : a0(a0_), a1(a1_), a2(a2_), a3(a3_), a4(a4_), a5(a5_), a6(a6_)
00976     { }
00977 
00978     template<class T>
00979     typename TE<T>::Type operator()(T& t) const {
00980       return TE<T>::apply(t, a0, a1, a2, a3, a4, a5, a6);
00981     }
00982   };
00983   template<template<class> class TE, class A0, class A1, class A2, class A3,
00984            class A4, class A5, class A6>
00985   TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6>
00986   makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
00987                             A6& a6) {
00988     return TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6>
00989       (a0, a1, a2, a3, a4, a5, a6);
00990   }
00991 
00992   // 8 arguments
00993   template<template<class> class TE, class A0, class A1, class A2, class A3,
00994            class A4, class A5, class A6, class A7>
00995   class TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7>
00996   {
00997     A0& a0; A1& a1; A2& a2; A3& a3; A4& a4; A5& a5; A6& a6; A7& a7;
00998 
00999   public:
01000     template<class T> struct TypeEvaluator : public TE<T> {};
01001 
01002     TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_, A3& a3_, A4& a4_, A5& a5_,
01003                           A6& a6_, A7& a7_)
01004       : a0(a0_), a1(a1_), a2(a2_), a3(a3_), a4(a4_), a5(a5_), a6(a6_), a7(a7_)
01005     { }
01006 
01007     template<class T>
01008     typename TE<T>::Type operator()(T& t) const {
01009       return TE<T>::apply(t, a0, a1, a2, a3, a4, a5, a6, a7);
01010     }
01011   };
01012   template<template<class> class TE, class A0, class A1, class A2, class A3,
01013            class A4, class A5, class A6, class A7>
01014   TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7>
01015   makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
01016                             A6& a6, A7& a7) {
01017     return TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7>
01018       (a0, a1, a2, a3, a4, a5, a6, a7);
01019   }
01020 
01021   // 9 arguments
01022   template<template<class> class TE, class A0, class A1, class A2, class A3,
01023            class A4, class A5, class A6, class A7, class A8>
01024   class TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7, A8>
01025   {
01026     A0& a0; A1& a1; A2& a2; A3& a3; A4& a4; A5& a5; A6& a6; A7& a7; A8& a8;
01027 
01028   public:
01029     template<class T> struct TypeEvaluator : public TE<T> {};
01030 
01031     TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_, A3& a3_, A4& a4_, A5& a5_,
01032                           A6& a6_, A7& a7_, A8& a8_)
01033       : a0(a0_), a1(a1_), a2(a2_), a3(a3_), a4(a4_), a5(a5_), a6(a6_), a7(a7_),
01034         a8(a8_)
01035     { }
01036 
01037     template<class T>
01038     typename TE<T>::Type operator()(T& t) const {
01039       return TE<T>::apply(t, a0, a1, a2, a3, a4, a5, a6, a7, a8);
01040     }
01041   };
01042   template<template<class> class TE, class A0, class A1, class A2, class A3,
01043            class A4, class A5, class A6, class A7, class A8>
01044   TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7, A8>
01045   makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
01046                             A6& a6, A7& a7, A8& a8) {
01047     return TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7, A8>
01048       (a0, a1, a2, a3, a4, a5, a6, a7, a8);
01049   }
01050 #endif // ! defined(DOXYGEN)
01051 
01053 
01147   template<template<class> class TypeEvaluator, class Tuple, class A0,
01148            class A1, class A2, class A3, class A4, class A5, class A6,
01149            class A7, class A8, class A9>
01150   typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
01151   transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
01152                  A6& a6, A7& a7, A8& a8, A9& a9) {
01153     return genericTransformTuple
01154       ( orig,
01155         makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2, a3, a4, a5, a6,
01156                                                  a7, a8, a9));
01157   }
01158 
01159 #ifndef DOXYGEN
01160   // 0 extra arguments
01161   template<template<class> class TypeEvaluator, class Tuple>
01162   typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
01163   transformTuple(Tuple& orig) {
01164     return genericTransformTuple
01165       ( orig,
01166         makeTransformTupleFunctor<TypeEvaluator>());
01167   }
01168 
01169   // 1 extra argument
01170   template<template<class> class TypeEvaluator, class Tuple, class A0>
01171   typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
01172   transformTuple(Tuple& orig, A0& a0) {
01173     return genericTransformTuple
01174       ( orig,
01175         makeTransformTupleFunctor<TypeEvaluator>(a0));
01176   }
01177 
01178   // 2 extra arguments
01179   template<template<class> class TypeEvaluator, class Tuple, class A0,
01180            class A1>
01181   typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
01182   transformTuple(Tuple& orig, A0& a0, A1& a1) {
01183     return genericTransformTuple
01184       ( orig,
01185         makeTransformTupleFunctor<TypeEvaluator>(a0, a1));
01186   }
01187 
01188   // 3 extra arguments
01189   template<template<class> class TypeEvaluator, class Tuple, class A0,
01190            class A1, class A2>
01191   typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
01192   transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2) {
01193     return genericTransformTuple
01194       ( orig,
01195         makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2));
01196   }
01197 
01198   // 4 extra arguments
01199   template<template<class> class TypeEvaluator, class Tuple, class A0,
01200            class A1, class A2, class A3>
01201   typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
01202   transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2, A3& a3) {
01203     return genericTransformTuple
01204       ( orig,
01205         makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2, a3));
01206   }
01207 
01208   // 5 extra arguments
01209   template<template<class> class TypeEvaluator, class Tuple, class A0,
01210            class A1, class A2, class A3, class A4>
01211   typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
01212   transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2, A3& a3, A4& a4) {
01213     return genericTransformTuple
01214       ( orig,
01215         makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2, a3, a4));
01216   }
01217 
01218   // 6 extra arguments
01219   template<template<class> class TypeEvaluator, class Tuple, class A0,
01220            class A1, class A2, class A3, class A4, class A5>
01221   typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
01222   transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) {
01223     return genericTransformTuple
01224       ( orig,
01225         makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2, a3, a4, a5));
01226   }
01227 
01228   // 7 extra arguments
01229   template<template<class> class TypeEvaluator, class Tuple, class A0,
01230            class A1, class A2, class A3, class A4, class A5, class A6>
01231   typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
01232   transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
01233                  A6& a6) {
01234     return genericTransformTuple
01235       ( orig,
01236         makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2, a3, a4, a5, a6));
01237   }
01238 
01239   // 8 extra arguments
01240   template<template<class> class TypeEvaluator, class Tuple, class A0,
01241            class A1, class A2, class A3, class A4, class A5, class A6,
01242            class A7>
01243   typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
01244   transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
01245                  A6& a6, A7& a7) {
01246     return genericTransformTuple
01247       ( orig,
01248         makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2, a3, a4, a5, a6,
01249                                                  a7));
01250   }
01251 
01252   // 9 extra arguments
01253   template<template<class> class TypeEvaluator, class Tuple, class A0,
01254            class A1, class A2, class A3, class A4, class A5, class A6,
01255            class A7, class A8>
01256   typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
01257   transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
01258                  A6& a6, A7& a7, A8& a8) {
01259     return genericTransformTuple
01260       ( orig,
01261         makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2, a3, a4, a5, a6,
01262                                                  a7, a8));
01263   }
01264 #endif // not defined(DOXYGEN)
01265 
01267   //
01268   // Sample TypeEvaluators
01269   //
01270 
01272 
01276   template<class T>
01277   struct AddRefTypeEvaluator {
01278     typedef T& Type;
01279     static Type apply(T& t) { return t; }
01280   };
01281 
01283 
01287   template<class T>
01288   struct AddPtrTypeEvaluator {
01289     typedef typename remove_reference<T>::type* Type;
01290     static Type apply(T& t) { return &t; }
01291   };
01292 
01293   // Specialization, in case the type is already a reference
01294   template<class T>
01295   struct AddPtrTypeEvaluator<T&> {
01296     typedef typename remove_reference<T>::type* Type;
01297     static Type apply(T& t) { return &t; }
01298   };
01299 
01300   namespace
01301   {
01302     template<int i, typename T1,typename F>
01303     struct Visitor
01304     {
01305       static inline void visit(F& func, T1& t1)
01306       {
01307         func.visit(get<tuple_size<T1>::value-i>(t1));
01308         Visitor<i-1,T1,F>::visit(func, t1);
01309       }
01310     };
01311         
01312     template<typename T1,typename F>
01313     struct Visitor<0,T1,F>
01314     {
01315       static inline void visit(F& func, T1& t1)
01316       {}
01317     };
01318 
01319     template<int i, typename T1, typename T2,typename F>
01320     struct PairVisitor
01321     {
01322       static inline void visit(F& func, T1& t1, T2& t2)
01323       {
01324         func.visit(get<tuple_size<T1>::value-i>(t1), get<tuple_size<T2>::value-i>(t2));
01325         PairVisitor<i-1,T1,T2,F>::visit(func, t1, t2);
01326       }
01327     };
01328         
01329     template<typename T1, typename T2, typename F>
01330     struct PairVisitor<0,T1,T2,F>
01331     {
01332       static inline void visit(F& func, T1& t1, T2& t2)
01333       {}
01334     };
01335   }
01336   
01371   template <class TupleType>
01372   class ForEachValue {
01373   public:
01376     ForEachValue(TupleType& tuple) : tuple_(tuple) {}
01377     
01380     template <class Functor>
01381     void apply(Functor& f) const {
01382       Visitor<tuple_size<TupleType>::value,TupleType,Functor>::visit(f, tuple_);
01383     }
01384   private:
01385     TupleType& tuple_;
01386   };
01387 
01388   //- Definition ForEachValuePair class
01389   // Assertion: both tuples have the same length and the contained types are
01390   // compatible in the sense of the applied function object
01404   template <class TupleType1, class TupleType2>
01405   class ForEachValuePair {
01406   public:
01410     ForEachValuePair(TupleType1& t1, TupleType2& t2) :
01411       tuple1_(t1),
01412       tuple2_(t2)
01413     {}
01414 
01417     template <class Functor>
01418     void apply(Functor& f) {
01419       PairVisitor<tuple_size<TupleType1>::value,TupleType1,TupleType2,Functor>
01420         ::visit(f, tuple1_, tuple2_);
01421     }
01422   private:
01423     TupleType1& tuple1_;
01424     TupleType2& tuple2_;
01425   };
01426 
01427   //- Reverse element access
01433   template <int N, class Tuple>
01434   struct AtType {
01435     typedef typename tuple_element<tuple_size<Tuple>::value - N - 1,
01436                                    Tuple>::type Type;
01437   };
01438   
01446   template <int N>
01447   struct At 
01448   {
01449 
01450     template<typename Tuple>
01451     static
01452     typename TupleAccessTraits<typename AtType<N, Tuple>::Type>::NonConstType
01453     get(Tuple& t)
01454     {
01455       return Dune::get<tuple_size<Tuple>::value - N - 1>(t);
01456     }
01457     
01458     template<typename Tuple>
01459     static
01460     typename TupleAccessTraits<typename AtType<N, Tuple>::Type>::ConstType
01461     get(const Tuple& t)
01462     {
01463       return Dune::get<tuple_size<Tuple>::value - N - 1>(t);
01464     }
01465   };
01466 
01473   template <class Tuple>
01474   class PointerPairDeletor
01475   {
01476     struct Deletor {
01477       template<typename P> void visit(const P& p) { delete p; }
01478     };
01479 
01480   public:
01481     static void apply(Tuple& t) {
01482       static Deletor deletor;
01483       ForEachValue<Tuple>(t).apply(deletor);
01484     }
01485   };
01486 
01487 
01511   template<class Tuple, template<class> class Predicate, std::size_t start = 0,
01512            std::size_t size = tuple_size<Tuple>::value>
01513   class FirstPredicateIndex :
01514     public SelectType<Predicate<typename tuple_element<start,
01515                                                        Tuple>::type>::value,
01516                       integral_constant<std::size_t, start>,
01517                       FirstPredicateIndex<Tuple, Predicate, start+1> >::Type
01518   {
01519     dune_static_assert(tuple_size<Tuple>::value == size, "The \"size\" "
01520                        "template parameter of FirstPredicateIndex is an "
01521                        "implementation detail and should never be set "
01522                        "explicitly!");
01523   };
01524 
01525 #ifndef DOXYGEN
01526   template<class Tuple, template<class> class Predicate, std::size_t size>
01527   class FirstPredicateIndex<Tuple, Predicate, size, size>
01528   {
01529     dune_static_assert(AlwaysFalse<Tuple>::value, "None of the tuple element "
01530                        "types matches the predicate!");
01531   };
01532 #endif // !DOXYGEN
01533 
01543   template<class T>
01544   struct IsType {
01546     template<class U>
01547     struct Predicate : public is_same<T, U> {};
01548   };
01549 
01563   template<class Tuple, class T, std::size_t start = 0>
01564   struct FirstTypeIndex :
01565     public FirstPredicateIndex<Tuple, IsType<T>::template Predicate, start>
01566   { };
01567 
01568 
01569 
01587   template< class Tuple, class T>
01588   struct PushBackTuple
01589   {
01590     dune_static_assert(AlwaysFalse<Tuple>::value, "Attempt to use the "
01591                        "unspecialized version of PushBackTuple.  "
01592                        "PushBackTuple needs to be specialized for "
01593                        "each possible tuple size.  Naturally the number of "
01594                        "pre-defined specializations is limited arbitrarily.  "
01595                        "Maybe you need to raise this limit by defining some "
01596                        "more specializations?");
01597 
01604     typedef Tuple type;
01605   };
01606 
01607 
01608 #ifndef DOXYGEN
01609 
01610   template<class T>
01611   struct PushBackTuple< Dune::tuple<>, T>
01612   {
01613     typedef typename Dune::tuple<T> type;
01614   };
01615 
01616   template< class T1, class T>
01617   struct PushBackTuple< Dune::tuple<T1>, T>
01618   {
01619     typedef typename Dune::tuple<T1, T> type;
01620   };
01621 
01622   template< class T1, class T2, class T>
01623   struct PushBackTuple< Dune::tuple<T1, T2>, T>
01624   {
01625     typedef typename Dune::tuple<T1, T2, T> type;
01626   };
01627 
01628   template< class T1, class T2, class T3, class T>
01629   struct PushBackTuple< Dune::tuple<T1, T2, T3>, T>
01630   {
01631     typedef typename Dune::tuple<T1, T2, T3, T> type;
01632   };
01633 
01634   template< class T1, class T2, class T3, class T4, class T>
01635   struct PushBackTuple< Dune::tuple<T1, T2, T3, T4>, T>
01636   {
01637     typedef typename Dune::tuple<T1, T2, T3, T4, T> type;
01638   };
01639 
01640   template< class T1, class T2, class T3, class T4, class T5, class T>
01641   struct PushBackTuple< Dune::tuple<T1, T2, T3, T4, T5>, T>
01642   {
01643     typedef typename Dune::tuple<T1, T2, T3, T4, T5, T> type;
01644   };
01645 
01646   template< class T1, class T2, class T3, class T4, class T5, class T6, class T>
01647   struct PushBackTuple< Dune::tuple<T1, T2, T3, T4, T5, T6>, T>
01648   {
01649     typedef typename Dune::tuple<T1, T2, T3, T4, T5, T6, T> type;
01650   };
01651 
01652   template< class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T>
01653   struct PushBackTuple< Dune::tuple<T1, T2, T3, T4, T5, T6, T7>, T>
01654   {
01655     typedef typename Dune::tuple<T1, T2, T3, T4, T5, T6, T7, T> type;
01656   };
01657 
01658   template< class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T>
01659   struct PushBackTuple< Dune::tuple<T1, T2, T3, T4, T5, T6, T7, T8>, T>
01660   {
01661     typedef typename Dune::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T> type;
01662   };
01663 
01664 #endif
01665 
01666 
01667 
01685   template< class Tuple, class T>
01686   struct PushFrontTuple
01687   {
01688     dune_static_assert(AlwaysFalse<Tuple>::value, "Attempt to use the "
01689                        "unspecialized version of PushFrontTuple.  "
01690                        "PushFrontTuple needs to be specialized for "
01691                        "each possible tuple size.  Naturally the number of "
01692                        "pre-defined specializations is limited arbitrarily.  "
01693                        "Maybe you need to raise this limit by defining some "
01694                        "more specializations?");
01695 
01702     typedef Tuple type;
01703   };
01704 
01705 
01706 #ifndef DOXYGEN
01707 
01708   template<class T>
01709   struct PushFrontTuple< Dune::tuple<>, T>
01710   {
01711     typedef typename Dune::tuple<T> type;
01712   };
01713 
01714   template< class T1, class T>
01715   struct PushFrontTuple< Dune::tuple<T1>, T>
01716   {
01717     typedef typename Dune::tuple<T, T1> type;
01718   };
01719 
01720   template< class T1, class T2, class T>
01721   struct PushFrontTuple< Dune::tuple<T1, T2>, T>
01722   {
01723     typedef typename Dune::tuple<T, T1, T2> type;
01724   };
01725 
01726   template< class T1, class T2, class T3, class T>
01727   struct PushFrontTuple< Dune::tuple<T1, T2, T3>, T>
01728   {
01729     typedef typename Dune::tuple<T, T1, T2, T3> type;
01730   };
01731 
01732   template< class T1, class T2, class T3, class T4, class T>
01733   struct PushFrontTuple< Dune::tuple<T1, T2, T3, T4>, T>
01734   {
01735     typedef typename Dune::tuple<T, T1, T2, T3, T4> type;
01736   };
01737 
01738   template< class T1, class T2, class T3, class T4, class T5, class T>
01739   struct PushFrontTuple< Dune::tuple<T1, T2, T3, T4, T5>, T>
01740   {
01741     typedef typename Dune::tuple<T, T1, T2, T3, T4, T5> type;
01742   };
01743 
01744   template< class T1, class T2, class T3, class T4, class T5, class T6, class T>
01745   struct PushFrontTuple< Dune::tuple<T1, T2, T3, T4, T5, T6>, T>
01746   {
01747     typedef typename Dune::tuple<T, T1, T2, T3, T4, T5, T6> type;
01748   };
01749 
01750   template< class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T>
01751   struct PushFrontTuple< Dune::tuple<T1, T2, T3, T4, T5, T6, T7>, T>
01752   {
01753     typedef typename Dune::tuple<T, T1, T2, T3, T4, T5, T6, T7> type;
01754   };
01755 
01756   template< class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T>
01757   struct PushFrontTuple< Dune::tuple<T1, T2, T3, T4, T5, T6, T7, T8>, T>
01758   {
01759     typedef typename Dune::tuple<T, T1, T2, T3, T4, T5, T6, T7, T8> type;
01760   };
01761 
01762 #endif
01763 
01764 
01765 
01778   template<
01779     template <class, class> class F,
01780     class Tuple,
01781     class Seed=tuple<>,
01782     int N=tuple_size<Tuple>::value>
01783   struct ReduceTuple
01784   {
01785     typedef typename ReduceTuple<F, Tuple, Seed, N-1>::type Accumulated;
01786     typedef typename tuple_element<N-1, Tuple>::type Value;
01787 
01789     typedef typename F<Accumulated, Value>::type type;
01790   };
01791 
01802   template<
01803     template <class, class> class F,
01804     class Tuple,
01805     class Seed>
01806   struct ReduceTuple<F, Tuple, Seed, 0>
01807   {
01809     typedef Seed type;
01810   };
01811 
01812 
01813 
01823   template<class Head, class Tail>
01824   struct JoinTuples
01825   {
01827     typedef typename ReduceTuple< PushBackTuple, Tail, Head>::type type;
01828   };
01829 
01830 
01831 
01840   template<class TupleTuple>
01841   struct FlattenTuple
01842   {
01844     typedef typename ReduceTuple< JoinTuples, TupleTuple>::type type;
01845   };
01846 
01847 }
01848 
01849 #endif