dune-common  2.2.0
tuples.hh
Go to the documentation of this file.
00001 // -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
00002 // vi: set ts=8 sw=2 et sts=2:
00003 
00004 #ifndef DUNE_TUPLES_HH
00005 #define DUNE_TUPLES_HH
00006 
00007 #include<iostream>
00008 
00009 #include"typetraits.hh"
00010 #include"static_assert.hh"
00011 
00012 #ifdef HAVE_TUPLE
00013 #include <tuple>
00014 #elif defined HAVE_TR1_TUPLE
00015 #include <tr1/tuple>
00016 #endif
00017 
00018 namespace Dune{
00037   template<class T>
00038   struct TupleAccessTraits
00039   {
00040     typedef typename ConstantVolatileTraits<T>::ConstType& ConstType;
00041     typedef T& NonConstType;
00042     typedef const typename ConstantVolatileTraits<T>::UnqualifiedType& ParameterType;
00043   };
00044   
00045   template<class T>
00046   struct TupleAccessTraits<T*>
00047   {
00048     typedef typename ConstantVolatileTraits<T>::ConstType* ConstType;
00049     typedef T* NonConstType;
00050     typedef T* ParameterType;
00051   };
00052 
00053   template<class T>
00054   struct TupleAccessTraits<T&>
00055   {
00056     typedef T& ConstType;
00057     typedef T& NonConstType;
00058     typedef T& ParameterType;
00059   };
00060 
00061 #ifdef HAVE_TUPLE
00062   using std::tuple;
00063 #elif defined HAVE_TR1_TUPLE
00064   using std::tr1::tuple;
00065 #else
00066 
00069   struct Nil
00070   {};
00071 
00072   namespace
00073   {
00074     inline const Nil nullType()
00075     {
00076       return Nil();
00077     }
00078   }
00079 
00085   template<typename T1, typename TT>
00086   struct Pair
00087   {
00091     typedef T1 Type1;
00092     
00096     typedef TT Type2;
00097 //     enum{
00098 //     /**
00099 //      * @brief The number of values we hold.
00100 //      */
00101 //       values = 2;
00102 //     };
00103     
00117     template<typename T2, typename T3, typename T4, typename T5,
00118              typename T6, typename T7, typename T8, typename T9>
00119     Pair(typename TupleAccessTraits<T1>::ParameterType t1, T2& t2, T3& t3, T4& t4, T5& t5, 
00120          T6& t6, T7& t7, T8& t8, T9& t9);
00121 
00128     Pair(typename TupleAccessTraits<Type1>::ParameterType t1, TT& t2);
00129 
00130     Pair();
00131     
00136     template<typename U1, typename U2>
00137     Pair(const Pair<U1,U2>& other);
00138     
00143     template<typename U1, typename U2>
00144     Pair& operator=(const Pair<U1,U2>& other);
00145     
00146     Pair& operator=(const Pair& other);
00147     
00152     typename TupleAccessTraits<Type1>::NonConstType first();
00153     
00158     typename TupleAccessTraits<Type1>::ConstType 
00159     first() const;
00160 
00165     typename TupleAccessTraits<Type2>::NonConstType
00166     second();
00167     
00172     typename TupleAccessTraits<Type2>::ConstType 
00173     second() const;
00174 
00176     Type1 first_;
00178     Type2 second_;
00179     
00180   };
00181 
00186   template<typename T1>
00187   struct Pair<T1,Nil>
00188   {
00192     typedef T1 Type1;
00193 
00199     typedef Nil Type2;
00200 
00205     Pair(typename TupleAccessTraits<T1>::ParameterType first, const Nil&, const Nil&, const Nil&, const Nil&,
00206          const Nil&, const Nil&, const Nil&, const Nil&);
00207     
00212     Pair(typename TupleAccessTraits<T1>::ParameterType first, 
00213          const Nil&);
00214 
00215     Pair();
00216     
00220     template<typename T2>
00221     Pair(const Pair<T2,Nil>& other);
00222 
00226     template<typename T2>
00227     Pair& operator=(const Pair<T2,Nil>& other);
00228     
00232     Pair& operator=(const Pair& other);
00233 
00238     typename TupleAccessTraits<Type1>::NonConstType
00239     first();
00240     
00245     typename TupleAccessTraits<Type1>::ConstType 
00246     first() const;
00247 
00249     Type1 first_;
00250   };
00251   
00252     
00256   template<typename T1, typename T2, typename T3, typename T4, typename T5,
00257            typename T6, typename T7, typename T8, typename T9>
00258   struct TupleToPairs
00259   {
00260     typedef Pair<T1, typename TupleToPairs<T2,T3,T4,T5,T6,T7,T8,T9,Nil>::Type > Type;
00261   };
00262 
00266   template<typename T1>
00267   struct TupleToPairs<T1,Nil,Nil,Nil,Nil,Nil,Nil,Nil,Nil>
00268   {
00269     typedef Pair<T1,Nil> Type;
00270   };
00271   
00289   template<typename T1 = Nil, typename T2 = Nil, typename T3 = Nil, 
00290            typename T4 = Nil, typename T5 = Nil,typename T6 = Nil, 
00291            typename T7 = Nil, typename T8 = Nil, typename T9 = Nil>
00292   class tuple : public TupleToPairs<T1,T2,T3,T4,T5,T6,T7,T8,T9>::Type
00293   {
00294   public:
00296     typedef typename TupleToPairs<T1,T2,T3,T4,T5,T6,T7,T8,T9>::Type FirstPair;
00297 
00298     tuple()
00299     {}
00300 
00301     tuple(typename TupleAccessTraits<T1>::ParameterType t1)
00302       : FirstPair(t1, nullType(), nullType(), nullType(), 
00303                   nullType(), nullType(), nullType(), nullType(), 
00304                   nullType())
00305     {}
00306 
00307     tuple(typename TupleAccessTraits<T1>::ParameterType t1,
00308           typename TupleAccessTraits<T2>::ParameterType t2)
00309       : FirstPair(t1, t2, nullType(), nullType(), 
00310                   nullType(), nullType(), nullType(), nullType(), 
00311                   nullType())
00312     {}
00313 
00314     tuple(typename TupleAccessTraits<T1>::ParameterType t1,
00315           typename TupleAccessTraits<T2>::ParameterType t2,
00316           typename TupleAccessTraits<T3>::ParameterType t3)
00317       : FirstPair(t1, t2, t3, nullType(), 
00318                   nullType(), 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       : FirstPair(t1, t2, t3, t4, 
00327                   nullType(), nullType(), nullType(), nullType(), 
00328                   nullType())
00329     {}
00330 
00331     tuple(typename TupleAccessTraits<T1>::ParameterType t1,
00332           typename TupleAccessTraits<T2>::ParameterType t2,
00333           typename TupleAccessTraits<T3>::ParameterType t3,
00334           typename TupleAccessTraits<T4>::ParameterType t4,
00335           typename TupleAccessTraits<T5>::ParameterType t5)
00336       : FirstPair(t1, t2, t3, t4, 
00337                   t5, nullType(), nullType(), nullType(), 
00338                   nullType())
00339     {}
00340 
00341     tuple(typename TupleAccessTraits<T1>::ParameterType t1,
00342           typename TupleAccessTraits<T2>::ParameterType t2,
00343           typename TupleAccessTraits<T3>::ParameterType t3,
00344           typename TupleAccessTraits<T4>::ParameterType t4,
00345           typename TupleAccessTraits<T5>::ParameterType t5,
00346           typename TupleAccessTraits<T6>::ParameterType t6)
00347       : FirstPair(t1, t2, t3, t4, 
00348                   t5, t6, nullType(), nullType(), 
00349                   nullType())
00350     {}
00351 
00352     tuple(typename TupleAccessTraits<T1>::ParameterType t1,
00353           typename TupleAccessTraits<T2>::ParameterType t2,
00354           typename TupleAccessTraits<T3>::ParameterType t3,
00355           typename TupleAccessTraits<T4>::ParameterType t4,
00356           typename TupleAccessTraits<T5>::ParameterType t5,
00357           typename TupleAccessTraits<T6>::ParameterType t6,
00358           typename TupleAccessTraits<T7>::ParameterType t7)
00359       : FirstPair(t1, t2, t3, t4, 
00360                   t5, t6, t7, nullType(), 
00361                   nullType())
00362     {}
00363 
00364     tuple(typename TupleAccessTraits<T1>::ParameterType t1,
00365           typename TupleAccessTraits<T2>::ParameterType t2,
00366           typename TupleAccessTraits<T3>::ParameterType t3,
00367           typename TupleAccessTraits<T4>::ParameterType t4,
00368           typename TupleAccessTraits<T5>::ParameterType t5,
00369           typename TupleAccessTraits<T6>::ParameterType t6,
00370           typename TupleAccessTraits<T7>::ParameterType t7,
00371           typename TupleAccessTraits<T8>::ParameterType t8)
00372       : FirstPair(t1, t2, t3, t4,
00373                   t5, t6, t7, t8, 
00374                   nullType())
00375     {}
00376 
00377     tuple(typename TupleAccessTraits<T1>::ParameterType t1,
00378           typename TupleAccessTraits<T2>::ParameterType t2,
00379           typename TupleAccessTraits<T3>::ParameterType t3,
00380           typename TupleAccessTraits<T4>::ParameterType t4,
00381           typename TupleAccessTraits<T5>::ParameterType t5,
00382           typename TupleAccessTraits<T6>::ParameterType t6,
00383           typename TupleAccessTraits<T7>::ParameterType t7,
00384           typename TupleAccessTraits<T8>::ParameterType t8,
00385           typename TupleAccessTraits<T9>::ParameterType t9)
00386       : FirstPair(t1, t2, t3, t4, t5, t6, t7, t8, t9)
00387     {}
00388 
00389     template<class U1, class U2>
00390     tuple& operator=(const Pair<U1,U2>& other)
00391     {
00392       FirstPair::operator=(other);
00393       return *this;
00394     }
00395   };
00396 
00397 #endif
00398 
00399 #ifdef HAVE_TUPLE
00400   using std::tuple_element;
00401 #elif defined HAVE_TR1_TUPLE
00402   using std::tr1::tuple_element;
00403 #else
00404 
00407   template<int N, class Tuple>
00408   struct tuple_element
00409   {
00413     typedef typename tuple_element<N,typename Tuple::FirstPair>::type type;
00414     typedef typename tuple_element<N,typename Tuple::FirstPair>::type Type;
00415   };
00416   
00417   template<int N, typename T1, typename T2>
00418   struct tuple_element<N,Pair<T1,T2> >
00419   {
00423     typedef typename tuple_element<N-1,T2>::Type type;
00424     typedef typename tuple_element<N-1,T2>::Type Type;
00425   };
00426   
00430   template<typename T1, typename T2>
00431   struct tuple_element<0, Pair<T1,T2> >
00432   {
00436     typedef T1 type;
00437     typedef T1 Type;
00438   };
00439   
00440 #endif
00441 
00442 #if defined HAVE_TUPLE || defined HAVE_TR1_TUPLE
00443 #ifdef HAVE_TUPLE
00444   using std::get;
00445 #elif defined HAVE_TR1_TUPLE
00446   using std::tr1::get;
00447 #endif
00448 
00449 #else
00450 
00455   template<int N>
00456   struct Element
00457   {
00463     template<typename T1, typename T2>
00464     static typename TupleAccessTraits<
00465       typename tuple_element<N,Pair<T1,T2> >::type
00466     >::NonConstType
00467     get(Pair<T1,T2>& tuple)
00468     {
00469       return Element<N-1>::get(tuple.second());
00470     }
00471     
00477     template<typename T1, typename T2>
00478     static typename TupleAccessTraits<
00479       typename tuple_element<N,Pair<T1,T2> >::type
00480     >::ConstType
00481     get(const Pair<T1,T2>& tuple)
00482     {
00483       return Element<N-1>::get(tuple.second());
00484     }
00485   };
00486   
00490   template<>
00491   struct Element<0>
00492   {
00498     template<typename T1, typename T2>
00499     static typename TupleAccessTraits<T1>::NonConstType get(Pair<T1,T2>& tuple)
00500     {
00501       return tuple.first();
00502     }
00503     
00509     template<typename T1, typename T2>
00510     static typename TupleAccessTraits<T1>::ConstType get(const Pair<T1,T2>& tuple)
00511     {
00512       return tuple.first();
00513     }
00514   };
00515 
00516   template<int i, typename T1, typename T2, typename T3, typename T4,
00517            typename T5, typename T6, typename T7, typename T8, typename T9>
00518   typename TupleAccessTraits<typename tuple_element<i, tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> >::type>
00519   ::NonConstType 
00520   get(tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9>& t)
00521   {
00522     return Element<i>::get(t);
00523   }
00524 
00525   template<int i, typename T1, typename T2, typename T3, typename T4,
00526            typename T5, typename T6, typename T7, typename T8, typename T9>
00527   typename TupleAccessTraits<typename tuple_element<i, tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> >::type>
00528   ::ConstType 
00529   get(const tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9>& t)
00530   {
00531     return Element<i>::get(t);
00532   }
00533 
00534 #endif  
00535 
00536 #ifdef HAVE_TUPLE
00537   using std::tuple_size;
00538 #elif defined HAVE_TR1_TUPLE
00539   using std::tr1::tuple_size;
00540 #else
00541 
00545   template<class T>
00546   struct tuple_size
00547   {
00548     enum{ 
00549       // @brief The number of Elements in the tuple.
00550       value=tuple_size<typename T::FirstPair>::value
00551         };
00552     
00553     
00554   };
00555   
00556   template<typename T1, typename T2>
00557   struct tuple_size<Pair<T1,T2> >
00558   {
00559     enum{ value=1+tuple_size<T2>::value};
00560   };
00561   
00562   
00563   template<typename T1>
00564   struct tuple_size<Pair<T1,Nil> >
00565   {
00566     enum{ value=1};
00567   };
00568 
00569   template<>
00570   struct tuple_size<Pair<Nil,Nil> >
00571   {
00572     enum{ value=0};
00573   };
00574 #endif
00575   
00576 
00577 #ifdef HAVE_TUPLE    
00578   using std::tie;
00579   using std::make_tuple;
00580 #elif defined HAVE_TR1_TUPLE    
00581   using std::tr1::tie;
00582   using std::tr1::make_tuple;
00583 #endif
00584 
00585 
00586   template<int i>
00587   struct tuple_writer
00588   {
00589     template<class T>
00590     static std::ostream& put(std::ostream& os, const T& t, const char* delim=", ")
00591     {
00592       return tuple_writer<i-1>::put(os,t,delim)<<delim<<Dune::get<i-1>(t);
00593     }
00594 
00595     template< class T >
00596     static std::istream &get ( std::istream &is, T &t, const char *delim = "," )
00597     {
00598       tuple_writer< i-1 >::get( is, t, delim );
00599       for( const char *it = delim; is && (*it != 0); ++it )
00600       {
00601         char c = 0;
00602         is >> c;
00603         if( c != *it )
00604           is.setstate( std::ios::failbit );
00605       }
00606       return is >> Dune::get< i-1 >( t );
00607     }
00608   };
00609 
00610    template<>
00611   struct tuple_writer<1>
00612   {
00613     template<class T>
00614     static std::ostream& put(std::ostream& os, const T& t, const char* delim=", ")
00615     {
00616       return os<<Dune::get<0>(t);
00617     }
00618 
00619     template< class T >
00620     static std::istream &get ( std::istream &is, T &t, const char *delim = ", " )
00621     {
00622       return is >> Dune::get< 0 >( t );
00623     }
00624    };
00625   
00626   template<>
00627   struct tuple_writer<0>
00628   {
00629     template<class T>
00630     static std::ostream& put(std::ostream& os, const T& t, const char* delim=", ")
00631     {
00632       return os;
00633     }
00634 
00635     template< class T >
00636     static std::istream &get ( std::istream &is, T &t, const char *delim = ", " )
00637     {
00638       return is;
00639     }
00640   };
00641 
00642 #if defined HAVE_TUPLE || defined HAVE_TR1_TUPLE
00643 
00646   template<typename T1>
00647   inline std::ostream& operator<<( std::ostream& os, const tuple<T1> & t)
00648   {
00649     typedef tuple<T1> TupleT;
00650     return tuple_writer<tuple_size<TupleT>::value>::put(os, t);
00651   }
00652   
00653   template<typename T1, typename T2>
00654   inline std::ostream& operator<<( std::ostream& os, const tuple<T1,T2> & t)
00655   {
00656     typedef tuple<T1,T2> TupleT;
00657     return tuple_writer<tuple_size<TupleT>::value>::put(os, t);
00658   }
00659   
00660   template<typename T1, typename T2, typename T3>
00661   inline std::ostream& operator<<( std::ostream& os, const tuple<T1,T2,T3> & t)
00662   {
00663     typedef tuple<T1,T2,T3> TupleT;
00664     return tuple_writer<tuple_size<TupleT>::value>::put(os, t);
00665   }
00666   
00667   template<typename T1, typename T2, typename T3, typename T4>
00668   inline std::ostream& operator<<( std::ostream& os, const tuple<T1,T2,T3,T4> & t)
00669   {
00670     typedef tuple<T1,T2,T3,T4> TupleT;
00671     return tuple_writer<tuple_size<TupleT>::value>::put(os, t);
00672   }
00673   
00674   template<typename T1, typename T2, typename T3, typename T4, typename T5>
00675   inline std::ostream& operator<<( std::ostream& os, const tuple<T1,T2,T3,T4,T5> & t)
00676   {
00677     typedef tuple<T1,T2,T3,T4,T5> TupleT;
00678     return tuple_writer<tuple_size<TupleT>::value>::put(os, t);
00679   }
00680   
00681   template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
00682   inline std::ostream& operator<<( std::ostream& os, const tuple<T1,T2,T3,T4,T5,T6> & t)
00683   {
00684     typedef tuple<T1,T2,T3,T4,T5,T6> TupleT;
00685     return tuple_writer<tuple_size<TupleT>::value>::put(os, t);
00686   }
00687   
00688   template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
00689   inline std::ostream& operator<<( std::ostream& os, const tuple<T1,T2,T3,T4,T5,T6,T7> & t)
00690   {
00691     typedef tuple<T1,T2,T3,T4,T5,T6,T7> TupleT;
00692     return tuple_writer<tuple_size<TupleT>::value>::put(os, t);
00693   }
00694   
00695   template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7,
00696            typename T8>
00697   inline std::ostream& operator<<( std::ostream& os, const tuple<T1,T2,T3,T4,T5,T6,T7,T8> & t)
00698   {
00699     typedef tuple<T1,T2,T3,T4,T5,T6,T7,T8> TupleT;
00700     return tuple_writer<tuple_size<TupleT>::value>::put(os, t);
00701   }
00702   
00703   template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7,
00704            typename T8, typename T9>
00705   inline std::ostream& operator<<( std::ostream& os, const tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> & t)
00706   {
00707     typedef tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> TupleT;
00708     return tuple_writer<tuple_size<TupleT>::value>::put(os, t);
00709   }
00710   
00711   template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7,
00712            typename T8, typename T9, typename T10>
00713   inline std::ostream& operator<<( std::ostream& os, const tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> & t)
00714   {
00715     typedef tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> TupleT;
00716     return tuple_writer<tuple_size<TupleT>::value>::put(os, t);
00717   }
00718 
00722   template<typename T1>
00723   inline std::istream& operator>>( std::istream& is, tuple<T1> & t)
00724   {
00725     typedef tuple<T1> TupleT;
00726     return tuple_writer<tuple_size<TupleT>::value>::get(is, t);
00727   }
00728   
00729   template<typename T1, typename T2>
00730   inline std::istream& operator>>( std::istream& is, tuple<T1,T2> & t)
00731   {
00732     typedef tuple<T1,T2> TupleT;
00733     return tuple_writer<tuple_size<TupleT>::value>::get(is, t);
00734   }
00735   
00736   template<typename T1, typename T2, typename T3>
00737   inline std::istream& operator>>( std::istream& is, tuple<T1,T2,T3> & t)
00738   {
00739     typedef tuple<T1,T2,T3> TupleT;
00740     return tuple_writer<tuple_size<TupleT>::value>::get(is, t);
00741   }
00742   
00743   template<typename T1, typename T2, typename T3, typename T4>
00744   inline std::istream& operator>>( std::istream& is, tuple<T1,T2,T3,T4> & t)
00745   {
00746     typedef tuple<T1,T2,T3,T4> TupleT;
00747     return tuple_writer<tuple_size<TupleT>::value>::get(is, t);
00748   }
00749   
00750   template<typename T1, typename T2, typename T3, typename T4, typename T5>
00751   inline std::istream& operator>>( std::istream& is, tuple<T1,T2,T3,T4,T5> & t)
00752   {
00753     typedef tuple<T1,T2,T3,T4,T5> TupleT;
00754     return tuple_writer<tuple_size<TupleT>::value>::get(is, t);
00755   }
00756   
00757   template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
00758   inline std::istream& operator>>( std::istream& is, tuple<T1,T2,T3,T4,T5,T6> & t)
00759   {
00760     typedef tuple<T1,T2,T3,T4,T5,T6> TupleT;
00761     return tuple_writer<tuple_size<TupleT>::value>::get(is, t);
00762   }
00763   
00764   template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
00765   inline std::istream& operator>>( std::istream& is, tuple<T1,T2,T3,T4,T5,T6,T7> & t)
00766   {
00767     typedef tuple<T1,T2,T3,T4,T5,T6,T7> TupleT;
00768     return tuple_writer<tuple_size<TupleT>::value>::get(is, t);
00769   }
00770   
00771   template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7,
00772            typename T8>
00773   inline std::istream& operator>>( std::istream& is, tuple<T1,T2,T3,T4,T5,T6,T7,T8> & t)
00774   {
00775     typedef tuple<T1,T2,T3,T4,T5,T6,T7,T8> TupleT;
00776     return tuple_writer<tuple_size<TupleT>::value>::get(is, t);
00777   }
00778   
00779   template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7,
00780            typename T8, typename T9>
00781   inline std::istream& operator>>( std::istream& is, tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> & t)
00782   {
00783     typedef tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> TupleT;
00784     return tuple_writer<tuple_size<TupleT>::value>::get(is, t);
00785   }
00786   
00787   template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7,
00788            typename T8, typename T9, typename T10>
00789   inline std::istream& operator>>( std::istream& is, tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> & t)
00790   {
00791     typedef tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> TupleT;
00792     return tuple_writer<tuple_size<TupleT>::value>::get(is, t);
00793   }
00794 #else
00795 
00800   template<typename T1, typename T2, typename U1, typename U2>
00801   inline bool operator==(const Pair<T1,T2>& tuple1, const Pair<U1,U2>& tuple2)
00802   {
00803     return (tuple1.first()==tuple2.first() && tuple1.second()==tuple2.second());
00804   }
00805   
00811   template<typename T1, typename T2, typename U1, typename U2>
00812   inline bool operator!=(const Pair<T1,T2>& tuple1, const Pair<U1,U2>& tuple2)
00813   {
00814     return (tuple1.first()!=tuple2.first() || tuple1.second()!=tuple2.second());
00815   }
00816 
00822   template<typename T1, typename T2, typename U1, typename U2>
00823   inline bool operator<(const Pair<T1,T2>& tuple1, const Pair<U1,U2>& tuple2)
00824   {
00825     return tuple1.first() < tuple2.first()
00826       || (tuple1.first() == tuple2.first() && tuple1.second() < tuple2.second());
00827   }
00828 
00834   template<typename T1,typename U1>
00835   inline bool operator==(const Pair<T1,Nil>& tuple1, const Pair<U1,Nil>& tuple2)
00836   {
00837     return (tuple1.first()==tuple2.first());
00838   }
00839   
00845   template<typename T1, typename U1>
00846   inline bool operator!=(const Pair<T1,Nil>& tuple1, const Pair<U1,Nil>& tuple2)
00847   {
00848     dune_static_assert( (IsInteroperable<T1,U1>::value),
00849                         "T1 and U1 have to be interoperable, i.e., either "
00850                         "conversion from one to the other must exist." );
00851     return (tuple1.first()!=tuple2.first());
00852   }
00853 
00859   template<typename T1, typename U1>
00860   inline bool operator<(const Pair<T1,Nil>& tuple1, const Pair<U1,Nil>& tuple2)
00861   {
00862     return (tuple1.first()<tuple2.first());
00863   }
00864 
00872   template<typename T1,typename U1, typename U2>
00873   inline bool operator==(const Pair<T1,Nil>& tuple1, const Pair<U1,U2>& tuple2)
00874   {
00875     return false;
00876   }
00877   
00884   template<typename T1, typename U1, typename U2>
00885   inline bool operator!=(const Pair<T1,Nil>& tuple1, const Pair<U1,U2>& tuple2)
00886   {
00887     return true;
00888   }
00889 
00890 
00897   template<typename T1, typename T2, typename U1>
00898   inline bool operator==(const Pair<T1,T2>& tuple1, const Pair<U1,Nil>& tuple2)
00899   {
00900     return false;
00901   }
00902   
00909   template<typename T1, typename T2, typename U1>
00910   inline bool operator!=(const Pair<T1,T2>& tuple1, const Pair<U1,Nil>& tuple2)
00911   {
00912     return true;
00913   }
00914 
00920   template<typename T1, typename T2>
00921   inline Pair<T1,T2> makePair(const T1& first, const T2& second)
00922   {
00923     return Pair<T1,T2>(first, second);
00924   }
00925 
00929   template<typename T1, typename T2>
00930   inline std::ostream& operator<<(std::ostream& os, const Pair<T1,T2>& pair)
00931   {
00932     os<<pair.first()<<" "<<pair.second();
00933     return os;
00934   }
00935 
00936   template<typename T1>
00937   inline std::ostream& operator<<(std::ostream& os, const Pair<T1,Nil>& pair)
00938   {
00939     os<<pair.first();
00940     return os;
00941   }
00942 
00946   template<typename T1, typename T2>
00947   inline std::istream& operator>>(std::istream& is, Pair<T1,T2>& pair)
00948   {
00949     return is >> pair.first() >> pair.second();
00950   }
00951 
00952   template<typename T1>
00953   inline std::istream& operator>>(std::istream& is, Pair<T1,Nil>& pair)
00954   {
00955     return is >> pair.first();
00956   }
00957 
00958   template<class T1>
00959   inline tuple<T1&> tie(T1& t1) {
00960     return tuple<T1&> (t1);
00961   }
00962 
00963   template<class T1, class T2>
00964   inline tuple<T1&, T2&> tie(T1& t1, T2& t2) {
00965     return tuple<T1&, T2&> (t1, t2);
00966   }
00967 
00968   template<class T1, class T2, class T3>
00969   inline tuple<T1&, T2&, T3&> tie(T1& t1, T2& t2, T3& t3) {
00970     return tuple<T1&, T2&, T3&> (t1, t2, t3);
00971   }
00972 
00973   template<class T1, class T2, class T3, class T4>
00974   inline tuple<T1&, T2&, T3&, T4&> tie(T1& t1, T2& t2, T3& t3, T4& t4) {
00975     return tuple<T1&, T2&, T3&, T4&> (t1, t2, t3, t4);
00976   }
00977 
00978   template<class T1, class T2, class T3, class T4, class T5>
00979   inline tuple<T1&, T2&, T3&, T4&, T5&>
00980   tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) {
00981     return tuple<T1&, T2&, T3&, T4&, T5&> (t1, t2, t3, t4, t5);
00982   }
00983 
00984   template<class T1, class T2, class T3, class T4, class T5, class T6>
00985   inline tuple<T1&, T2&, T3&, T4&, T5&, T6&>
00986   tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6) {
00987     return tuple<T1&, T2&, T3&, T4&, T5&, T6&> (t1, t2, t3, t4, t5, t6);
00988   }
00989 
00990   template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
00991   inline tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&>
00992   tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7) {
00993     return tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&> (t1, t2, t3, t4, t5, t6, t7);
00994   }
00995 
00996   template<class T1, class T2, class T3, class T4, class T5, class T6, class T7,
00997            class T8>
00998   inline tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&>
00999   tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8) {
01000     return tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&>
01001       (t1, t2, t3, t4, t5, t6, t7, t8);
01002   }
01003 
01004   template<class T1, class T2, class T3, class T4, class T5, class T6, class T7,
01005            class T8, class T9>
01006   inline tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&, T9&>
01007   tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8, T9& t9) {
01008     return tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&, T9&>
01009       (t1, t2, t3, t4, t5, t6, t7, t8, t9);
01010   }
01011 
01012   template<class T1>
01013   inline tuple<T1> make_tuple(const T1& t1) {
01014     return tuple<T1> (t1);
01015   }
01016 
01017   template<class T1, class T2>
01018   inline tuple<T1, T2> make_tuple(const T1& t1, const T2& t2) {
01019     return tuple<T1, T2> (t1, t2);
01020   }
01021 
01022   template<class T1, class T2, class T3>
01023   inline tuple<T1, T2, T3> make_tuple(const T1& t1, const T2& t2, const T3& t3) {
01024     return tuple<T1, T2, T3> (t1, t2, t3);
01025   }
01026 
01027   template<class T1, class T2, class T3, class T4>
01028   inline tuple<T1, T2, T3, T4> make_tuple(const T1& t1, const T2& t2, const T3& t3, const T4& t4) {
01029     return tuple<T1, T2, T3, T4> (t1, t2, t3, t4);
01030   }
01031 
01032   template<class T1, class T2, class T3, class T4, class T5>
01033   inline tuple<T1, T2, T3, T4, T5>
01034   make_tuple(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5) {
01035     return tuple<T1, T2, T3, T4, T5> (t1, t2, t3, t4, t5);
01036   }
01037 
01038   template<class T1, class T2, class T3, class T4, class T5, class T6>
01039   inline tuple<T1, T2, T3, T4, T5, T6>
01040   make_tuple(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6) {
01041     return tuple<T1, T2, T3, T4, T5, T6> (t1, t2, t3, t4, t5, t6);
01042   }
01043 
01044   template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
01045   inline tuple<T1, T2, T3, T4, T5, T6, T7>
01046   make_tuple(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6,
01047              const T7& t7) {
01048     return tuple<T1, T2, T3, T4, T5, T6, T7> (t1, t2, t3, t4, t5, t6, t7);
01049   }
01050 
01051   template<class T1, class T2, class T3, class T4, class T5, class T6, class T7,
01052            class T8>
01053   inline tuple<T1, T2, T3, T4, T5, T6, T7, T8>
01054   make_tuple(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6,
01055              const T7& t7, const T8& t8) {
01056     return tuple<T1, T2, T3, T4, T5, T6, T7, T8>
01057       (t1, t2, t3, t4, t5, t6, t7, t8);
01058   }
01059 
01060   template<class T1, class T2, class T3, class T4, class T5, class T6, class T7,
01061            class T8, class T9>
01062   inline tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>
01063   make_tuple(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6,
01064              const  T7& t7, const T8& t8, const T9& t9) {
01065     return tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>
01066       (t1, t2, t3, t4, t5, t6, t7, t8, t9);
01067   }
01068 
01069   template<typename T1, typename TT>
01070   template<typename T2, typename T3, typename T4, typename T5,
01071            typename T6, typename T7, typename T8, typename T9>
01072   inline Pair<T1,TT>::Pair(typename TupleAccessTraits<T1>::ParameterType first, 
01073                            T2& t2, T3& t3, T4& t4, T5& t5, 
01074                            T6& t6, T7& t7, T8& t8, T9& t9)
01075     : first_(first), second_(t2,t3,t4,t5,t6,t7,t8,t9, nullType())
01076   {}
01077 
01078   template <typename T1, typename TT>
01079   inline Pair<T1, TT>::Pair(typename TupleAccessTraits<T1>::ParameterType first, TT& second) 
01080     : first_(first), second_(second)
01081   {}
01082   
01083   template<typename T1, typename T2>
01084   inline Pair<T1,T2>::Pair()
01085     : first_(), second_()
01086   {}
01087   
01088   template<typename T1, typename T2>
01089   template<typename U1, typename U2>
01090   inline Pair<T1,T2>::Pair(const Pair<U1,U2>& other)
01091     : first_(other.first_), second_(other.second_)
01092   {}
01093   
01094   template<typename T1, typename T2>
01095   template<typename U1, typename U2>
01096   inline Pair<T1,T2>& Pair<T1,T2>::operator=(const Pair<U1,U2>& other)
01097   {
01098     first_=other.first_;
01099     second_=other.second_;
01100     return *this;
01101   }
01102 
01103   template<typename T1, typename T2>
01104   inline Pair<T1,T2>& Pair<T1,T2>::operator=(const Pair& other)
01105   {
01106     first_=other.first_;
01107     second_=other.second_;
01108     return *this;
01109   }
01110 
01111   template<typename T1, typename T2>
01112   inline typename TupleAccessTraits<T1>::NonConstType 
01113   Pair<T1,T2>::first()
01114   {
01115     return first_;
01116   }
01117   
01118   template<typename T1, typename T2>
01119   inline typename TupleAccessTraits<T1>::ConstType 
01120   Pair<T1,T2>::first() const
01121   {
01122     return first_;
01123   }
01124  
01125   
01126   template<typename T1, typename T2>
01127   inline typename TupleAccessTraits<T2>::NonConstType
01128   Pair<T1,T2>::second()
01129   {
01130     return second_;
01131   }
01132   
01133   template<typename T1, typename T2>
01134   inline typename TupleAccessTraits<T2>::ConstType
01135   Pair<T1,T2>::second() const
01136   {
01137     return second_;
01138   }
01139 
01140   template<typename T1>
01141   inline Pair<T1,Nil>::Pair(typename TupleAccessTraits<T1>::ParameterType first,
01142                             const Nil&, const Nil&, const Nil&, const Nil&,
01143                             const Nil&, const Nil&, const Nil&, const Nil&)
01144     : first_(first)
01145   {}
01146 
01147   template <typename T1>
01148   inline Pair<T1, Nil>::Pair(typename TupleAccessTraits<T1>::ParameterType first,
01149                              const Nil&)
01150     : first_(first)
01151   {}
01152 
01153   template<typename T1>
01154   inline Pair<T1,Nil>::Pair()
01155     : first_()
01156   {}
01157   
01158   template<typename T1>
01159   template<typename T2>
01160   inline Pair<T1,Nil>::Pair(const Pair<T2,Nil>& other)
01161     : first_(other.first_)
01162   {}
01163 
01164   template<typename T1>
01165   template<typename T2>
01166   Pair<T1,Nil>& Pair<T1,Nil>::operator=(const Pair<T2,Nil>& other)
01167   {
01168     first_ = other.first_;
01169     return *this;
01170   }
01171 
01172   
01173   template<typename T1>
01174   Pair<T1,Nil>& Pair<T1,Nil>::operator=(const Pair& other)
01175   {
01176     first_ = other.first_;
01177     return *this;
01178   }
01179 
01180   template<typename T1>
01181   inline typename TupleAccessTraits<T1>::NonConstType 
01182   Pair<T1,Nil>::first()
01183   {
01184     return first_;
01185   }
01186   
01187   template<typename T1>
01188   inline typename TupleAccessTraits<T1>::ConstType 
01189   Pair<T1,Nil>::first() const
01190   {
01191     return first_;
01192   }
01193  
01195 #endif
01196 }
01197 #endif