mapped_reference.hpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*-----------------------------------------------------------------------------+
  2. Copyright (c) 2009-2009: Joachim Faulhaber
  3. +------------------------------------------------------------------------------+
  4. Distributed under the Boost Software License, Version 1.0.
  5. (See accompanying file LICENCE.txt or copy at
  6. http://www.boost.org/LICENSE_1_0.txt)
  7. +-----------------------------------------------------------------------------*/
  8. #ifndef BOOST_ICL_DETAIL_MAPPED_REFERENCE_HPP_JOFA_091108
  9. #define BOOST_ICL_DETAIL_MAPPED_REFERENCE_HPP_JOFA_091108
  10. #include <boost/type_traits/is_const.hpp>
  11. #include <boost/type_traits/remove_const.hpp>
  12. #include <boost/mpl/if.hpp>
  13. #include <boost/icl/type_traits/is_concept_equivalent.hpp>
  14. namespace boost{namespace icl
  15. {
  16. template<class FirstT, class SecondT> class mapped_reference;
  17. //------------------------------------------------------------------------------
  18. template<class Type>
  19. struct is_mapped_reference_combinable{
  20. typedef is_mapped_reference_combinable type;
  21. BOOST_STATIC_CONSTANT(bool, value = false);
  22. };
  23. template<class FirstT, class SecondT>
  24. struct is_mapped_reference_combinable<std::pair<const FirstT,SecondT> >
  25. {
  26. typedef is_mapped_reference_combinable<std::pair<const FirstT,SecondT> > type;
  27. BOOST_STATIC_CONSTANT(bool, value = true);
  28. };
  29. template<class FirstT, class SecondT>
  30. struct is_mapped_reference_combinable<std::pair<FirstT,SecondT> >
  31. {
  32. typedef is_mapped_reference_combinable<std::pair<FirstT,SecondT> > type;
  33. BOOST_STATIC_CONSTANT(bool, value = true);
  34. };
  35. //------------------------------------------------------------------------------
  36. template<class Type>
  37. struct is_mapped_reference_or_combinable{
  38. typedef is_mapped_reference_or_combinable type;
  39. BOOST_STATIC_CONSTANT(bool, value = is_mapped_reference_combinable<Type>::value);
  40. };
  41. template<class FirstT, class SecondT>
  42. struct is_mapped_reference_or_combinable<mapped_reference<FirstT,SecondT> >
  43. {
  44. typedef is_mapped_reference_or_combinable<mapped_reference<FirstT,SecondT> > type;
  45. BOOST_STATIC_CONSTANT(bool, value = true);
  46. };
  47. //------------------------------------------------------------------------------
  48. template<class FirstT, class SecondT>
  49. class mapped_reference
  50. {
  51. private:
  52. mapped_reference& operator = (const mapped_reference&);
  53. public:
  54. typedef FirstT first_type;
  55. typedef SecondT second_type;
  56. typedef mapped_reference type;
  57. typedef typename
  58. mpl::if_<is_const<second_type>,
  59. second_type&,
  60. const second_type&>::type second_reference_type;
  61. typedef std::pair< first_type, second_type> std_pair_type;
  62. typedef std::pair<const first_type, second_type> key_std_pair_type;
  63. const first_type& first ;
  64. second_reference_type second;
  65. mapped_reference(const FirstT& fst, second_reference_type snd) : first(fst), second(snd){}
  66. template<class FstT, class SndT>
  67. mapped_reference(const mapped_reference<FstT, SndT>& source):
  68. first(source.first), second(source.second){}
  69. template<class FstT, class SndT>
  70. operator std::pair<FstT,SndT>(){ return std::pair<FstT,SndT>(first, second); }
  71. template<class Comparand>
  72. typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
  73. operator == (const Comparand& right)const
  74. { return first == right.first && second == right.second; }
  75. template<class Comparand>
  76. typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
  77. operator != (const Comparand& right)const
  78. { return !(*this == right); }
  79. template<class Comparand>
  80. typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
  81. operator < (const Comparand& right)const
  82. {
  83. return first < right.first
  84. ||(!(right.first < first) && second < right.second);
  85. }
  86. template<class Comparand>
  87. typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
  88. operator > (const Comparand& right)const
  89. {
  90. return first > right.first
  91. ||(!(right.first > first) && second > right.second);
  92. }
  93. template<class Comparand>
  94. typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
  95. operator <= (const Comparand& right)const
  96. {
  97. return !(*this > right);
  98. }
  99. template<class Comparand>
  100. typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
  101. operator >= (const Comparand& right)const
  102. {
  103. return !(*this < right);
  104. }
  105. };
  106. //------------------------------------------------------------------------------
  107. template<class FirstT, class SecondT, class StdPairT>
  108. inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
  109. operator == ( const StdPairT& left,
  110. const mapped_reference<FirstT, SecondT>& right)
  111. {
  112. return right == left;
  113. }
  114. template<class FirstT, class SecondT, class StdPairT>
  115. inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
  116. operator != ( const StdPairT& left,
  117. const mapped_reference<FirstT, SecondT>& right)
  118. {
  119. return !(right == left);
  120. }
  121. //------------------------------------------------------------------------------
  122. template<class FirstT, class SecondT, class StdPairT>
  123. inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
  124. operator < ( const StdPairT& left,
  125. const mapped_reference<FirstT, SecondT>& right)
  126. {
  127. return right > left;
  128. }
  129. //------------------------------------------------------------------------------
  130. template<class FirstT, class SecondT, class StdPairT>
  131. inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
  132. operator > ( const StdPairT& left,
  133. const mapped_reference<FirstT, SecondT>& right)
  134. {
  135. return right < left;
  136. }
  137. //------------------------------------------------------------------------------
  138. template<class FirstT, class SecondT, class StdPairT>
  139. inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
  140. operator <= ( const StdPairT& left,
  141. const mapped_reference<FirstT, SecondT>& right)
  142. {
  143. return !(right < left);
  144. }
  145. //------------------------------------------------------------------------------
  146. template<class FirstT, class SecondT, class StdPairT>
  147. inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
  148. operator >= ( const StdPairT& left,
  149. const mapped_reference<FirstT, SecondT>& right)
  150. {
  151. return !(left < right);
  152. }
  153. //------------------------------------------------------------------------------
  154. //------------------------------------------------------------------------------
  155. template<class FirstT, class SecondT>
  156. inline mapped_reference<FirstT, SecondT> make_mapped_reference(const FirstT& left, SecondT& right)
  157. { return mapped_reference<FirstT, SecondT>(left, right); }
  158. }} // namespace icl boost
  159. #endif // BOOST_ICL_DETAIL_MAPPED_REFERENCE_HPP_JOFA_091108