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 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   //- Definition ForEachValuePair class
00419   // Assertion: both tuples have the same length and the contained types are
00420   // compatible in the sense of the applied function object
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   //- Reverse element access
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
Generated on Mon Apr 26 10:45:22 2010 for dune-common by  doxygen 1.6.3