File indexing completed on 2025-01-18 09:38:20
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_ICL_DETAIL_MAPPED_REFERENCE_HPP_JOFA_091108
0009 #define BOOST_ICL_DETAIL_MAPPED_REFERENCE_HPP_JOFA_091108
0010
0011 #include <boost/type_traits/is_const.hpp>
0012 #include <boost/type_traits/remove_const.hpp>
0013 #include <boost/mpl/if.hpp>
0014 #include <boost/icl/type_traits/is_concept_equivalent.hpp>
0015
0016 namespace boost{namespace icl
0017 {
0018
0019 template<class FirstT, class SecondT> class mapped_reference;
0020
0021
0022 template<class Type>
0023 struct is_mapped_reference_combinable{
0024 typedef is_mapped_reference_combinable type;
0025 BOOST_STATIC_CONSTANT(bool, value = false);
0026 };
0027
0028 template<class FirstT, class SecondT>
0029 struct is_mapped_reference_combinable<std::pair<const FirstT,SecondT> >
0030 {
0031 typedef is_mapped_reference_combinable<std::pair<const FirstT,SecondT> > type;
0032 BOOST_STATIC_CONSTANT(bool, value = true);
0033 };
0034
0035 template<class FirstT, class SecondT>
0036 struct is_mapped_reference_combinable<std::pair<FirstT,SecondT> >
0037 {
0038 typedef is_mapped_reference_combinable<std::pair<FirstT,SecondT> > type;
0039 BOOST_STATIC_CONSTANT(bool, value = true);
0040 };
0041
0042
0043 template<class Type>
0044 struct is_mapped_reference_or_combinable{
0045 typedef is_mapped_reference_or_combinable type;
0046 BOOST_STATIC_CONSTANT(bool, value = is_mapped_reference_combinable<Type>::value);
0047 };
0048
0049 template<class FirstT, class SecondT>
0050 struct is_mapped_reference_or_combinable<mapped_reference<FirstT,SecondT> >
0051 {
0052 typedef is_mapped_reference_or_combinable<mapped_reference<FirstT,SecondT> > type;
0053 BOOST_STATIC_CONSTANT(bool, value = true);
0054 };
0055
0056
0057
0058
0059 template<class FirstT, class SecondT>
0060 class mapped_reference
0061 {
0062 private:
0063 mapped_reference& operator = (const mapped_reference&);
0064 public:
0065 typedef FirstT first_type;
0066 typedef SecondT second_type;
0067 typedef mapped_reference type;
0068
0069 typedef typename
0070 mpl::if_<is_const<second_type>,
0071 second_type&,
0072 const second_type&>::type second_reference_type;
0073
0074 typedef std::pair< first_type, second_type> std_pair_type;
0075 typedef std::pair<const first_type, second_type> key_std_pair_type;
0076
0077 const first_type& first ;
0078 second_reference_type second;
0079
0080 mapped_reference(const FirstT& fst, second_reference_type snd) : first(fst), second(snd){}
0081
0082 template<class FstT, class SndT>
0083 mapped_reference(const mapped_reference<FstT, SndT>& source):
0084 first(source.first), second(source.second){}
0085
0086 template<class FstT, class SndT>
0087 operator std::pair<FstT,SndT>(){ return std::pair<FstT,SndT>(first, second); }
0088
0089 template<class Comparand>
0090 typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
0091 operator == (const Comparand& right)const
0092 { return first == right.first && second == right.second; }
0093
0094 template<class Comparand>
0095 typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
0096 operator != (const Comparand& right)const
0097 { return !(*this == right); }
0098
0099 template<class Comparand>
0100 typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
0101 operator < (const Comparand& right)const
0102 {
0103 return first < right.first
0104 ||(!(right.first < first) && second < right.second);
0105 }
0106
0107 template<class Comparand>
0108 typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
0109 operator > (const Comparand& right)const
0110 {
0111 return first > right.first
0112 ||(!(right.first > first) && second > right.second);
0113 }
0114
0115 template<class Comparand>
0116 typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
0117 operator <= (const Comparand& right)const
0118 {
0119 return !(*this > right);
0120 }
0121
0122 template<class Comparand>
0123 typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
0124 operator >= (const Comparand& right)const
0125 {
0126 return !(*this < right);
0127 }
0128
0129 };
0130
0131
0132 template<class FirstT, class SecondT, class StdPairT>
0133 inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
0134 operator == ( const StdPairT& left,
0135 const mapped_reference<FirstT, SecondT>& right)
0136 {
0137 return right == left;
0138 }
0139
0140 template<class FirstT, class SecondT, class StdPairT>
0141 inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
0142 operator != ( const StdPairT& left,
0143 const mapped_reference<FirstT, SecondT>& right)
0144 {
0145 return !(right == left);
0146 }
0147
0148
0149 template<class FirstT, class SecondT, class StdPairT>
0150 inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
0151 operator < ( const StdPairT& left,
0152 const mapped_reference<FirstT, SecondT>& right)
0153 {
0154 return right > left;
0155 }
0156
0157
0158 template<class FirstT, class SecondT, class StdPairT>
0159 inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
0160 operator > ( const StdPairT& left,
0161 const mapped_reference<FirstT, SecondT>& right)
0162 {
0163 return right < left;
0164 }
0165
0166
0167 template<class FirstT, class SecondT, class StdPairT>
0168 inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
0169 operator <= ( const StdPairT& left,
0170 const mapped_reference<FirstT, SecondT>& right)
0171 {
0172 return !(right < left);
0173 }
0174
0175
0176 template<class FirstT, class SecondT, class StdPairT>
0177 inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
0178 operator >= ( const StdPairT& left,
0179 const mapped_reference<FirstT, SecondT>& right)
0180 {
0181 return !(left < right);
0182 }
0183
0184
0185
0186 template<class FirstT, class SecondT>
0187 inline mapped_reference<FirstT, SecondT> make_mapped_reference(const FirstT& left, SecondT& right)
0188 { return mapped_reference<FirstT, SecondT>(left, right); }
0189
0190 }}
0191
0192 #endif