utility.hh

Go to the documentation of this file.
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 //   template <template <class> class TypeEvaluator, class Head>
00158 //   struct ForEachType<TypeEvaluator, Pair<Head, Nil> > {
00159 //     //! For the storage element, Head is replaced by the expression provided
00160 //     //! by the TypeEvaluator helper template.
00161 //     typedef Pair<typename TypeEvaluator<Head>::Type, Nil> Type;
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   //- Definition ForEachValuePair class
00229   // Assertion: both tuples have the same length and the contained types are
00230   // compatible in the sense of the applied function object
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   //- Reverse element access
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

Generated on 12 Dec 2007 with Doxygen (ver 1.5.1)