diff --git a/common/test/tuplestest.cc b/common/test/tuplestest.cc index 99645c52012115c23d88687334894802d7a10238..a41aada992b985d3eac5ac22cdf1a94ba2c00392 100644 --- a/common/test/tuplestest.cc +++ b/common/test/tuplestest.cc @@ -73,12 +73,47 @@ int copyTest() return 0; } +int referenceTest() +{ + int k=5; + int& kr(k); + kr=20; + int i=50; + double d=-3.3; + long j=-666; + Tuple<int,double,long> t1(100, 5.0, 10); + Tuple<int,int,int> t2(1,5,9); + std::cout << "i="<<i<<" d="<<d<<" j="<<j<<std::endl; + + Tuple<int&,double&,long&> tr(i,d,j); + + std::cout <<"tr="<< tr<<std::endl; + + Tuple<int> i1(5); + Tuple<int&> ir(i); + ir=i1; + + t1=t2; + + std::cout <<"tr="<< tr<<std::endl; + std::cout <<"t1="<< t1<<std::endl; + tr=t1; + + if(tr!=t1) + return 1; + else + std::cout<<"t1="<<t1<< " tr="<<tr<<std::endl; + + + return 0; +} + int main(int argc, char** argv) { Tuple<float,int,double,char,std::string> tuple; test(tuple); test(static_cast<const Tuple<float,int,double,char,std::string>&>(tuple)); - exit(copyTest()+iteratorTupleTest()); + exit(copyTest()+iteratorTupleTest()+referenceTest()); } diff --git a/common/tuples.hh b/common/tuples.hh index 483f4a893e781de20e992375d5fee52547ee9f1c..7467e8c00b580c066e0cbbb5d20d5db07b0bc604 100644 --- a/common/tuples.hh +++ b/common/tuples.hh @@ -5,6 +5,7 @@ #define DUNE_TUPLES_HH #include <ostream> +#include "typetraits.hh" namespace Dune { @@ -31,6 +32,29 @@ namespace Dune struct Nil {}; + namespace + { + inline const Nil nullType() + { + return Nil(); + } + } + + template<class T> + struct TupleAccessTraits + { + typedef const T& ConstType; + typedef T& NonConstType; + typedef const typename ConstantVolatileTraits<T>::UnqualifiedType& ParameterType; + }; + + template<class T> + struct TupleAccessTraits<T&> + { + typedef T& ConstType; + typedef T& NonConstType; + typedef T& ParameterType; + }; /** * @brief A tuple consisting of two objects. @@ -38,9 +62,8 @@ namespace Dune * This is similar to std::pair */ template<typename T1, typename TT> - class Pair + struct Pair { - public: /** * @brief The type of the first field. */ @@ -65,9 +88,8 @@ namespace Dune */ template<typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> - Pair(const Type1& t1, const T2& t2, const T3& t3, - const T4& t4, const T5& t5, const T6& t6, const T7& t7, - const T8& t8, const T9& t9); + Pair(typename TupleAccessTraits<T1>::ParameterType t1, T2& t2, T3& t3, T4& t4, T5& t5, + T6& t6, T7& t7, T8& t8, T9& t9); /** * @brief Constructor @@ -75,7 +97,9 @@ namespace Dune * @param t1 The value of the first field. * @param t2 The value of the second field. */ - Pair(const Type1& t1, const TT& t2); + Pair(typename TupleAccessTraits<Type1>::ParameterType t1, TT& t2); + + Pair(); /** * @brief Copy Constructor for implicit type conversion @@ -89,33 +113,37 @@ namespace Dune * @param other The tuple to assign. */ template<typename U1, typename U2> - Pair<T1,TT>& operator=(const Pair<U1,U2>& other); + Pair& operator=(const Pair<U1,U2>& other); + + Pair& operator=(const Pair& other); /** * @brief Get the first value * @return The first value */ - Type1& first(); + typename TupleAccessTraits<Type1>::NonConstType first(); /** * @brief Get the first value * @return The first value */ - const Type1& first() const; + typename TupleAccessTraits<Type1>::ConstType + first() const; /** * @brief Get the second value * @return The first value */ - Type2& second(); + typename TupleAccessTraits<Type2>::NonConstType + second(); /** * @brief Get the first value * @return The second value */ - const Type2& second() const; + typename TupleAccessTraits<Type2>::ConstType + second() const; - private: /** @brief The value of the first field. */ Type1 first_; /** @brief The value of the second field. */ @@ -128,9 +156,8 @@ namespace Dune * Specialization of Pair that really is a single value. */ template<typename T1> - class Pair<T1,Nil> + struct Pair<T1,Nil> { - public: /** * @brief The type of the first field. */ @@ -148,7 +175,7 @@ namespace Dune * @param t1 The values for the first field. * @param t2 The value for the second field. */ - Pair(const Type1& first, const Nil&, const Nil&, const Nil&, const Nil&, + Pair(typename TupleAccessTraits<T1>::ParameterType first, const Nil&, const Nil&, const Nil&, const Nil&, const Nil&, const Nil&, const Nil&, const Nil&); /** @@ -156,7 +183,10 @@ namespace Dune * @param t1 The values for the first field. * @param t2 The value for the second field. */ - Pair(const Type1& first, const Nil&); + Pair(typename TupleAccessTraits<T1>::ParameterType first, + const Nil&); + + Pair(); /** * @brief Copy constructor for type conversion. @@ -168,21 +198,27 @@ namespace Dune * @brief Assignment operator for type conversion. */ template<typename T2> - Pair<T1,Nil>& operator=(const Pair<T2,Nil>& other); + Pair& operator=(const Pair<T2,Nil>& other); + + /** + * @brief Assignment operator. + */ + Pair& operator=(const Pair& other); /** * @brief Get the first value * @return The first value */ - Type1& first(); + typename TupleAccessTraits<Type1>::NonConstType + first(); /** * @brief Get the first value * @return The first value */ - const Type1& first() const; + typename TupleAccessTraits<Type1>::ConstType + first() const; - private: /** @brief The value of the first field.*/ Type1 first_; }; @@ -233,14 +269,103 @@ namespace Dune //! Type of the first Pair defining the Tuple typedef typename TupleToPairs<T1,T2,T3,T4,T5,T6,T7,T8,T9>::Type FirstPair; - Tuple(const T1& t1=T1(), const T2& t2=T2(), const T3& t3=T3(), - const T4& t4=T4(), const T5& t5=T5(), const T6& t6=T6(), - const T7& t7=T7(), const T8& t8=T8(), const T9& t9=T8()) - : TupleToPairs<T1,T2,T3,T4,T5,T6,T7,T8,T9>::Type(t1, t2, t3, - t4, t5, t6, - t7, t8, t9) + Tuple() + {} + + Tuple(typename TupleAccessTraits<T1>::ParameterType t1) + : FirstPair(t1, nullType(), nullType(), nullType(), + nullType(), nullType(), nullType(), nullType(), + nullType()) {} + Tuple(typename TupleAccessTraits<T1>::ParameterType t1, + typename TupleAccessTraits<T2>::ParameterType t2) + : FirstPair(t1, t2, nullType(), nullType(), + nullType(), nullType(), nullType(), nullType(), + nullType()) + {} + + Tuple(typename TupleAccessTraits<T1>::ParameterType t1, + typename TupleAccessTraits<T2>::ParameterType t2, + typename TupleAccessTraits<T3>::ParameterType t3) + : FirstPair(t1, t2, t3, nullType(), + nullType(), nullType(), nullType(), nullType(), + nullType()) + {} + + Tuple(typename TupleAccessTraits<T1>::ParameterType t1, + typename TupleAccessTraits<T2>::ParameterType t2, + typename TupleAccessTraits<T3>::ParameterType t3, + typename TupleAccessTraits<T4>::ParameterType t4) + : FirstPair(t1, t2, t3, t4, + nullType(), nullType(), nullType(), nullType(), + nullType()) + {} + + Tuple(typename TupleAccessTraits<T1>::ParameterType t1, + typename TupleAccessTraits<T2>::ParameterType t2, + typename TupleAccessTraits<T3>::ParameterType t3, + typename TupleAccessTraits<T4>::ParameterType t4, + typename TupleAccessTraits<T5>::ParameterType t5) + : FirstPair(t1, t2, t3, t4, + t5, nullType(), nullType(), nullType(), + nullType()) + {} + + Tuple(typename TupleAccessTraits<T1>::ParameterType t1, + typename TupleAccessTraits<T2>::ParameterType t2, + typename TupleAccessTraits<T3>::ParameterType t3, + typename TupleAccessTraits<T4>::ParameterType t4, + typename TupleAccessTraits<T5>::ParameterType t5, + typename TupleAccessTraits<T6>::ParameterType t6) + : FirstPair(t1, t2, t3, t4, + t5, t6, nullType(), nullType(), + nullType()) + {} + + Tuple(typename TupleAccessTraits<T1>::ParameterType t1, + typename TupleAccessTraits<T2>::ParameterType t2, + typename TupleAccessTraits<T3>::ParameterType t3, + typename TupleAccessTraits<T4>::ParameterType t4, + typename TupleAccessTraits<T5>::ParameterType t5, + typename TupleAccessTraits<T6>::ParameterType t6, + typename TupleAccessTraits<T7>::ParameterType t7) + : FirstPair(t1, t2, t3, t4, + t5, t6, t7, nullType(), + nullType()) + {} + + Tuple(typename TupleAccessTraits<T1>::ParameterType t1, + typename TupleAccessTraits<T2>::ParameterType t2, + typename TupleAccessTraits<T3>::ParameterType t3, + typename TupleAccessTraits<T4>::ParameterType t4, + typename TupleAccessTraits<T5>::ParameterType t5, + typename TupleAccessTraits<T6>::ParameterType t6, + typename TupleAccessTraits<T7>::ParameterType t7, + typename TupleAccessTraits<T8>::ParameterType t8) + : FirstPair(t1, t2, t3, t4, + t5, t6, t7, t8, + nullType()) + {} + + Tuple(typename TupleAccessTraits<T1>::ParameterType t1, + typename TupleAccessTraits<T2>::ParameterType t2, + typename TupleAccessTraits<T3>::ParameterType t3, + typename TupleAccessTraits<T4>::ParameterType t4, + typename TupleAccessTraits<T5>::ParameterType t5, + typename TupleAccessTraits<T6>::ParameterType t6, + typename TupleAccessTraits<T7>::ParameterType t7, + typename TupleAccessTraits<T8>::ParameterType t8, + typename TupleAccessTraits<T9>::ParameterType t9) + : FirstPair(t1, t2, t3, t4, t5, t6, t7, t8, t9) + {} + + template<class U1, class U2> + Tuple& operator=(const Pair<U1,U2>& other) + { + FirstPair::operator=(other); + return *this; + } }; /** @@ -452,20 +577,80 @@ namespace Dune return os; } + template<class T1> + inline Tuple<T1&> tie(T1& t1) { + return Tuple<T1&> (t1); + } + + template<class T1, class T2> + inline Tuple<T1&, T2&> tie(T1& t1, T2& t2) { + return Tuple<T1&, T2&> (t1, t2); + } + + template<class T1, class T2, class T3> + inline Tuple<T1&, T2&, T3&> tie(T1& t1, T2& t2, T3& t3) { + return Tuple<T1&, T2&, T3&> (t1, t2, t3); + } + + template<class T1, class T2, class T3, class T4> + inline Tuple<T1&, T2&, T3&, T4&> tie(T1& t1, T2& t2, T3& t3, T4& t4) { + return Tuple<T1&, T2&, T3&, T4&> (t1, t2, t3, t4); + } + + template<class T1, class T2, class T3, class T4, class T5> + inline Tuple<T1&, T2&, T3&, T4&, T5&> + tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) { + return Tuple<T1&, T2&, T3&, T4&, T5&> (t1, t2, t3, t4, t5); + } + + template<class T1, class T2, class T3, class T4, class T5, class T6> + inline Tuple<T1&, T2&, T3&, T4&, T5&, T6&> + tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6) { + return Tuple<T1&, T2&, T3&, T4&, T5&, T6&> (t1, t2, t3, t4, t5, t6); + } + + template<class T1, class T2, class T3, class T4, class T5, class T6, class T7> + inline Tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&> + tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7) { + return Tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&> (t1, t2, t3, t4, t5, t6, t7); + } + + template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, + class T8> + inline Tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&> + tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8) { + return Tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&> + (t1, t2, t3, t4, t5, t6, t7, t8); + } + + template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, + class T8, class T9> + inline Tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&, T9&> + tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8, T9& t9) { + return Tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&, T9&> + (t1, t2, t3, t4, t5, t6, t7, t8, t9); + } + + template<typename T1, typename TT> template<typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> - inline Pair<T1,TT>::Pair(const Type1& first, const T2& t2, const T3& t3, - const T4& t4, const T5& t5, const T6& t6, - const T7& t7, const T8& t8, const T9& t9) - : first_(first), second_(t2,t3,t4,t5,t6,t7,t8,t9,Nil()) + inline Pair<T1,TT>::Pair(typename TupleAccessTraits<T1>::ParameterType first, + T2& t2, T3& t3, T4& t4, T5& t5, + T6& t6, T7& t7, T8& t8, T9& t9) + : first_(first), second_(t2,t3,t4,t5,t6,t7,t8,t9, nullType()) {} template <typename T1, typename TT> - inline Pair<T1, TT>::Pair(const Type1& first, const TT& second) + inline Pair<T1, TT>::Pair(typename TupleAccessTraits<T1>::ParameterType first, TT& second) : first_(first), second_(second) {} + template<typename T1, typename T2> + inline Pair<T1,T2>::Pair() + : first_(), second_() + {} + template<typename T1, typename T2> template<typename U1, typename U2> inline Pair<T1,T2>::Pair(const Pair<U1,U2>& other) @@ -482,41 +667,60 @@ namespace Dune } template<typename T1, typename T2> - inline T1& Pair<T1,T2>::first() + inline Pair<T1,T2>& Pair<T1,T2>::operator=(const Pair& other) + { + first_=other.first_; + second_=other.second_; + return *this; + } + + template<typename T1, typename T2> + inline typename TupleAccessTraits<T1>::NonConstType + Pair<T1,T2>::first() { return first_; } template<typename T1, typename T2> - inline const T1& Pair<T1,T2>::first() const + inline typename TupleAccessTraits<T1>::ConstType + Pair<T1,T2>::first() const { return first_; } template<typename T1, typename T2> - inline T2& Pair<T1,T2>::second() + inline typename TupleAccessTraits<T2>::NonConstType + Pair<T1,T2>::second() { return second_; } template<typename T1, typename T2> - inline const T2& Pair<T1,T2>::second() const + inline typename TupleAccessTraits<T2>::ConstType + Pair<T1,T2>::second() const { return second_; } template<typename T1> - inline Pair<T1,Nil>::Pair(const Type1& first, const Nil&, const Nil&, const Nil&, const Nil&, + inline Pair<T1,Nil>::Pair(typename TupleAccessTraits<T1>::ParameterType first, + const Nil&, const Nil&, const Nil&, const Nil&, const Nil&, const Nil&, const Nil&, const Nil&) : first_(first) {} template <typename T1> - inline Pair<T1, Nil>::Pair(const Type1& first, const Nil&) + inline Pair<T1, Nil>::Pair(typename TupleAccessTraits<T1>::ParameterType first, + const Nil&) : first_(first) {} + template<typename T1> + inline Pair<T1,Nil>::Pair() + : first_() + {} + template<typename T1> template<typename T2> inline Pair<T1,Nil>::Pair(const Pair<T2,Nil>& other) @@ -531,14 +735,24 @@ namespace Dune return *this; } + + template<typename T1> + Pair<T1,Nil>& Pair<T1,Nil>::operator=(const Pair& other) + { + first_ = other.first_; + return *this; + } + template<typename T1> - inline T1& Pair<T1,Nil>::first() + inline typename TupleAccessTraits<T1>::NonConstType + Pair<T1,Nil>::first() { return first_; } template<typename T1> - inline const T1& Pair<T1,Nil>::first() const + inline typename TupleAccessTraits<T1>::ConstType + Pair<T1,Nil>::first() const { return first_; }