dune-common 2.1.1
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   
00177   template <class Tuple>
00178   struct Length
00179   {
00180     enum{ 
00181       value=tuple_size<Tuple>::value
00182         };
00183   };
00184 
00206   template <template <class> class TypeEvaluator, class TupleType>
00207   class ForEachType {
00208     dune_static_assert(AlwaysFalse<TupleType>::value, "Attempt to use the "
00209                        "unspecialized version of ForEachType.  ForEachType "
00210                        "needs to be specialized for each possible tuple "
00211                        "size.  Naturally the number of pre-defined "
00212                        "specializations is limited arbitrarily.  Maybe you "
00213                        "need to raise this limit by defining some more "
00214                        "specializations?");
00215     struct ImplementationDefined {};
00216   public:
00218     typedef ImplementationDefined Type;
00219   };
00220 
00221 #ifndef DOXYGEN
00222   template <template <class> class TE, class Tuple>
00223   struct ForEachType<TE, const Tuple> {
00224     typedef const typename ForEachType<TE, Tuple>::Type Type;
00225   };
00226 
00227   template <template <class> class TE>
00228   struct ForEachType<TE, tuple<> > {
00229     typedef tuple<> Type;
00230   };
00231 
00232   template <template <class> class TE, class T0>
00233   struct ForEachType<TE, tuple<T0> > {
00234     typedef tuple<typename TE<T0>::Type> Type;
00235   };
00236 
00237   template <template <class> class TE, class T0, class T1>
00238   struct ForEachType<TE, tuple<T0, T1> > {
00239     typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type> Type;
00240   };
00241 
00242   template <template <class> class TE, class T0, class T1, class T2>
00243   struct ForEachType<TE, tuple<T0, T1, T2> > {
00244     typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
00245                   typename TE<T2>::Type> Type;
00246   };
00247 
00248   template <template <class> class TE, class T0, class T1, class T2, class T3>
00249   struct ForEachType<TE, tuple<T0, T1, T2, T3> > {
00250     typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
00251                   typename TE<T2>::Type, typename TE<T3>::Type> Type;
00252   };
00253 
00254   template <template <class> class TE, class T0, class T1, class T2, class T3,
00255             class T4>
00256   struct ForEachType<TE, tuple<T0, T1, T2, T3, T4> > {
00257     typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
00258                   typename TE<T2>::Type, typename TE<T3>::Type,
00259                   typename TE<T4>::Type> Type;
00260   };
00261 
00262   template <template <class> class TE, class T0, class T1, class T2, class T3,
00263             class T4, class T5>
00264   struct ForEachType<TE, tuple<T0, T1, T2, T3, T4, T5> > {
00265     typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
00266                   typename TE<T2>::Type, typename TE<T3>::Type,
00267                   typename TE<T4>::Type, typename TE<T5>::Type> Type;
00268   };
00269 
00270   template <template <class> class TE, class T0, class T1, class T2, class T3,
00271             class T4, class T5, class T6>
00272   struct ForEachType<TE, tuple<T0, T1, T2, T3, T4, T5, T6> > {
00273     typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
00274                   typename TE<T2>::Type, typename TE<T3>::Type,
00275                   typename TE<T4>::Type, typename TE<T5>::Type,
00276                   typename TE<T6>::Type> Type;
00277   };
00278 
00279   template <template <class> class TE, class T0, class T1, class T2, class T3,
00280             class T4, class T5, class T6, class T7>
00281   struct ForEachType<TE, tuple<T0, T1, T2, T3, T4, T5, T6, T7> > {
00282     typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
00283                   typename TE<T2>::Type, typename TE<T3>::Type,
00284                   typename TE<T4>::Type, typename TE<T5>::Type,
00285                   typename TE<T6>::Type, typename TE<T7>::Type> Type;
00286   };
00287 
00288   template <template <class> class TE, class T0, class T1, class T2, class T3,
00289             class T4, class T5, class T6, class T7, class T8>
00290   struct ForEachType<TE, tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> > {
00291     typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
00292                   typename TE<T2>::Type, typename TE<T3>::Type,
00293                   typename TE<T4>::Type, typename TE<T5>::Type,
00294                   typename TE<T6>::Type, typename TE<T7>::Type,
00295                   typename TE<T8>::Type> Type;
00296   };
00297 
00298   // template <template <class> class TE, class T0, class T1, class T2, class T3,
00299   //           class T4, class T5, class T6, class T7, class T8, class T9>
00300   // struct ForEachType<TE, tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> > {
00301   //   typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
00302   //                 typename TE<T2>::Type, typename TE<T3>::Type,
00303   //                 typename TE<T4>::Type, typename TE<T5>::Type,
00304   //                 typename TE<T6>::Type, typename TE<T7>::Type,
00305   //                 typename TE<T8>::Type, typename TE<T9>::Type> Type;
00306   // };
00307 #endif // !defined(DOXYGEN)
00308 
00310   //
00311   // genericTransformTuple stuff
00312   //
00313 
00314   // genericTransformTuple() needs to be overloaded for each tuple size (we
00315   // limit ourselves to tuple_size <= 10 here).  For a given tuple size it
00316   // needs to be overloaded for all combinations of const and non-const
00317   // argument references.  (On the one hand, we want to allow modifyable
00318   // arguments, so const references alone are not sufficient.  On the other
00319   // hand, we also want to allow rvalues (literals) as argument, which do not
00320   // bind to non-const references.)
00321   //
00322   // We can half the number of specializations required by introducing a
00323   // function genericTransformTupleBackend(), which is overloaded for each
00324   // tuple size and for const and non-const tuple arguments; the functor
00325   // argument is always given as as (non-const) reference.  When
00326   // genericTransformTupleBackend() is called, the type of the Functor template
00327   // parameter is the deduced as either "SomeType" or "const SomeType",
00328   // depending on whether the function argument is a non-const or a const
00329   // lvalue of type "SomeType".  As explained above, this does not work for
00330   // rvalues (i.e. literals).
00331   //
00332   // To make it work for literals of functors as well, we wrap the call to
00333   // genericTransformTupleBackend() in a function genericTransformTuple().
00334   // genericTransformTuple() needs to be overloaded for non-const and const
00335   // tuples and functors -- 4 overloads only.  Inside genericTransformTuple()
00336   // the functor is an lvalue no matter whether the argument was an lvalue or
00337   // an rvalue.  There is no need need to overload genericTransformTuple() for
00338   // all tuple sizes -- this is done by the underlying
00339   // genericTransformTupleBackend().
00340 
00341   // genericTransformTupleBackend() is an implementation detail -- hide it
00342   // from Doxygen
00343 #ifndef DOXYGEN
00344   // 0-element tuple
00345   // This is a special case: we touch neither the tuple nor the functor, so
00346   // const references are sufficient and we don't need to overload
00347   template<class Functor>
00348   typename ForEachType<Functor::template TypeEvaluator,
00349                        tuple<> >::Type
00350   genericTransformTupleBackend
00351   (const tuple<>& t, const Functor& f)
00352   {
00353     return typename ForEachType<Functor::template TypeEvaluator,
00354       tuple<> >::Type
00355       ();
00356   }
00357 
00358   // 1-element tuple
00359   template<class T0, class Functor>
00360   typename ForEachType<Functor::template TypeEvaluator,
00361                        tuple<T0> >::Type
00362   genericTransformTupleBackend
00363   (tuple<T0>& t, Functor& f)
00364   {
00365     return typename ForEachType<Functor::template TypeEvaluator,
00366       tuple<T0> >::Type
00367       (f(get<0>(t)));
00368   }
00369   template<class T0, class Functor>
00370   typename ForEachType<Functor::template TypeEvaluator,
00371                        tuple<T0> >::Type
00372   genericTransformTupleBackend
00373   (const tuple<T0>& t, Functor& f)
00374   {
00375     return typename ForEachType<Functor::template TypeEvaluator,
00376       tuple<T0> >::Type
00377       (f(get<0>(t)));
00378   }
00379 
00380   // 2-element tuple
00381   template<class T0, class T1, class Functor>
00382   typename ForEachType<Functor::template TypeEvaluator,
00383                        tuple<T0, T1> >::Type
00384   genericTransformTupleBackend
00385   (tuple<T0, T1>& t, Functor& f)
00386   {
00387     return typename ForEachType<Functor::template TypeEvaluator,
00388       tuple<T0, T1> >::Type
00389       (f(get<0>(t)), f(get<1>(t)));
00390   }
00391   template<class T0, class T1, class Functor>
00392   typename ForEachType<Functor::template TypeEvaluator,
00393                        tuple<T0, T1> >::Type
00394   genericTransformTupleBackend
00395   (const tuple<T0, T1>& t, Functor& f)
00396   {
00397     return typename ForEachType<Functor::template TypeEvaluator,
00398       tuple<T0, T1> >::Type
00399       (f(get<0>(t)), f(get<1>(t)));
00400   }
00401 
00402   // 3-element tuple
00403   template<class T0, class T1, class T2, class Functor>
00404   typename ForEachType<Functor::template TypeEvaluator,
00405                        tuple<T0, T1, T2> >::Type
00406   genericTransformTupleBackend
00407   (tuple<T0, T1, T2>& t, Functor& f)
00408   {
00409     return typename ForEachType<Functor::template TypeEvaluator,
00410       tuple<T0, T1, T2> >::Type
00411       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)));
00412   }
00413   template<class T0, class T1, class T2, class Functor>
00414   typename ForEachType<Functor::template TypeEvaluator,
00415                        tuple<T0, T1, T2> >::Type
00416   genericTransformTupleBackend
00417   (const tuple<T0, T1, T2>& t, Functor& f)
00418   {
00419     return typename ForEachType<Functor::template TypeEvaluator,
00420       tuple<T0, T1, T2> >::Type
00421       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)));
00422   }
00423 
00424   // 4-element tuple
00425   template<class T0, class T1, class T2, class T3, class Functor>
00426   typename ForEachType<Functor::template TypeEvaluator,
00427                        tuple<T0, T1, T2, T3> >::Type
00428   genericTransformTupleBackend
00429   (tuple<T0, T1, T2, T3>& t, Functor& f)
00430   {
00431     return typename ForEachType<Functor::template TypeEvaluator,
00432       tuple<T0, T1, T2, T3> >::Type
00433       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)));
00434   }
00435   template<class T0, class T1, class T2, class T3, class Functor>
00436   typename ForEachType<Functor::template TypeEvaluator,
00437                        tuple<T0, T1, T2, T3> >::Type
00438   genericTransformTupleBackend
00439   (const tuple<T0, T1, T2, T3>& t, Functor& f)
00440   {
00441     return typename ForEachType<Functor::template TypeEvaluator,
00442       tuple<T0, T1, T2, T3> >::Type
00443       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)));
00444   }
00445 
00446   // 5-element tuple
00447   template<class T0, class T1, class T2, class T3, class T4, class Functor>
00448   typename ForEachType<Functor::template TypeEvaluator,
00449                        tuple<T0, T1, T2, T3, T4> >::Type
00450   genericTransformTupleBackend
00451   (tuple<T0, T1, T2, T3, T4>& t, Functor& f)
00452   {
00453     return typename ForEachType<Functor::template TypeEvaluator,
00454       tuple<T0, T1, T2, T3, T4> >::Type
00455       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)));
00456   }
00457   template<class T0, class T1, class T2, class T3, class T4, class Functor>
00458   typename ForEachType<Functor::template TypeEvaluator,
00459                        tuple<T0, T1, T2, T3, T4> >::Type
00460   genericTransformTupleBackend
00461   (const tuple<T0, T1, T2, T3, T4>& t, Functor& f)
00462   {
00463     return typename ForEachType<Functor::template TypeEvaluator,
00464       tuple<T0, T1, T2, T3, T4> >::Type
00465       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)));
00466   }
00467 
00468   // 6-element tuple
00469   template<class T0, class T1, class T2, class T3, class T4, class T5,
00470            class Functor>
00471   typename ForEachType<Functor::template TypeEvaluator,
00472                        tuple<T0, T1, T2, T3, T4, T5> >::Type
00473   genericTransformTupleBackend
00474   (tuple<T0, T1, T2, T3, T4, T5>& t, Functor& f)
00475   {
00476     return typename ForEachType<Functor::template TypeEvaluator,
00477       tuple<T0, T1, T2, T3, T4, T5> >::Type
00478       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
00479        f(get<5>(t)));
00480   }
00481   template<class T0, class T1, class T2, class T3, class T4, class T5,
00482            class Functor>
00483   typename ForEachType<Functor::template TypeEvaluator,
00484                        tuple<T0, T1, T2, T3, T4, T5> >::Type
00485   genericTransformTupleBackend
00486   (const tuple<T0, T1, T2, T3, T4, T5>& t, Functor& f)
00487   {
00488     return typename ForEachType<Functor::template TypeEvaluator,
00489       tuple<T0, T1, T2, T3, T4, T5> >::Type
00490       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
00491        f(get<5>(t)));
00492   }
00493 
00494   // 7-element tuple
00495   template<class T0, class T1, class T2, class T3, class T4, class T5,
00496            class T6, class Functor>
00497   typename ForEachType<Functor::template TypeEvaluator,
00498                        tuple<T0, T1, T2, T3, T4, T5, T6> >::Type
00499   genericTransformTupleBackend
00500   (tuple<T0, T1, T2, T3, T4, T5, T6>& t, Functor& f)
00501   {
00502     return typename ForEachType<Functor::template TypeEvaluator,
00503       tuple<T0, T1, T2, T3, T4, T5, T6> >::Type
00504       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
00505        f(get<5>(t)), f(get<6>(t)));
00506   }
00507   template<class T0, class T1, class T2, class T3, class T4, class T5,
00508            class T6, class Functor>
00509   typename ForEachType<Functor::template TypeEvaluator,
00510                        tuple<T0, T1, T2, T3, T4, T5, T6> >::Type
00511   genericTransformTupleBackend
00512   (const tuple<T0, T1, T2, T3, T4, T5, T6>& t, Functor& f)
00513   {
00514     return typename ForEachType<Functor::template TypeEvaluator,
00515       tuple<T0, T1, T2, T3, T4, T5, T6> >::Type
00516       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
00517        f(get<5>(t)), f(get<6>(t)));
00518   }
00519 
00520   // 8-element tuple
00521   template<class T0, class T1, class T2, class T3, class T4, class T5,
00522            class T6, class T7, class Functor>
00523   typename ForEachType<Functor::template TypeEvaluator,
00524                        tuple<T0, T1, T2, T3, T4, T5, T6, T7> >::Type
00525   genericTransformTupleBackend
00526   (tuple<T0, T1, T2, T3, T4, T5, T6, T7>& t, Functor& f)
00527   {
00528     return typename ForEachType<Functor::template TypeEvaluator,
00529       tuple<T0, T1, T2, T3, T4, T5, T6, T7> >::Type
00530       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
00531        f(get<5>(t)), f(get<6>(t)), f(get<7>(t)));
00532   }
00533   template<class T0, class T1, class T2, class T3, class T4, class T5,
00534            class T6, class T7, class Functor>
00535   typename ForEachType<Functor::template TypeEvaluator,
00536                        tuple<T0, T1, T2, T3, T4, T5, T6, T7> >::Type
00537   genericTransformTupleBackend
00538   (const tuple<T0, T1, T2, T3, T4, T5, T6, T7>& t, Functor& f)
00539   {
00540     return typename ForEachType<Functor::template TypeEvaluator,
00541       tuple<T0, T1, T2, T3, T4, T5, T6, T7> >::Type
00542       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
00543        f(get<5>(t)), f(get<6>(t)), f(get<7>(t)));
00544   }
00545 
00546   // 9-element tuple
00547   template<class T0, class T1, class T2, class T3, class T4, class T5,
00548            class T6, class T7, class T8, class Functor>
00549   typename ForEachType<Functor::template TypeEvaluator,
00550                        tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> >::Type
00551   genericTransformTupleBackend
00552   (tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8>& t, Functor& f)
00553   {
00554     return typename ForEachType<Functor::template TypeEvaluator,
00555       tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> >::Type
00556       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
00557        f(get<5>(t)), f(get<6>(t)), f(get<7>(t)), f(get<8>(t)));
00558   }
00559   template<class T0, class T1, class T2, class T3, class T4, class T5,
00560            class T6, class T7, class T8, class Functor>
00561   typename ForEachType<Functor::template TypeEvaluator,
00562                        tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> >::Type
00563   genericTransformTupleBackend
00564   (const tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8>& t, Functor& f)
00565   {
00566     return typename ForEachType<Functor::template TypeEvaluator,
00567       tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> >::Type
00568       (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
00569        f(get<5>(t)), f(get<6>(t)), f(get<7>(t)), f(get<8>(t)));
00570   }
00571 
00572   // // 10-element tuple
00573   // template<class T0, class T1, class T2, class T3, class T4, class T5,
00574   //          class T6, class T7, class T8, class T9, class Functor>
00575   // typename ForEachType<Functor::template TypeEvaluator,
00576   //                      tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::Type
00577   // genericTransformTupleBackend
00578   // (tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& t, Functor& f)
00579   // {
00580   //   return typename ForEachType<Functor::template TypeEvaluator,
00581   //     tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::Type
00582   //     (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
00583   //      f(get<5>(t)), f(get<6>(t)), f(get<7>(t)), f(get<8>(t)), f(get<9>(t)));
00584   // }
00585   // template<class T0, class T1, class T2, class T3, class T4, class T5,
00586   //          class T6, class T7, class T8, class T9, class Functor>
00587   // typename ForEachType<Functor::template TypeEvaluator,
00588   //                      tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::Type
00589   // genericTransformTupleBackend
00590   // (const tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& t, Functor& f)
00591   // {
00592   //   return typename ForEachType<Functor::template TypeEvaluator,
00593   //     tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::Type
00594   //     (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
00595   //      f(get<5>(t)), f(get<6>(t)), f(get<7>(t)), f(get<8>(t)), f(get<9>(t)));
00596   // }
00597 #endif // ! defined(DOXYGEN)
00598 
00600 
00641   template<class Tuple, class Functor>
00642   typename ForEachType<Functor::template TypeEvaluator, Tuple>::Type
00643   genericTransformTuple(Tuple& t, Functor& f) {
00644     return genericTransformTupleBackend(t, f);
00645   }
00646 #ifndef DOXYGEN
00647   template<class Tuple, class Functor>
00648   typename ForEachType<Functor::template TypeEvaluator, Tuple>::Type
00649   genericTransformTuple(const Tuple& t, Functor& f) {
00650     return genericTransformTupleBackend(t, f);
00651   }
00652   template<class Tuple, class Functor>
00653   typename ForEachType<Functor::template TypeEvaluator, Tuple>::Type
00654   genericTransformTuple(Tuple& t, const Functor& f) {
00655     return genericTransformTupleBackend(t, f);
00656   }
00657   template<class Tuple, class Functor>
00658   typename ForEachType<Functor::template TypeEvaluator, Tuple>::Type
00659   genericTransformTuple(const Tuple& t, const Functor& f) {
00660     return genericTransformTupleBackend(t, f);
00661   }
00662 #endif // ! defined(DOXYGEN)
00663 
00665   //
00666   // transformTuple() related stuff
00667   //
00668 
00670 
00701   template<template<class> class TE, class A0 = void, class A1 = void,
00702            class A2 = void, class A3 = void, class A4 = void, class A5 = void,
00703            class A6 = void, class A7 = void, class A8 = void, class A9 = void>
00704   class TransformTupleFunctor {
00705     A0& a0; A1& a1; A2& a2; A3& a3; A4& a4; A5& a5; A6& a6; A7& a7; A8& a8;
00706     A9& a9;
00707 
00708   public:
00710     template<class T> struct TypeEvaluator : public TE<T> {};
00711 
00713 
00718     TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_, A3& a3_, A4& a4_, A5& a5_,
00719                           A6& a6_, A7& a7_, A8& a8_, A9& a9_)
00720       : a0(a0_), a1(a1_), a2(a2_), a3(a3_), a4(a4_), a5(a5_), a6(a6_), a7(a7_),
00721         a8(a8_), a9(a9_)
00722     { }
00723 
00725 
00733     template<class T>
00734     typename TE<T>::Type operator()(T& t) const {
00735       return TE<T>::apply(t, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
00736     }
00737   };
00738 
00740 
00792   template<template<class> class TE, class A0, class A1, class A2, class A3,
00793            class A4, class A5, class A6, class A7, class A8, class A9>
00794   TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9>
00795   makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
00796                             A6& a6, A7& a7, A8& a8, A9& a9) {
00797     return TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9>
00798       (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
00799   }
00800 
00801 #ifndef DOXYGEN
00802   // 0 argument
00803   template<template<class> class TE>
00804   struct TransformTupleFunctor<TE>
00805   {
00806     template<class T> struct TypeEvaluator : public TE<T> {};
00807 
00808     template<class T>
00809     typename TE<T>::Type operator()(T& t) const {
00810       return TE<T>::apply(t);
00811     }
00812   };
00813   template<template<class> class TE>
00814   TransformTupleFunctor<TE>
00815   makeTransformTupleFunctor() {
00816     return TransformTupleFunctor<TE>
00817       ();
00818   }
00819 
00820   // 1 argument
00821   template<template<class> class TE, class A0>
00822   class TransformTupleFunctor<TE, A0>
00823   {
00824     A0& a0;
00825 
00826   public:
00827     template<class T> struct TypeEvaluator : public TE<T> {};
00828 
00829     TransformTupleFunctor(A0& a0_)
00830       : a0(a0_)
00831     { }
00832 
00833     template<class T>
00834     typename TE<T>::Type operator()(T& t) const {
00835       return TE<T>::apply(t, a0);
00836     }
00837   };
00838   template<template<class> class TE, class A0>
00839   TransformTupleFunctor<TE, A0>
00840   makeTransformTupleFunctor(A0& a0) {
00841     return TransformTupleFunctor<TE, A0>
00842       (a0);
00843   }
00844 
00845   // 2 argument
00846   template<template<class> class TE, class A0, class A1>
00847   class TransformTupleFunctor<TE, A0, A1>
00848   {
00849     A0& a0; A1& a1;
00850 
00851   public:
00852     template<class T> struct TypeEvaluator : public TE<T> {};
00853 
00854     TransformTupleFunctor(A0& a0_, A1& a1_)
00855       : a0(a0_), a1(a1_)
00856     { }
00857 
00858     template<class T>
00859     typename TE<T>::Type operator()(T& t) const {
00860       return TE<T>::apply(t, a0, a1);
00861     }
00862   };
00863   template<template<class> class TE, class A0, class A1>
00864   TransformTupleFunctor<TE, A0, A1>
00865   makeTransformTupleFunctor(A0& a0, A1& a1) {
00866     return TransformTupleFunctor<TE, A0, A1>
00867       (a0, a1);
00868   }
00869 
00870   // 3 arguments
00871   template<template<class> class TE, class A0, class A1, class A2>
00872   class TransformTupleFunctor<TE, A0, A1, A2>
00873   {
00874     A0& a0; A1& a1; A2& a2;
00875 
00876   public:
00877     template<class T> struct TypeEvaluator : public TE<T> {};
00878 
00879     TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_)
00880       : a0(a0_), a1(a1_), a2(a2_)
00881     { }
00882 
00883     template<class T>
00884     typename TE<T>::Type operator()(T& t) const {
00885       return TE<T>::apply(t, a0, a1, a2);
00886     }
00887   };
00888   template<template<class> class TE, class A0, class A1, class A2>
00889   TransformTupleFunctor<TE, A0, A1, A2>
00890   makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2) {
00891     return TransformTupleFunctor<TE, A0, A1, A2>
00892       (a0, a1, a2);
00893   }
00894 
00895   // 4 arguments
00896   template<template<class> class TE, class A0, class A1, class A2, class A3>
00897   class TransformTupleFunctor<TE, A0, A1, A2, A3>
00898   {
00899     A0& a0; A1& a1; A2& a2; A3& a3;
00900 
00901   public:
00902     template<class T> struct TypeEvaluator : public TE<T> {};
00903 
00904     TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_, A3& a3_)
00905       : a0(a0_), a1(a1_), a2(a2_), a3(a3_)
00906     { }
00907 
00908     template<class T>
00909     typename TE<T>::Type operator()(T& t) const {
00910       return TE<T>::apply(t, a0, a1, a2, a3);
00911     }
00912   };
00913   template<template<class> class TE, class A0, class A1, class A2, class A3>
00914   TransformTupleFunctor<TE, A0, A1, A2, A3>
00915   makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2, A3& a3) {
00916     return TransformTupleFunctor<TE, A0, A1, A2, A3>
00917       (a0, a1, a2, a3);
00918   }
00919 
00920   // 5 arguments
00921   template<template<class> class TE, class A0, class A1, class A2, class A3,
00922            class A4>
00923   class TransformTupleFunctor<TE, A0, A1, A2, A3, A4>
00924   {
00925     A0& a0; A1& a1; A2& a2; A3& a3; A4& a4;
00926 
00927   public:
00928     template<class T> struct TypeEvaluator : public TE<T> {};
00929 
00930     TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_, A3& a3_, A4& a4_)
00931       : a0(a0_), a1(a1_), a2(a2_), a3(a3_), a4(a4_)
00932     { }
00933 
00934     template<class T>
00935     typename TE<T>::Type operator()(T& t) const {
00936       return TE<T>::apply(t, a0, a1, a2, a3, a4);
00937     }
00938   };
00939   template<template<class> class TE, class A0, class A1, class A2, class A3,
00940            class A4>
00941   TransformTupleFunctor<TE, A0, A1, A2, A3, A4>
00942   makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4) {
00943     return TransformTupleFunctor<TE, A0, A1, A2, A3, A4>
00944       (a0, a1, a2, a3, a4);
00945   }
00946 
00947   // 6 arguments
00948   template<template<class> class TE, class A0, class A1, class A2, class A3,
00949            class A4, class A5>
00950   class TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5>
00951   {
00952     A0& a0; A1& a1; A2& a2; A3& a3; A4& a4; A5& a5;
00953 
00954   public:
00955     template<class T> struct TypeEvaluator : public TE<T> {};
00956 
00957     TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_, A3& a3_, A4& a4_, A5& a5_)
00958       : a0(a0_), a1(a1_), a2(a2_), a3(a3_), a4(a4_), a5(a5_)
00959     { }
00960 
00961     template<class T>
00962     typename TE<T>::Type operator()(T& t) const {
00963       return TE<T>::apply(t, a0, a1, a2, a3, a4, a5);
00964     }
00965   };
00966   template<template<class> class TE, class A0, class A1, class A2, class A3,
00967            class A4, class A5>
00968   TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5>
00969   makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) {
00970     return TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5>
00971       (a0, a1, a2, a3, a4, a5);
00972   }
00973 
00974   // 7 arguments
00975   template<template<class> class TE, class A0, class A1, class A2, class A3,
00976            class A4, class A5, class A6>
00977   class TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6>
00978   {
00979     A0& a0; A1& a1; A2& a2; A3& a3; A4& a4; A5& a5; A6& a6;
00980 
00981   public:
00982     template<class T> struct TypeEvaluator : public TE<T> {};
00983 
00984     TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_, A3& a3_, A4& a4_, A5& a5_,
00985                           A6& a6_)
00986       : a0(a0_), a1(a1_), a2(a2_), a3(a3_), a4(a4_), a5(a5_), a6(a6_)
00987     { }
00988 
00989     template<class T>
00990     typename TE<T>::Type operator()(T& t) const {
00991       return TE<T>::apply(t, a0, a1, a2, a3, a4, a5, a6);
00992     }
00993   };
00994   template<template<class> class TE, class A0, class A1, class A2, class A3,
00995            class A4, class A5, class A6>
00996   TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6>
00997   makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
00998                             A6& a6) {
00999     return TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6>
01000       (a0, a1, a2, a3, a4, a5, a6);
01001   }
01002 
01003   // 8 arguments
01004   template<template<class> class TE, class A0, class A1, class A2, class A3,
01005            class A4, class A5, class A6, class A7>
01006   class TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7>
01007   {
01008     A0& a0; A1& a1; A2& a2; A3& a3; A4& a4; A5& a5; A6& a6; A7& a7;
01009 
01010   public:
01011     template<class T> struct TypeEvaluator : public TE<T> {};
01012 
01013     TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_, A3& a3_, A4& a4_, A5& a5_,
01014                           A6& a6_, A7& a7_)
01015       : a0(a0_), a1(a1_), a2(a2_), a3(a3_), a4(a4_), a5(a5_), a6(a6_), a7(a7_)
01016     { }
01017 
01018     template<class T>
01019     typename TE<T>::Type operator()(T& t) const {
01020       return TE<T>::apply(t, a0, a1, a2, a3, a4, a5, a6, a7);
01021     }
01022   };
01023   template<template<class> class TE, class A0, class A1, class A2, class A3,
01024            class A4, class A5, class A6, class A7>
01025   TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7>
01026   makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
01027                             A6& a6, A7& a7) {
01028     return TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7>
01029       (a0, a1, a2, a3, a4, a5, a6, a7);
01030   }
01031 
01032   // 9 arguments
01033   template<template<class> class TE, class A0, class A1, class A2, class A3,
01034            class A4, class A5, class A6, class A7, class A8>
01035   class TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7, A8>
01036   {
01037     A0& a0; A1& a1; A2& a2; A3& a3; A4& a4; A5& a5; A6& a6; A7& a7; A8& a8;
01038 
01039   public:
01040     template<class T> struct TypeEvaluator : public TE<T> {};
01041 
01042     TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_, A3& a3_, A4& a4_, A5& a5_,
01043                           A6& a6_, A7& a7_, A8& a8_)
01044       : a0(a0_), a1(a1_), a2(a2_), a3(a3_), a4(a4_), a5(a5_), a6(a6_), a7(a7_),
01045         a8(a8_)
01046     { }
01047 
01048     template<class T>
01049     typename TE<T>::Type operator()(T& t) const {
01050       return TE<T>::apply(t, a0, a1, a2, a3, a4, a5, a6, a7, a8);
01051     }
01052   };
01053   template<template<class> class TE, class A0, class A1, class A2, class A3,
01054            class A4, class A5, class A6, class A7, class A8>
01055   TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7, A8>
01056   makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
01057                             A6& a6, A7& a7, A8& a8) {
01058     return TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7, A8>
01059       (a0, a1, a2, a3, a4, a5, a6, a7, a8);
01060   }
01061 #endif // ! defined(DOXYGEN)
01062 
01064 
01158   template<template<class> class TypeEvaluator, class Tuple, class A0,
01159            class A1, class A2, class A3, class A4, class A5, class A6,
01160            class A7, class A8, class A9>
01161   typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
01162   transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
01163                  A6& a6, A7& a7, A8& a8, A9& a9) {
01164     return genericTransformTuple
01165       ( orig,
01166         makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2, a3, a4, a5, a6,
01167                                                  a7, a8, a9));
01168   }
01169 
01170 #ifndef DOXYGEN
01171   // 0 extra arguments
01172   template<template<class> class TypeEvaluator, class Tuple>
01173   typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
01174   transformTuple(Tuple& orig) {
01175     return genericTransformTuple
01176       ( orig,
01177         makeTransformTupleFunctor<TypeEvaluator>());
01178   }
01179 
01180   // 1 extra argument
01181   template<template<class> class TypeEvaluator, class Tuple, class A0>
01182   typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
01183   transformTuple(Tuple& orig, A0& a0) {
01184     return genericTransformTuple
01185       ( orig,
01186         makeTransformTupleFunctor<TypeEvaluator>(a0));
01187   }
01188 
01189   // 2 extra arguments
01190   template<template<class> class TypeEvaluator, class Tuple, class A0,
01191            class A1>
01192   typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
01193   transformTuple(Tuple& orig, A0& a0, A1& a1) {
01194     return genericTransformTuple
01195       ( orig,
01196         makeTransformTupleFunctor<TypeEvaluator>(a0, a1));
01197   }
01198 
01199   // 3 extra arguments
01200   template<template<class> class TypeEvaluator, class Tuple, class A0,
01201            class A1, class A2>
01202   typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
01203   transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2) {
01204     return genericTransformTuple
01205       ( orig,
01206         makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2));
01207   }
01208 
01209   // 4 extra arguments
01210   template<template<class> class TypeEvaluator, class Tuple, class A0,
01211            class A1, class A2, class A3>
01212   typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
01213   transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2, A3& a3) {
01214     return genericTransformTuple
01215       ( orig,
01216         makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2, a3));
01217   }
01218 
01219   // 5 extra arguments
01220   template<template<class> class TypeEvaluator, class Tuple, class A0,
01221            class A1, class A2, class A3, class A4>
01222   typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
01223   transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2, A3& a3, A4& a4) {
01224     return genericTransformTuple
01225       ( orig,
01226         makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2, a3, a4));
01227   }
01228 
01229   // 6 extra arguments
01230   template<template<class> class TypeEvaluator, class Tuple, class A0,
01231            class A1, class A2, class A3, class A4, class A5>
01232   typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
01233   transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) {
01234     return genericTransformTuple
01235       ( orig,
01236         makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2, a3, a4, a5));
01237   }
01238 
01239   // 7 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   typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
01243   transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
01244                  A6& a6) {
01245     return genericTransformTuple
01246       ( orig,
01247         makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2, a3, a4, a5, a6));
01248   }
01249 
01250   // 8 extra arguments
01251   template<template<class> class TypeEvaluator, class Tuple, class A0,
01252            class A1, class A2, class A3, class A4, class A5, class A6,
01253            class A7>
01254   typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
01255   transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
01256                  A6& a6, A7& a7) {
01257     return genericTransformTuple
01258       ( orig,
01259         makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2, a3, a4, a5, a6,
01260                                                  a7));
01261   }
01262 
01263   // 9 extra arguments
01264   template<template<class> class TypeEvaluator, class Tuple, class A0,
01265            class A1, class A2, class A3, class A4, class A5, class A6,
01266            class A7, class A8>
01267   typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
01268   transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
01269                  A6& a6, A7& a7, A8& a8) {
01270     return genericTransformTuple
01271       ( orig,
01272         makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2, a3, a4, a5, a6,
01273                                                  a7, a8));
01274   }
01275 #endif // not defined(DOXYGEN)
01276 
01278   //
01279   // Sample TypeEvaluators
01280   //
01281 
01283 
01287   template<class T>
01288   struct AddRefTypeEvaluator {
01289     typedef T& Type;
01290     static Type apply(T& t) { return t; }
01291   };
01292 
01294 
01298   template<class T>
01299   struct AddPtrTypeEvaluator {
01300     typedef typename remove_reference<T>::type* Type;
01301     static Type apply(T& t) { return &t; }
01302   };
01303 
01304   // Specialization, in case the type is already a reference
01305   template<class T>
01306   struct AddPtrTypeEvaluator<T&> {
01307     typedef typename remove_reference<T>::type* Type;
01308     static Type apply(T& t) { return &t; }
01309   };
01310 
01311   namespace
01312   {
01313     template<int i, typename T1,typename F>
01314     struct Visitor
01315     {
01316       static inline void visit(F& func, T1& t1)
01317       {
01318         func.visit(get<tuple_size<T1>::value-i>(t1));
01319         Visitor<i-1,T1,F>::visit(func, t1);
01320       }
01321     };
01322         
01323     template<typename T1,typename F>
01324     struct Visitor<0,T1,F>
01325     {
01326       static inline void visit(F& func, T1& t1)
01327       {}
01328     };
01329 
01330     template<int i, typename T1, typename T2,typename F>
01331     struct PairVisitor
01332     {
01333       static inline void visit(F& func, T1& t1, T2& t2)
01334       {
01335         func.visit(get<tuple_size<T1>::value-i>(t1), get<tuple_size<T2>::value-i>(t2));
01336         PairVisitor<i-1,T1,T2,F>::visit(func, t1, t2);
01337       }
01338     };
01339         
01340     template<typename T1, typename T2, typename F>
01341     struct PairVisitor<0,T1,T2,F>
01342     {
01343       static inline void visit(F& func, T1& t1, T2& t2)
01344       {}
01345     };
01346   }
01347   
01382   template <class TupleType>
01383   class ForEachValue {
01384   public:
01387     ForEachValue(TupleType& tuple) : tuple_(tuple) {}
01388     
01391     template <class Functor>
01392     void apply(Functor& f) const {
01393       Visitor<tuple_size<TupleType>::value,TupleType,Functor>::visit(f, tuple_);
01394     }
01395   private:
01396     TupleType& tuple_;
01397   };
01398 
01399   //- Definition ForEachValuePair class
01400   // Assertion: both tuples have the same length and the contained types are
01401   // compatible in the sense of the applied function object
01415   template <class TupleType1, class TupleType2>
01416   class ForEachValuePair {
01417   public:
01421     ForEachValuePair(TupleType1& t1, TupleType2& t2) :
01422       tuple1_(t1),
01423       tuple2_(t2)
01424     {}
01425 
01428     template <class Functor>
01429     void apply(Functor& f) {
01430       PairVisitor<tuple_size<TupleType1>::value,TupleType1,TupleType2,Functor>
01431         ::visit(f, tuple1_, tuple2_);
01432     }
01433   private:
01434     TupleType1& tuple1_;
01435     TupleType2& tuple2_;
01436   };
01437 
01438   //- Reverse element access
01444   template <int N, class Tuple>
01445   struct AtType {
01446     typedef typename tuple_element<Length<Tuple>::value - N - 1,
01447                                    Tuple>::type Type;
01448   };
01449   
01457   template <int N>
01458   struct At 
01459   {
01460 
01461     template<typename Tuple>
01462     static
01463     typename TupleAccessTraits<typename AtType<N, Tuple>::Type>::NonConstType
01464     get(Tuple& t)
01465     {
01466       return Dune::get<tuple_size<Tuple>::value - N - 1>(t);
01467     }
01468     
01469     template<typename Tuple>
01470     static
01471     typename TupleAccessTraits<typename AtType<N, Tuple>::Type>::ConstType
01472     get(const Tuple& t)
01473     {
01474       return Dune::get<tuple_size<Tuple>::value - N - 1>(t);
01475     }
01476   };
01477 
01484   template <class Tuple>
01485   class PointerPairDeletor
01486   {
01487     struct Deletor {
01488       template<typename P> void visit(const P& p) { delete p; }
01489     };
01490 
01491   public:
01492     static void apply(Tuple& t) {
01493       static Deletor deletor;
01494       ForEachValue<Tuple>(t).apply(deletor);
01495     }
01496   };
01497 
01498 
01522   template<class Tuple, template<class> class Predicate, std::size_t start = 0,
01523            std::size_t size = tuple_size<Tuple>::value>
01524   class FirstPredicateIndex :
01525     public SelectType<Predicate<typename tuple_element<start,
01526                                                        Tuple>::type>::value,
01527                       integral_constant<std::size_t, start>,
01528                       FirstPredicateIndex<Tuple, Predicate, start+1> >::Type
01529   {
01530     dune_static_assert(tuple_size<Tuple>::value == size, "The \"size\" "
01531                        "template parameter of FirstPredicateIndex is an "
01532                        "implementation detail and should never be set "
01533                        "explicitly!");
01534   };
01535 
01536 #ifndef DOXYGEN
01537   template<class Tuple, template<class> class Predicate, std::size_t size>
01538   class FirstPredicateIndex<Tuple, Predicate, size, size>
01539   {
01540     dune_static_assert(AlwaysFalse<Tuple>::value, "None of the tuple element "
01541                        "types matches the predicate!");
01542   };
01543 #endif // !DOXYGEN
01544 
01554   template<class T>
01555   struct IsType {
01557     template<class U>
01558     struct Predicate : public is_same<T, U> {};
01559   };
01560 
01574   template<class Tuple, class T, std::size_t start = 0>
01575   struct FirstTypeIndex :
01576     public FirstPredicateIndex<Tuple, IsType<T>::template Predicate, start>
01577   { };
01578 
01579 
01580 
01598   template< class Tuple, class T>
01599   struct PushBackTuple
01600   {
01601     dune_static_assert(AlwaysFalse<Tuple>::value, "Attempt to use the "
01602                        "unspecialized version of PushBackTuple.  "
01603                        "PushBackTuple needs to be specialized for "
01604                        "each possible tuple size.  Naturally the number of "
01605                        "pre-defined specializations is limited arbitrarily.  "
01606                        "Maybe you need to raise this limit by defining some "
01607                        "more specializations?");
01608 
01615     typedef Tuple type;
01616   };
01617 
01618 
01619 #ifndef DOXYGEN
01620 
01621   template<class T>
01622   struct PushBackTuple< Dune::tuple<>, T>
01623   {
01624     typedef typename Dune::tuple<T> type;
01625   };
01626 
01627   template< class T1, class T>
01628   struct PushBackTuple< Dune::tuple<T1>, T>
01629   {
01630     typedef typename Dune::tuple<T1, T> type;
01631   };
01632 
01633   template< class T1, class T2, class T>
01634   struct PushBackTuple< Dune::tuple<T1, T2>, T>
01635   {
01636     typedef typename Dune::tuple<T1, T2, T> type;
01637   };
01638 
01639   template< class T1, class T2, class T3, class T>
01640   struct PushBackTuple< Dune::tuple<T1, T2, T3>, T>
01641   {
01642     typedef typename Dune::tuple<T1, T2, T3, T> type;
01643   };
01644 
01645   template< class T1, class T2, class T3, class T4, class T>
01646   struct PushBackTuple< Dune::tuple<T1, T2, T3, T4>, T>
01647   {
01648     typedef typename Dune::tuple<T1, T2, T3, T4, T> type;
01649   };
01650 
01651   template< class T1, class T2, class T3, class T4, class T5, class T>
01652   struct PushBackTuple< Dune::tuple<T1, T2, T3, T4, T5>, T>
01653   {
01654     typedef typename Dune::tuple<T1, T2, T3, T4, T5, T> type;
01655   };
01656 
01657   template< class T1, class T2, class T3, class T4, class T5, class T6, class T>
01658   struct PushBackTuple< Dune::tuple<T1, T2, T3, T4, T5, T6>, T>
01659   {
01660     typedef typename Dune::tuple<T1, T2, T3, T4, T5, T6, T> type;
01661   };
01662 
01663   template< class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T>
01664   struct PushBackTuple< Dune::tuple<T1, T2, T3, T4, T5, T6, T7>, T>
01665   {
01666     typedef typename Dune::tuple<T1, T2, T3, T4, T5, T6, T7, T> type;
01667   };
01668 
01669   template< class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T>
01670   struct PushBackTuple< Dune::tuple<T1, T2, T3, T4, T5, T6, T7, T8>, T>
01671   {
01672     typedef typename Dune::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T> type;
01673   };
01674 
01675 #endif
01676 
01677 
01678 
01696   template< class Tuple, class T>
01697   struct PushFrontTuple
01698   {
01699     dune_static_assert(AlwaysFalse<Tuple>::value, "Attempt to use the "
01700                        "unspecialized version of PushFrontTuple.  "
01701                        "PushFrontTuple needs to be specialized for "
01702                        "each possible tuple size.  Naturally the number of "
01703                        "pre-defined specializations is limited arbitrarily.  "
01704                        "Maybe you need to raise this limit by defining some "
01705                        "more specializations?");
01706 
01713     typedef Tuple type;
01714   };
01715 
01716 
01717 #ifndef DOXYGEN
01718 
01719   template<class T>
01720   struct PushFrontTuple< Dune::tuple<>, T>
01721   {
01722     typedef typename Dune::tuple<T> type;
01723   };
01724 
01725   template< class T1, class T>
01726   struct PushFrontTuple< Dune::tuple<T1>, T>
01727   {
01728     typedef typename Dune::tuple<T, T1> type;
01729   };
01730 
01731   template< class T1, class T2, class T>
01732   struct PushFrontTuple< Dune::tuple<T1, T2>, T>
01733   {
01734     typedef typename Dune::tuple<T, T1, T2> type;
01735   };
01736 
01737   template< class T1, class T2, class T3, class T>
01738   struct PushFrontTuple< Dune::tuple<T1, T2, T3>, T>
01739   {
01740     typedef typename Dune::tuple<T, T1, T2, T3> type;
01741   };
01742 
01743   template< class T1, class T2, class T3, class T4, class T>
01744   struct PushFrontTuple< Dune::tuple<T1, T2, T3, T4>, T>
01745   {
01746     typedef typename Dune::tuple<T, T1, T2, T3, T4> type;
01747   };
01748 
01749   template< class T1, class T2, class T3, class T4, class T5, class T>
01750   struct PushFrontTuple< Dune::tuple<T1, T2, T3, T4, T5>, T>
01751   {
01752     typedef typename Dune::tuple<T, T1, T2, T3, T4, T5> type;
01753   };
01754 
01755   template< class T1, class T2, class T3, class T4, class T5, class T6, class T>
01756   struct PushFrontTuple< Dune::tuple<T1, T2, T3, T4, T5, T6>, T>
01757   {
01758     typedef typename Dune::tuple<T, T1, T2, T3, T4, T5, T6> type;
01759   };
01760 
01761   template< class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T>
01762   struct PushFrontTuple< Dune::tuple<T1, T2, T3, T4, T5, T6, T7>, T>
01763   {
01764     typedef typename Dune::tuple<T, T1, T2, T3, T4, T5, T6, T7> type;
01765   };
01766 
01767   template< class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T>
01768   struct PushFrontTuple< Dune::tuple<T1, T2, T3, T4, T5, T6, T7, T8>, T>
01769   {
01770     typedef typename Dune::tuple<T, T1, T2, T3, T4, T5, T6, T7, T8> type;
01771   };
01772 
01773 #endif
01774 
01775 
01776 
01789   template<
01790     template <class, class> class F,
01791     class Tuple,
01792     class Seed=tuple<>,
01793     int N=tuple_size<Tuple>::value>
01794   struct ReduceTuple
01795   {
01796     typedef typename ReduceTuple<F, Tuple, Seed, N-1>::type Accumulated;
01797     typedef typename tuple_element<N-1, Tuple>::type Value;
01798 
01800     typedef typename F<Accumulated, Value>::type type;
01801   };
01802 
01813   template<
01814     template <class, class> class F,
01815     class Tuple,
01816     class Seed>
01817   struct ReduceTuple<F, Tuple, Seed, 0>
01818   {
01820     typedef Seed type;
01821   };
01822 
01823 
01824 
01834   template<class Head, class Tail>
01835   struct JoinTuples
01836   {
01838     typedef typename ReduceTuple< PushBackTuple, Tail, Head>::type type;
01839   };
01840 
01841 
01842 
01851   template<class TupleTuple>
01852   struct FlattenTuple
01853   {
01855     typedef typename ReduceTuple< JoinTuples, TupleTuple>::type type;
01856   };
01857 
01858 }
01859 
01860 #endif