00001 #ifndef DUNE_UTILITY_HH
00002 #define DUNE_UTILITY_HH
00003
00004 #include "tuples.hh"
00005
00006 namespace Dune {
00007
00025 template <class PairT>
00026 class NullPointerInitialiser {};
00027
00031 template <class Head, class Tail>
00032 class NullPointerInitialiser<Pair<Head*, Tail> > {
00033 public:
00036 typedef Pair<Head*, Tail> ResultType;
00037 public:
00039 static inline ResultType apply() {
00040 return ResultType(0, NullPointerInitialiser<Tail>::apply());
00041 }
00042 };
00043
00047 template <>
00048 class NullPointerInitialiser<Nil> {
00049 public:
00051 typedef Nil ResultType;
00052 public:
00054 static inline ResultType apply() {
00055 return Nil();
00056 }
00057 };
00058
00065 template <class PairT>
00066 struct PointerPairDeletor {};
00067
00071 template <class Head, class Tail>
00072 struct PointerPairDeletor<Pair<Head*, Tail> > {
00075 static void apply(Pair<Head*, Tail>& p) {
00076 delete p.first();
00077 PointerPairDeletor<Tail>::apply(p.second());
00078 }
00079 };
00080
00084 template <class Head>
00085 struct PointerPairDeletor<Pair<Head*, Nil> > {
00087 static void apply(Pair<Head*, Nil>& p) {
00088 delete p.first();
00089 }
00090 };
00091
00095 template <class PairT>
00096 struct Length {};
00097
00103 template <class Head, class Tail>
00104 struct Length<Pair<Head, Tail> > {
00106 enum { value = 1 + Length<Tail>::value };
00107 };
00108
00112 template <>
00113 struct Length<Nil> {
00115 enum { value = 0 };
00116 };
00117
00136 template <template <class> class TypeEvaluator, class TupleType>
00137 struct ForEachType {};
00138
00142 template <template <class> class TypeEvaluator, class Head, class Tail>
00143 struct ForEachType<TypeEvaluator, Pair<Head, Tail> > {
00145 typedef Pair<typename TypeEvaluator<Head>::Type,
00146 typename ForEachType<TypeEvaluator, Tail>::Type> Type;
00147 };
00148
00152 template <template <class> class TypeEvaluator>
00153 struct ForEachType<TypeEvaluator, Nil> {
00154 typedef Nil Type;
00155 };
00156
00157
00158
00159
00160
00161
00162
00163
00197 template <class TupleType>
00198 class ForEachValue {
00199 public:
00202 ForEachValue(TupleType& tuple) : tuple_(tuple) {}
00203
00206 template <class Functor>
00207 void apply(Functor& f) {
00208 apply(f, tuple_);
00209 }
00210
00211 private:
00213 template <class Functor, class Head>
00214 void apply(Functor& f, Pair<Head, Nil>& last) {
00215 f.visit(last.first());
00216 }
00217
00219 template <class Functor, class Head, class Tail>
00220 void apply(Functor& f, Pair<Head, Tail>& pair) {
00221 f.visit(pair.first());
00222 apply(f, pair.second());
00223 }
00224 private:
00225 TupleType& tuple_;
00226 };
00227
00228
00229
00230
00244 template <class TupleType1, class TupleType2>
00245 class ForEachValuePair {
00246 public:
00250 ForEachValuePair(TupleType1& t1, TupleType2& t2) :
00251 tuple1_(t1),
00252 tuple2_(t2)
00253 {}
00254
00257 template <class Functor>
00258 void apply(Functor& f) {
00259 apply(f, tuple1_, tuple2_);
00260 }
00261
00262 private:
00264 template <class Functor, class Head1, class Head2>
00265 void apply(Functor& f, Pair<Head1, Nil>& last1, Pair<Head2, Nil>& last2) {
00266 f.visit(last1.first(), last2.first());
00267 }
00268
00270 template <class Functor, class Head1, class Tail1, class Head2,class Tail2>
00271 void apply(Functor& f, Pair<Head1, Tail1>& p1, Pair<Head2, Tail2>& p2) {
00272 f.visit(p1.first(), p2.first());
00273 apply(f, p1.second(), p2.second());
00274 }
00275
00276 private:
00277 TupleType1& tuple1_;
00278 TupleType2& tuple2_;
00279 };
00280
00281
00287 template <int N, class Tuple>
00288 struct AtType {
00289 typename ElementType<Length<Tuple>::value - N - 1,
00290 Tuple>::Type Type;
00291 };
00292
00300 template <int N>
00301 struct At
00302 {
00303 template <class T1, class T2>
00304 static typename ElementType<Length<Pair<T1, T2> >::value - N - 1,
00305 Pair<T1, T2> >::Type&
00306 get(Pair<T1, T2>& tuple) {
00307 return Element<Length<Pair<T1, T2> >::value - N - 1>::get(tuple);
00308 }
00309
00310 template <class T1, class T2>
00311 static const typename ElementType<Length<Pair<T1, T2> >::value - N - 1,
00312 Pair<T1, T2> >::Type&
00313 get(const Pair<T1, T2>& tuple) {
00314 return Element<Length<Pair<T1, T2> >::value - N - 1>::get(tuple);
00315 }
00316
00317 };
00318
00319 }
00320
00321 #endif