tuples.hh

Go to the documentation of this file.
00001 // $Id: tuples.hh 4897 2007-04-10 12:13:22Z sander $
00002 #ifndef DUNE_TUPLES_HH
00003 #define DUNE_TUPLES_HH
00004 
00005 #include<ostream>
00006 #include"typetraits.hh"
00007 #include"helpertemplates.hh"
00008 
00009 namespace Dune 
00010 {
00031   struct Nil
00032   {};
00033 
00034   namespace
00035   {
00036     inline const Nil nullType()
00037     {
00038       return Nil();
00039     }
00040   }
00041   
00042   template<class T>
00043   struct TupleAccessTraits
00044   {
00045     typedef typename ConstantVolatileTraits<T>::ConstType& ConstType;
00046     typedef T& NonConstType;
00047     typedef const typename ConstantVolatileTraits<T>::UnqualifiedType& ParameterType;
00048   };
00049   
00050   template<class T>
00051   struct TupleAccessTraits<T*>
00052   {
00053     typedef typename ConstantVolatileTraits<T>::ConstType* ConstType;
00054     typedef T* NonConstType;
00055     typedef T* ParameterType;
00056   };
00057 
00058   template<class T>
00059   struct TupleAccessTraits<T&>
00060   {
00061     typedef typename ConstantVolatileTraits<T>::ConstType& ConstType;
00062     typedef T& NonConstType;
00063     typedef T& ParameterType;
00064   };
00065   
00071   template<typename T1, typename TT>
00072   struct Pair
00073   {
00077     typedef T1 Type1;
00078     
00082     typedef TT Type2;
00083 //     enum{
00084 //     /**
00085 //      * @brief The number of values we hold.
00086 //      */
00087 //       values = 2;
00088 //     };
00089     
00096     template<typename T2, typename T3, typename T4, typename T5,
00097              typename T6, typename T7, typename T8, typename T9>
00098     Pair(typename TupleAccessTraits<T1>::ParameterType t1, T2& t2, T3& t3, T4& t4, T5& t5, 
00099          T6& t6, T7& t7, T8& t8, T9& t9);
00100 
00107     Pair(typename TupleAccessTraits<Type1>::ParameterType t1, TT& t2);
00108 
00109     Pair();
00110     
00115     template<typename U1, typename U2>
00116     Pair(const Pair<U1,U2>& other);
00117     
00122     template<typename U1, typename U2>
00123     Pair& operator=(const Pair<U1,U2>& other);
00124     
00125     Pair& operator=(const Pair& other);
00126     
00131     typename TupleAccessTraits<Type1>::NonConstType first();
00132     
00137     typename TupleAccessTraits<Type1>::ConstType 
00138     first() const;
00139 
00144     typename TupleAccessTraits<Type2>::NonConstType
00145     second();
00146     
00151     typename TupleAccessTraits<Type2>::ConstType 
00152     second() const;
00153 
00155     Type1 first_;
00157     Type2 second_;
00158     
00159   };
00160 
00165   template<typename T1>
00166   struct Pair<T1,Nil>
00167   {
00171     typedef T1 Type1;
00172 
00178     typedef Nil Type2;
00179 
00185     Pair(typename TupleAccessTraits<T1>::ParameterType first, const Nil&, const Nil&, const Nil&, const Nil&,
00186          const Nil&, const Nil&, const Nil&, const Nil&);
00187     
00193     Pair(typename TupleAccessTraits<T1>::ParameterType first, 
00194          const Nil&);
00195 
00196     Pair();
00197     
00201     template<typename T2>
00202     Pair(const Pair<T2,Nil>& other);
00203 
00207     template<typename T2>
00208     Pair& operator=(const Pair<T2,Nil>& other);
00209     
00213     Pair& operator=(const Pair& other);
00214 
00219     typename TupleAccessTraits<Type1>::NonConstType
00220     first();
00221     
00226     typename TupleAccessTraits<Type1>::ConstType 
00227     first() const;
00228 
00230     Type1 first_;
00231   };
00232   
00233     
00237   template<typename T1, typename T2, typename T3, typename T4, typename T5,
00238            typename T6, typename T7, typename T8, typename T9>
00239   struct TupleToPairs
00240   {
00241     typedef Pair<T1, typename TupleToPairs<T2,T3,T4,T5,T6,T7,T8,T9,Nil>::Type > Type;
00242   };
00243 
00247   template<typename T1>
00248   struct TupleToPairs<T1,Nil,Nil,Nil,Nil,Nil,Nil,Nil,Nil>
00249   {
00250     typedef Pair<T1,Nil> Type;
00251   };
00252   
00270   template<typename T1, typename T2 = Nil, typename T3 = Nil, 
00271            typename T4 = Nil, typename T5 = Nil,typename T6 = Nil, 
00272            typename T7 = Nil, typename T8 = Nil, typename T9 = Nil>
00273   class Tuple : public TupleToPairs<T1,T2,T3,T4,T5,T6,T7,T8,T9>::Type
00274   {
00275   public:
00277     typedef typename TupleToPairs<T1,T2,T3,T4,T5,T6,T7,T8,T9>::Type FirstPair;
00278 
00279     Tuple()
00280     {}
00281 
00282     Tuple(typename TupleAccessTraits<T1>::ParameterType t1)
00283       : FirstPair(t1, nullType(), nullType(), nullType(), 
00284                   nullType(), nullType(), nullType(), nullType(), 
00285                   nullType())
00286     {}
00287 
00288     Tuple(typename TupleAccessTraits<T1>::ParameterType t1,
00289           typename TupleAccessTraits<T2>::ParameterType t2)
00290       : FirstPair(t1, t2, nullType(), nullType(), 
00291                   nullType(), nullType(), nullType(), nullType(), 
00292                   nullType())
00293     {}
00294 
00295     Tuple(typename TupleAccessTraits<T1>::ParameterType t1,
00296           typename TupleAccessTraits<T2>::ParameterType t2,
00297           typename TupleAccessTraits<T3>::ParameterType t3)
00298       : FirstPair(t1, t2, t3, nullType(), 
00299                   nullType(), nullType(), nullType(), nullType(), 
00300                   nullType())
00301     {}
00302 
00303     Tuple(typename TupleAccessTraits<T1>::ParameterType t1,
00304           typename TupleAccessTraits<T2>::ParameterType t2,
00305           typename TupleAccessTraits<T3>::ParameterType t3,
00306           typename TupleAccessTraits<T4>::ParameterType t4)
00307       : FirstPair(t1, t2, t3, t4, 
00308                   nullType(), nullType(), nullType(), nullType(), 
00309                   nullType())
00310     {}
00311 
00312     Tuple(typename TupleAccessTraits<T1>::ParameterType t1,
00313           typename TupleAccessTraits<T2>::ParameterType t2,
00314           typename TupleAccessTraits<T3>::ParameterType t3,
00315           typename TupleAccessTraits<T4>::ParameterType t4,
00316           typename TupleAccessTraits<T5>::ParameterType t5)
00317       : FirstPair(t1, t2, t3, t4, 
00318                   t5, nullType(), nullType(), nullType(), 
00319                   nullType())
00320     {}
00321 
00322     Tuple(typename TupleAccessTraits<T1>::ParameterType t1,
00323           typename TupleAccessTraits<T2>::ParameterType t2,
00324           typename TupleAccessTraits<T3>::ParameterType t3,
00325           typename TupleAccessTraits<T4>::ParameterType t4,
00326           typename TupleAccessTraits<T5>::ParameterType t5,
00327           typename TupleAccessTraits<T6>::ParameterType t6)
00328       : FirstPair(t1, t2, t3, t4, 
00329                   t5, t6, nullType(), nullType(), 
00330                   nullType())
00331     {}
00332 
00333     Tuple(typename TupleAccessTraits<T1>::ParameterType t1,
00334           typename TupleAccessTraits<T2>::ParameterType t2,
00335           typename TupleAccessTraits<T3>::ParameterType t3,
00336           typename TupleAccessTraits<T4>::ParameterType t4,
00337           typename TupleAccessTraits<T5>::ParameterType t5,
00338           typename TupleAccessTraits<T6>::ParameterType t6,
00339           typename TupleAccessTraits<T7>::ParameterType t7)
00340       : FirstPair(t1, t2, t3, t4, 
00341                   t5, t6, t7, nullType(), 
00342                   nullType())
00343     {}
00344 
00345     Tuple(typename TupleAccessTraits<T1>::ParameterType t1,
00346           typename TupleAccessTraits<T2>::ParameterType t2,
00347           typename TupleAccessTraits<T3>::ParameterType t3,
00348           typename TupleAccessTraits<T4>::ParameterType t4,
00349           typename TupleAccessTraits<T5>::ParameterType t5,
00350           typename TupleAccessTraits<T6>::ParameterType t6,
00351           typename TupleAccessTraits<T7>::ParameterType t7,
00352           typename TupleAccessTraits<T8>::ParameterType t8)
00353       : FirstPair(t1, t2, t3, t4,
00354                   t5, t6, t7, t8, 
00355                   nullType())
00356     {}
00357 
00358     Tuple(typename TupleAccessTraits<T1>::ParameterType t1,
00359           typename TupleAccessTraits<T2>::ParameterType t2,
00360           typename TupleAccessTraits<T3>::ParameterType t3,
00361           typename TupleAccessTraits<T4>::ParameterType t4,
00362           typename TupleAccessTraits<T5>::ParameterType t5,
00363           typename TupleAccessTraits<T6>::ParameterType t6,
00364           typename TupleAccessTraits<T7>::ParameterType t7,
00365           typename TupleAccessTraits<T8>::ParameterType t8,
00366           typename TupleAccessTraits<T9>::ParameterType t9)
00367       : FirstPair(t1, t2, t3, t4, t5, t6, t7, t8, t9)
00368     {}
00369 
00370     template<class U1, class U2>
00371     Tuple& operator=(const Pair<U1,U2>& other)
00372     {
00373       FirstPair::operator=(other);
00374       return *this;
00375     }
00376   };
00377 
00381   template<int N, class Tuple>
00382   struct ElementType;
00383   
00384   template<int N, typename T1, typename T2>
00385   struct ElementType<N,Pair<T1,T2> >
00386   {
00390     typedef typename ElementType<N-1,T2>::Type Type;
00391   };
00392   
00396   template<typename T1, typename T2>
00397   struct ElementType<0, Pair<T1,T2> >
00398   {
00402     typedef T1 Type;
00403   };
00404   
00405   
00409   template<int N>
00410   struct Element
00411   {
00417     template<typename T1, typename T2>
00418     static typename TupleAccessTraits<
00419       typename ElementType<N,Pair<T1,T2> >::Type
00420     >::NonConstType
00421     get(Pair<T1,T2>& tuple)
00422     {
00423       return Element<N-1>::get(tuple.second());
00424     }
00425     
00431     template<typename T1, typename T2>
00432     static typename TupleAccessTraits<
00433       typename ElementType<N,Pair<T1,T2> >::Type
00434     >::ConstType
00435     get(const Pair<T1,T2>& tuple)
00436     {
00437       return Element<N-1>::get(tuple.second());
00438     }
00439   };
00440   
00444   template<>
00445   struct Element<0>
00446   {
00452     template<typename T1, typename T2>
00453     static typename TupleAccessTraits<T1>::NonConstType get(Pair<T1,T2>& tuple)
00454     {
00455       return tuple.first();
00456     }
00457     
00463     template<typename T1, typename T2>
00464     static typename TupleAccessTraits<T1>::ConstType get(const Pair<T1,T2>& tuple)
00465     {
00466       return tuple.first();
00467     }
00468   };
00469 
00475   template<typename T1, typename T2, typename U1, typename U2>
00476   inline bool operator==(const Pair<T1,T2>& tuple1, const Pair<U1,U2>& tuple2)
00477   {
00478     return (tuple1.first()==tuple2.first() && tuple1.second()==tuple2.second());
00479   }
00480   
00486   template<typename T1, typename T2, typename U1, typename U2>
00487   inline bool operator!=(const Pair<T1,T2>& tuple1, const Pair<U1,U2>& tuple2)
00488   {
00489     return (tuple1.first()!=tuple2.first() || tuple1.second()!=tuple2.second());
00490   }
00491 
00497   template<typename T1, typename T2, typename U1, typename U2>
00498   inline bool operator<(const Pair<T1,T2>& tuple1, const Pair<U1,U2>& tuple2)
00499   {
00500     return tuple1.first() < tuple2.first()
00501       || (tuple1.first() == tuple2.first() && tuple1.second() < tuple2.second());
00502   }
00503 
00509   template<typename T1,typename U1>
00510   inline bool operator==(const Pair<T1,Nil>& tuple1, const Pair<U1,Nil>& tuple2)
00511   {
00512     return (tuple1.first()==tuple2.first());
00513   }
00514   
00520   template<typename T1, typename U1>
00521   inline bool operator!=(const Pair<T1,Nil>& tuple1, const Pair<U1,Nil>& tuple2)
00522   {
00523     IsTrue<IsInteroperable<T1,U1>::value>::yes();
00524     return (tuple1.first()!=tuple2.first());
00525   }
00526 
00532   template<typename T1, typename U1>
00533   inline bool operator<(const Pair<T1,Nil>& tuple1, const Pair<U1,Nil>& tuple2)
00534   {
00535     return (tuple1.first()<tuple2.first());
00536   }
00537 
00545   template<typename T1,typename U1, typename U2>
00546   inline bool operator==(const Pair<T1,Nil>& tuple1, const Pair<U1,U2>& tuple2)
00547   {
00548     return false;
00549   }
00550   
00557   template<typename T1, typename U1, typename U2>
00558   inline bool operator!=(const Pair<T1,Nil>& tuple1, const Pair<U1,U2>& tuple2)
00559   {
00560     return true;
00561   }
00562 
00563 
00570   template<typename T1, typename T2, typename U1>
00571   inline bool operator==(const Pair<T1,T2>& tuple1, const Pair<U1,Nil>& tuple2)
00572   {
00573     return false;
00574   }
00575   
00582   template<typename T1, typename T2, typename U1>
00583   inline bool operator!=(const Pair<T1,T2>& tuple1, const Pair<U1,Nil>& tuple2)
00584   {
00585     return true;
00586   }
00587 
00593   template<typename T1, typename T2>
00594   inline Pair<T1,T2> makePair(const T1& first, const T2& second)
00595   {
00596     return Pair<T1,T2>(first, second);
00597   }
00598 
00602   template<typename T1, typename T2>
00603   inline std::ostream& operator<<(std::ostream& os, const Pair<T1,T2>& pair)
00604   {
00605     os<<pair.first()<<" "<<pair.second();
00606     return os;
00607   }
00608 
00609   template<typename T1>
00610   inline std::ostream& operator<<(std::ostream& os, const Pair<T1,Nil>& pair)
00611   {
00612     os<<pair.first();
00613     return os;
00614   }
00615 
00616   template<class T1>
00617   inline Tuple<T1&> tie(T1& t1) {
00618     return Tuple<T1&> (t1);
00619   }
00620 
00621   template<class T1, class T2>
00622   inline Tuple<T1&, T2&> tie(T1& t1, T2& t2) {
00623     return Tuple<T1&, T2&> (t1, t2);
00624   }
00625 
00626   template<class T1, class T2, class T3>
00627   inline Tuple<T1&, T2&, T3&> tie(T1& t1, T2& t2, T3& t3) {
00628     return Tuple<T1&, T2&, T3&> (t1, t2, t3);
00629   }
00630 
00631   template<class T1, class T2, class T3, class T4>
00632   inline Tuple<T1&, T2&, T3&, T4&> tie(T1& t1, T2& t2, T3& t3, T4& t4) {
00633     return Tuple<T1&, T2&, T3&, T4&> (t1, t2, t3, t4);
00634   }
00635 
00636   template<class T1, class T2, class T3, class T4, class T5>
00637   inline Tuple<T1&, T2&, T3&, T4&, T5&>
00638   tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) {
00639     return Tuple<T1&, T2&, T3&, T4&, T5&> (t1, t2, t3, t4, t5);
00640   }
00641 
00642   template<class T1, class T2, class T3, class T4, class T5, class T6>
00643   inline Tuple<T1&, T2&, T3&, T4&, T5&, T6&>
00644   tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6) {
00645     return Tuple<T1&, T2&, T3&, T4&, T5&, T6&> (t1, t2, t3, t4, t5, t6);
00646   }
00647 
00648   template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
00649   inline Tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&>
00650   tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7) {
00651     return Tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&> (t1, t2, t3, t4, t5, t6, t7);
00652   }
00653 
00654   template<class T1, class T2, class T3, class T4, class T5, class T6, class T7,
00655            class T8>
00656   inline Tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&>
00657   tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8) {
00658     return Tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&>
00659       (t1, t2, t3, t4, t5, t6, t7, t8);
00660   }
00661 
00662   template<class T1, class T2, class T3, class T4, class T5, class T6, class T7,
00663            class T8, class T9>
00664   inline Tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&, T9&>
00665   tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8, T9& t9) {
00666     return Tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&, T9&>
00667       (t1, t2, t3, t4, t5, t6, t7, t8, t9);
00668   }
00669 
00670 
00671   template<typename T1, typename TT>
00672   template<typename T2, typename T3, typename T4, typename T5,
00673            typename T6, typename T7, typename T8, typename T9>
00674   inline Pair<T1,TT>::Pair(typename TupleAccessTraits<T1>::ParameterType first, 
00675                            T2& t2, T3& t3, T4& t4, T5& t5, 
00676                            T6& t6, T7& t7, T8& t8, T9& t9)
00677     : first_(first), second_(t2,t3,t4,t5,t6,t7,t8,t9, nullType())
00678   {}
00679 
00680   template <typename T1, typename TT>
00681   inline Pair<T1, TT>::Pair(typename TupleAccessTraits<T1>::ParameterType first, TT& second) 
00682     : first_(first), second_(second)
00683   {}
00684   
00685   template<typename T1, typename T2>
00686   inline Pair<T1,T2>::Pair()
00687     : first_(), second_()
00688   {}
00689   
00690   template<typename T1, typename T2>
00691   template<typename U1, typename U2>
00692   inline Pair<T1,T2>::Pair(const Pair<U1,U2>& other)
00693     : first_(other.first_), second_(other.second_)
00694   {}
00695   
00696   template<typename T1, typename T2>
00697   template<typename U1, typename U2>
00698   inline Pair<T1,T2>& Pair<T1,T2>::operator=(const Pair<U1,U2>& other)
00699   {
00700     first_=other.first_;
00701     second_=other.second_;
00702     return *this;
00703   }
00704 
00705   template<typename T1, typename T2>
00706   inline Pair<T1,T2>& Pair<T1,T2>::operator=(const Pair& other)
00707   {
00708     first_=other.first_;
00709     second_=other.second_;
00710     return *this;
00711   }
00712 
00713   template<typename T1, typename T2>
00714   inline typename TupleAccessTraits<T1>::NonConstType 
00715   Pair<T1,T2>::first()
00716   {
00717     return first_;
00718   }
00719   
00720   template<typename T1, typename T2>
00721   inline typename TupleAccessTraits<T1>::ConstType 
00722   Pair<T1,T2>::first() const
00723   {
00724     return first_;
00725   }
00726  
00727   
00728   template<typename T1, typename T2>
00729   inline typename TupleAccessTraits<T2>::NonConstType
00730   Pair<T1,T2>::second()
00731   {
00732     return second_;
00733   }
00734   
00735   template<typename T1, typename T2>
00736   inline typename TupleAccessTraits<T2>::ConstType
00737   Pair<T1,T2>::second() const
00738   {
00739     return second_;
00740   }
00741 
00742   template<typename T1>
00743   inline Pair<T1,Nil>::Pair(typename TupleAccessTraits<T1>::ParameterType first,
00744                             const Nil&, const Nil&, const Nil&, const Nil&,
00745                             const Nil&, const Nil&, const Nil&, const Nil&)
00746     : first_(first)
00747   {}
00748 
00749   template <typename T1>
00750   inline Pair<T1, Nil>::Pair(typename TupleAccessTraits<T1>::ParameterType first,
00751                              const Nil&)
00752     : first_(first)
00753   {}
00754 
00755   template<typename T1>
00756   inline Pair<T1,Nil>::Pair()
00757     : first_()
00758   {}
00759   
00760   template<typename T1>
00761   template<typename T2>
00762   inline Pair<T1,Nil>::Pair(const Pair<T2,Nil>& other)
00763     : first_(other.first_)
00764   {}
00765 
00766   template<typename T1>
00767   template<typename T2>
00768   Pair<T1,Nil>& Pair<T1,Nil>::operator=(const Pair<T2,Nil>& other)
00769   {
00770     first_ = other.first_;
00771     return *this;
00772   }
00773 
00774   
00775   template<typename T1>
00776   Pair<T1,Nil>& Pair<T1,Nil>::operator=(const Pair& other)
00777   {
00778     first_ = other.first_;
00779     return *this;
00780   }
00781 
00782   template<typename T1>
00783   inline typename TupleAccessTraits<T1>::NonConstType 
00784   Pair<T1,Nil>::first()
00785   {
00786     return first_;
00787   }
00788   
00789   template<typename T1>
00790   inline typename TupleAccessTraits<T1>::ConstType 
00791   Pair<T1,Nil>::first() const
00792   {
00793     return first_;
00794   }
00795  
00796 }
00797 
00798 #endif

Generated on 12 Dec 2007 with Doxygen (ver 1.5.1)