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
11 #include <boost/type_traits/is_const.hpp>
12 #include <boost/type_traits/remove_const.hpp>
13 #include <boost/mpl/if.hpp>
14 #include <boost/icl/type_traits/is_concept_equivalent.hpp>
16 namespace boost{namespace icl
19 template<class FirstT, class SecondT> class mapped_reference;
21 //------------------------------------------------------------------------------
23 struct is_mapped_reference_combinable{
24 typedef is_mapped_reference_combinable type;
25 BOOST_STATIC_CONSTANT(bool, value = false);
28 template<class FirstT, class SecondT>
29 struct is_mapped_reference_combinable<std::pair<const FirstT,SecondT> >
31 typedef is_mapped_reference_combinable<std::pair<const FirstT,SecondT> > type;
32 BOOST_STATIC_CONSTANT(bool, value = true);
35 template<class FirstT, class SecondT>
36 struct is_mapped_reference_combinable<std::pair<FirstT,SecondT> >
38 typedef is_mapped_reference_combinable<std::pair<FirstT,SecondT> > type;
39 BOOST_STATIC_CONSTANT(bool, value = true);
42 //------------------------------------------------------------------------------
44 struct is_mapped_reference_or_combinable{
45 typedef is_mapped_reference_or_combinable type;
46 BOOST_STATIC_CONSTANT(bool, value = is_mapped_reference_combinable<Type>::value);
49 template<class FirstT, class SecondT>
50 struct is_mapped_reference_or_combinable<mapped_reference<FirstT,SecondT> >
52 typedef is_mapped_reference_or_combinable<mapped_reference<FirstT,SecondT> > type;
53 BOOST_STATIC_CONSTANT(bool, value = true);
58 //------------------------------------------------------------------------------
59 template<class FirstT, class SecondT>
60 class mapped_reference
63 mapped_reference& operator = (const mapped_reference&);
65 typedef FirstT first_type;
66 typedef SecondT second_type;
67 typedef mapped_reference type;
70 mpl::if_<is_const<second_type>,
72 const second_type&>::type second_reference_type;
74 typedef std::pair< first_type, second_type> std_pair_type;
75 typedef std::pair<const first_type, second_type> key_std_pair_type;
77 const first_type& first ;
78 second_reference_type second;
80 mapped_reference(const FirstT& fst, second_reference_type snd) : first(fst), second(snd){}
82 template<class FstT, class SndT>
83 mapped_reference(const mapped_reference<FstT, SndT>& source):
84 first(source.first), second(source.second){}
86 template<class FstT, class SndT>
87 operator std::pair<FstT,SndT>(){ return std::pair<FstT,SndT>(first, second); }
89 template<class Comparand>
90 typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
91 operator == (const Comparand& right)const
92 { return first == right.first && second == right.second; }
94 template<class Comparand>
95 typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
96 operator != (const Comparand& right)const
97 { return !(*this == right); }
99 template<class Comparand>
100 typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
101 operator < (const Comparand& right)const
103 return first < right.first
104 ||(!(right.first < first) && second < right.second);
107 template<class Comparand>
108 typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
109 operator > (const Comparand& right)const
111 return first > right.first
112 ||(!(right.first > first) && second > right.second);
115 template<class Comparand>
116 typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
117 operator <= (const Comparand& right)const
119 return !(*this > right);
122 template<class Comparand>
123 typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
124 operator >= (const Comparand& right)const
126 return !(*this < right);
131 //------------------------------------------------------------------------------
132 template<class FirstT, class SecondT, class StdPairT>
133 inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
134 operator == ( const StdPairT& left,
135 const mapped_reference<FirstT, SecondT>& right)
137 return right == left;
140 template<class FirstT, class SecondT, class StdPairT>
141 inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
142 operator != ( const StdPairT& left,
143 const mapped_reference<FirstT, SecondT>& right)
145 return !(right == left);
148 //------------------------------------------------------------------------------
149 template<class FirstT, class SecondT, class StdPairT>
150 inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
151 operator < ( const StdPairT& left,
152 const mapped_reference<FirstT, SecondT>& right)
157 //------------------------------------------------------------------------------
158 template<class FirstT, class SecondT, class StdPairT>
159 inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
160 operator > ( const StdPairT& left,
161 const mapped_reference<FirstT, SecondT>& right)
166 //------------------------------------------------------------------------------
167 template<class FirstT, class SecondT, class StdPairT>
168 inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
169 operator <= ( const StdPairT& left,
170 const mapped_reference<FirstT, SecondT>& right)
172 return !(right < left);
175 //------------------------------------------------------------------------------
176 template<class FirstT, class SecondT, class StdPairT>
177 inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
178 operator >= ( const StdPairT& left,
179 const mapped_reference<FirstT, SecondT>& right)
181 return !(left < right);
184 //------------------------------------------------------------------------------
185 //------------------------------------------------------------------------------
186 template<class FirstT, class SecondT>
187 inline mapped_reference<FirstT, SecondT> make_mapped_reference(const FirstT& left, SecondT& right)
188 { return mapped_reference<FirstT, SecondT>(left, right); }
190 }} // namespace icl boost
192 #endif // BOOST_ICL_DETAIL_MAPPED_REFERENCE_HPP_JOFA_091108