- Home
- About DUNE
- Download
- Documentation
- Community
- Development
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 //! 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
Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].