dune-common
2.2.0
|
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