00001 #ifndef DUNE_UTILITY_HH
00002 #define DUNE_UTILITY_HH
00003
00004 #include "tuples.hh"
00005
00006 namespace Dune {
00007
00025 template <class Tuple>
00026 class NullPointerInitialiser {};
00027
00028 namespace
00029 {
00036 template<class T, int size>
00037 struct InitialiserHelper
00038 {};
00039
00040 template<typename T1, typename T2, typename T3, typename T4, typename T5,
00041 typename T6, typename T7, typename T8, typename T9>
00042 struct InitialiserHelper<tuple<T1*,T2,T3,T4,T5,T6,T7,T8,T9>,1>
00043 {
00044 static inline tuple<T1*,T2,T3,T4,T5,T6,T7,T8,T9> apply()
00045 {
00046 return tuple<T1*,T2,T3,T4,T5,T6,T7,T8,T9>(0);
00047 }
00048 };
00049
00050 template<typename T1, typename T2, typename T3, typename T4, typename T5,
00051 typename T6, typename T7, typename T8, typename T9>
00052 struct InitialiserHelper<tuple<T1*,T2*,T3,T4,T5,T6,T7,T8,T9>,2>
00053 {
00054 static inline tuple<T1*,T2*,T3,T4,T5,T6,T7,T8,T9> apply()
00055 {
00056 return tuple<T1*,T2*,T3,T4,T5,T6,T7,T8,T9>(0,0);
00057 }
00058 };
00059
00060 template<typename T1, typename T2, typename T3, typename T4, typename T5,
00061 typename T6, typename T7, typename T8, typename T9>
00062 struct InitialiserHelper<tuple<T1*,T2*,T3*,T4,T5,T6,T7,T8,T9>,3>
00063 {
00064 static inline tuple<T1*,T2*,T3*,T4,T5,T6,T7,T8,T9> apply()
00065 {
00066 return tuple<T1*,T2*,T3*,T4,T5,T6,T7,T8,T9>(0,0,0);
00067 }
00068 };
00069
00070 template<typename T1, typename T2, typename T3, typename T4, typename T5,
00071 typename T6, typename T7, typename T8, typename T9>
00072 struct InitialiserHelper<tuple<T1*,T2*,T3*,T4*,T5,T6,T7,T8,T9>,4>
00073 {
00074 static inline tuple<T1*,T2*,T3*,T4*,T5,T6,T7,T8,T9> apply()
00075 {
00076 return tuple<T1*,T2*,T3*,T4*,T5,T6,T7,T8,T9>(0,0,0,0);
00077 }
00078 };
00079
00080 template<typename T1, typename T2, typename T3, typename T4, typename T5,
00081 typename T6, typename T7, typename T8, typename T9>
00082 struct InitialiserHelper<tuple<T1*,T2*,T3*,T4*,T5*,T6,T7,T8,T9>,5>
00083 {
00084 static inline tuple<T1*,T2*,T3*,T4*,T5*,T6,T7,T8,T9> apply()
00085 {
00086 return tuple<T1*,T2*,T3*,T4*,T5*,T6,T7,T8,T9>(0,0,0,0,0);
00087 }
00088 };
00089
00090 template<typename T1, typename T2, typename T3, typename T4, typename T5,
00091 typename T6, typename T7, typename T8, typename T9>
00092 struct InitialiserHelper<tuple<T1*,T2*,T3*,T4*,T5*,T6*,T7,T8,T9>,6>
00093 {
00094 static inline tuple<T1*,T2*,T3*,T4*,T5*,T6*,T7,T8,T9> apply()
00095 {
00096 return tuple<T1*,T2*,T3*,T4*,T5*,T6*,T7,T8,T9>(0,0,0,0,0,0);
00097 }
00098 };
00099
00100 template<typename T1, typename T2, typename T3, typename T4, typename T5,
00101 typename T6, typename T7, typename T8, typename T9>
00102 struct InitialiserHelper<tuple<T1*,T2*,T3*,T4*,T5*,T6*,T7*,T8,T9>,7>
00103 {
00104 static inline tuple<T1*,T2*,T3*,T4*,T5*,T6*,T7*,T8,T9> apply()
00105 {
00106 return tuple<T1*,T2*,T3*,T4*,T5*,T6*,T7*,T8,T9>(0,0,0,0,0,0,0);
00107 }
00108 };
00109 template<typename T1, typename T2, typename T3, typename T4, typename T5,
00110 typename T6, typename T7, typename T8, typename T9>
00111 struct InitialiserHelper<tuple<T1*,T2*,T3*,T4*,T5*,T6*,T7*,T8*,T9>,8>
00112 {
00113 static inline tuple<T1*,T2*,T3*,T4*,T5*,T6*,T7*,T8*,T9> apply()
00114 {
00115 return tuple<T1*,T2*,T3*,T4*,T5*,T6*,T7*,T8*,T9>(0,0,0,0,0,0,0,0);
00116 }
00117 };
00118
00119 template<typename T1, typename T2, typename T3, typename T4, typename T5,
00120 typename T6, typename T7, typename T8, typename T9>
00121 struct InitialiserHelper<tuple<T1*,T2*,T3*,T4*,T5*,T6*,T7*,T8*,T9*>,9>
00122 {
00123 static inline tuple<T1*,T2*,T3*,T4*,T5*,T6*,T7*,T8*,T9*> apply()
00124 {
00125 return tuple<T1*,T2*,T3*,T4*,T5*,T6*,T7*,T8*,T9*>(0,0,0,0,0,0,0,0,0);
00126 }
00127 };
00128 }
00129
00130 template<typename T1, typename T2, typename T3, typename T4, typename T5,
00131 typename T6, typename T7, typename T8, typename T9>
00132 class NullPointerInitialiser<tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> >
00133 {
00134 public:
00135 typedef tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> ResultType;
00136
00137 static inline ResultType apply()
00138 {
00139 return InitialiserHelper<ResultType, tuple_size<ResultType>::value>::apply();
00140 }
00141 };
00142
00149 template <class Tuple>
00150 struct PointerPairDeletor {};
00151
00152 namespace
00153 {
00154
00155 template<class T, int s>
00156 struct PointerDeletor
00157 {};
00158
00159 template<typename T1, typename T2, typename T3, typename T4, typename T5,
00160 typename T6, typename T7, typename T8, typename T9, int s>
00161 struct PointerDeletor<tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9>,s>
00162 {
00163 static void apply(tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9>& t)
00164 {
00165
00166 PointerDeletor<tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9>,s-1>::apply(t);
00167 delete get<s-1>(t);
00168 }
00169 };
00170 template<typename T1, typename T2, typename T3, typename T4, typename T5,
00171 typename T6, typename T7, typename T8, typename T9>
00172 struct PointerDeletor<tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9>,0>
00173 {
00174 static void apply(tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9>& t)
00175 {}
00176 };
00177 }
00178
00179 template<typename T1, typename T2, typename T3, typename T4, typename T5,
00180 typename T6, typename T7, typename T8, typename T9>
00181 struct PointerPairDeletor<tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> >
00182 {
00183 static void apply(tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9>& t)
00184 {
00185 PointerDeletor<tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9>,
00186 tuple_size<tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> >::value>
00187 ::apply(t);
00188 }
00189
00190 };
00191
00195 template <class Tuple>
00196 struct Length {};
00197
00198 template<typename T1, typename T2, typename T3, typename T4, typename T5,
00199 typename T6, typename T7, typename T8, typename T9>
00200 struct Length<tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> >
00201 {
00202 enum{
00203 value=tuple_size<tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> >::value
00204 };
00205 };
00206
00207 namespace
00208 {
00215 template<template <class> class Eval, typename T, int s>
00216 struct ForEachTypeHelper
00217 {};
00218
00219 template<template <class> class Eval, typename T1, typename T2, typename T3, typename T4, typename T5,
00220 typename T6, typename T7, typename T8, typename T9>
00221 struct ForEachTypeHelper<Eval,tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9>,0>
00222 {
00223 typedef tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> Type;
00224 };
00225
00226
00227 template<template <class> class Eval, typename T1, typename T2, typename T3, typename T4, typename T5,
00228 typename T6, typename T7, typename T8, typename T9>
00229 struct ForEachTypeHelper<Eval,tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9>,1>
00230 {
00231 typedef tuple<typename Eval<T1>::Type,T2,T3,T4,T5,T6,T7,T8,T9> Type;
00232 };
00233
00234 template<template <class> class Eval, typename T1, typename T2, typename T3, typename T4, typename T5,
00235 typename T6, typename T7, typename T8, typename T9>
00236 struct ForEachTypeHelper<Eval,tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9>,2>
00237 {
00238 typedef tuple<typename Eval<T1>::Type,typename Eval<T2>::Type,T3,T4,T5,T6,T7,T8,T9> Type;
00239 };
00240
00241 template<template <class> class Eval, typename T1, typename T2, typename T3, typename T4, typename T5,
00242 typename T6, typename T7, typename T8, typename T9>
00243 struct ForEachTypeHelper<Eval,tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9>,3>
00244 {
00245 typedef tuple<typename Eval<T1>::Type,typename Eval<T2>::Type,typename Eval<T3>::Type,
00246 T4,T5,T6,T7,T8,T9> Type;
00247 };
00248
00249 template<template <class> class Eval, typename T1, typename T2, typename T3, typename T4, typename T5,
00250 typename T6, typename T7, typename T8, typename T9>
00251 struct ForEachTypeHelper<Eval,tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9>,4>
00252 {
00253 typedef tuple<typename Eval<T1>::Type,typename Eval<T2>::Type,typename Eval<T3>::Type,
00254 typename Eval<T4>::Type,T5,T6,T7,T8,T9> Type;
00255 };
00256
00257
00258 template<template <class> class Eval, typename T1, typename T2, typename T3, typename T4, typename T5,
00259 typename T6, typename T7, typename T8, typename T9>
00260 struct ForEachTypeHelper<Eval,tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9>,5>
00261 {
00262 typedef tuple<typename Eval<T1>::Type,typename Eval<T2>::Type,typename Eval<T3>::Type,
00263 typename Eval<T4>::Type,typename Eval<T5>::Type,T6,T7,T8,T9> Type;
00264 };
00265
00266
00267 template<template <class> class Eval, typename T1, typename T2, typename T3, typename T4, typename T5,
00268 typename T6, typename T7, typename T8, typename T9>
00269 struct ForEachTypeHelper<Eval,tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9>,6>
00270 {
00271 typedef tuple<typename Eval<T1>::Type,typename Eval<T2>::Type,typename Eval<T3>::Type,
00272 typename Eval<T4>::Type,typename Eval<T5>::Type,typename Eval<T6>::Type,
00273 T7,T8,T9> Type;
00274 };
00275
00276 template<template <class> class Eval, typename T1, typename T2, typename T3, typename T4, typename T5,
00277 typename T6, typename T7, typename T8, typename T9>
00278 struct ForEachTypeHelper<Eval,tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9>,7>
00279 {
00280 typedef tuple<typename Eval<T1>::Type,typename Eval<T2>::Type,typename Eval<T3>::Type,
00281 typename Eval<T4>::Type,typename Eval<T5>::Type,typename Eval<T6>::Type,
00282 typename Eval<T7>::Type,T8,T9> Type;
00283 };
00284
00285
00286 template<template <class> class Eval, typename T1, typename T2, typename T3, typename T4, typename T5,
00287 typename T6, typename T7, typename T8, typename T9>
00288 struct ForEachTypeHelper<Eval,tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9>,8>
00289 {
00290 typedef tuple<typename Eval<T1>::Type,typename Eval<T2>::Type,typename Eval<T3>::Type,
00291 typename Eval<T4>::Type,typename Eval<T5>::Type,typename Eval<T6>::Type,
00292 typename Eval<T7>::Type,typename Eval<T8>::Type,T9> Type;
00293 };
00294
00295 template<template <class> class Eval, typename T1, typename T2, typename T3, typename T4, typename T5,
00296 typename T6, typename T7, typename T8, typename T9>
00297 struct ForEachTypeHelper<Eval,tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9>,9>
00298 {
00299 typedef tuple<typename Eval<T1>::Type,typename Eval<T2>::Type,typename Eval<T3>::Type,
00300 typename Eval<T4>::Type,typename Eval<T5>::Type,typename Eval<T6>::Type,
00301 typename Eval<T7>::Type,typename Eval<T8>::Type,typename Eval<T9>::Type> Type;
00302 };
00303 }
00304
00305
00324 template <template <class> class TypeEvaluator, class TupleType>
00325 struct ForEachType {
00326 typedef typename ForEachTypeHelper<TypeEvaluator,TupleType,
00327 tuple_size<TupleType>::value>::Type Type;
00328
00329 };
00330
00331 namespace
00332 {
00333 template<int i, typename T1,typename F>
00334 struct Visitor
00335 {
00336 static inline void visit(F& func, T1& t1)
00337 {
00338 func.visit(get<tuple_size<T1>::value-i>(t1));
00339 Visitor<i-1,T1,F>::visit(func, t1);
00340 }
00341 };
00342
00343 template<typename T1,typename F>
00344 struct Visitor<0,T1,F>
00345 {
00346 static inline void visit(F& func, T1& t1)
00347 {}
00348 };
00349
00350 template<int i, typename T1, typename T2,typename F>
00351 struct PairVisitor
00352 {
00353 static inline void visit(F& func, T1& t1, T2& t2)
00354 {
00355 func.visit(get<tuple_size<T1>::value-i>(t1), get<tuple_size<T2>::value-i>(t2));
00356 PairVisitor<i-1,T1,T2,F>::visit(func, t1, t2);
00357 }
00358 };
00359
00360 template<typename T1, typename T2, typename F>
00361 struct PairVisitor<0,T1,T2,F>
00362 {
00363 static inline void visit(F& func, T1& t1, T2& t2)
00364 {}
00365 };
00366 }
00367
00401 template <class TupleType>
00402 class ForEachValue {
00403 public:
00406 ForEachValue(TupleType& tuple) : tuple_(tuple) {}
00407
00410 template <class Functor>
00411 void apply(Functor& f) {
00412 Visitor<tuple_size<TupleType>::value,TupleType,Functor>::visit(f, tuple_);
00413 }
00414 private:
00415 TupleType& tuple_;
00416 };
00417
00418
00419
00420
00434 template <class TupleType1, class TupleType2>
00435 class ForEachValuePair {
00436 public:
00440 ForEachValuePair(TupleType1& t1, TupleType2& t2) :
00441 tuple1_(t1),
00442 tuple2_(t2)
00443 {}
00444
00447 template <class Functor>
00448 void apply(Functor& f) {
00449 PairVisitor<tuple_size<TupleType1>::value,TupleType1,TupleType2,Functor>
00450 ::visit(f, tuple1_, tuple2_);
00451 }
00452 private:
00453 TupleType1& tuple1_;
00454 TupleType2& tuple2_;
00455 };
00456
00457
00463 template <int N, class Tuple>
00464 struct AtType {
00465 typename ElementType<Length<Tuple>::value - N - 1,
00466 Tuple>::Type Type;
00467 };
00468
00476 template <int N>
00477 struct At
00478 {
00479
00480 template<typename T1, typename T2, typename T3, typename T4, typename T5,
00481 typename T6, typename T7, typename T8, typename T9>
00482 static typename TupleAccessTraits<
00483 typename tuple_element<tuple_size<tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> >::value - N - 1,
00484 tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> >::type>::NonConstType
00485 get(tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9>& t)
00486 {
00487 return Dune::get<tuple_size<tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> >::value - N - 1>(t);
00488 }
00489
00490 template<typename T1, typename T2, typename T3, typename T4, typename T5,
00491 typename T6, typename T7, typename T8, typename T9>
00492 static typename TupleAccessTraits<
00493 typename tuple_element<tuple_size<tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> >::value - N - 1,
00494 tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> >::type>::ConstType
00495 get(const tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9>& t)
00496 {
00497 return Dune::get<tuple_size<tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> >::value - N - 1>(t);
00498 }
00499 };
00500
00501 }
00502
00503 #endif