00001
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
00084
00085
00086
00087
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