/*-----------------------------------------------------------------------------+ | |
Copyright (c) 2009-2009: Joachim Faulhaber | |
+------------------------------------------------------------------------------+ | |
Distributed under the Boost Software License, Version 1.0. | |
(See accompanying file LICENCE.txt or copy at | |
http://www.boost.org/LICENSE_1_0.txt) | |
+-----------------------------------------------------------------------------*/ | |
#ifndef BOOST_ICL_DETAIL_MAPPED_REFERENCE_HPP_JOFA_091108 | |
#define BOOST_ICL_DETAIL_MAPPED_REFERENCE_HPP_JOFA_091108 | |
#include <boost/type_traits/is_const.hpp> | |
#include <boost/type_traits/remove_const.hpp> | |
#include <boost/mpl/if.hpp> | |
#include <boost/icl/type_traits/is_concept_equivalent.hpp> | |
namespace boost{namespace icl | |
{ | |
template<class FirstT, class SecondT> class mapped_reference; | |
//------------------------------------------------------------------------------ | |
template<class Type> | |
struct is_mapped_reference_combinable{ | |
typedef is_mapped_reference_combinable type; | |
BOOST_STATIC_CONSTANT(bool, value = false); | |
}; | |
template<class FirstT, class SecondT> | |
struct is_mapped_reference_combinable<std::pair<const FirstT,SecondT> > | |
{ | |
typedef is_mapped_reference_combinable<std::pair<const FirstT,SecondT> > type; | |
BOOST_STATIC_CONSTANT(bool, value = true); | |
}; | |
template<class FirstT, class SecondT> | |
struct is_mapped_reference_combinable<std::pair<FirstT,SecondT> > | |
{ | |
typedef is_mapped_reference_combinable<std::pair<FirstT,SecondT> > type; | |
BOOST_STATIC_CONSTANT(bool, value = true); | |
}; | |
//------------------------------------------------------------------------------ | |
template<class Type> | |
struct is_mapped_reference_or_combinable{ | |
typedef is_mapped_reference_or_combinable type; | |
BOOST_STATIC_CONSTANT(bool, value = is_mapped_reference_combinable<Type>::value); | |
}; | |
template<class FirstT, class SecondT> | |
struct is_mapped_reference_or_combinable<mapped_reference<FirstT,SecondT> > | |
{ | |
typedef is_mapped_reference_or_combinable<mapped_reference<FirstT,SecondT> > type; | |
BOOST_STATIC_CONSTANT(bool, value = true); | |
}; | |
//------------------------------------------------------------------------------ | |
template<class FirstT, class SecondT> | |
class mapped_reference | |
{ | |
private: | |
mapped_reference& operator = (const mapped_reference&); | |
public: | |
typedef FirstT first_type; | |
typedef SecondT second_type; | |
typedef mapped_reference type; | |
typedef typename | |
mpl::if_<is_const<second_type>, | |
second_type&, | |
const second_type&>::type second_reference_type; | |
typedef std::pair< first_type, second_type> std_pair_type; | |
typedef std::pair<const first_type, second_type> key_std_pair_type; | |
const first_type& first ; | |
second_reference_type second; | |
mapped_reference(const FirstT& fst, second_reference_type snd) : first(fst), second(snd){} | |
template<class FstT, class SndT> | |
mapped_reference(const mapped_reference<FstT, SndT>& source): | |
first(source.first), second(source.second){} | |
template<class FstT, class SndT> | |
operator std::pair<FstT,SndT>(){ return std::pair<FstT,SndT>(first, second); } | |
template<class Comparand> | |
typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type | |
operator == (const Comparand& right)const | |
{ return first == right.first && second == right.second; } | |
template<class Comparand> | |
typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type | |
operator != (const Comparand& right)const | |
{ return !(*this == right); } | |
template<class Comparand> | |
typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type | |
operator < (const Comparand& right)const | |
{ | |
return first < right.first | |
||(!(right.first < first) && second < right.second); | |
} | |
template<class Comparand> | |
typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type | |
operator > (const Comparand& right)const | |
{ | |
return first > right.first | |
||(!(right.first > first) && second > right.second); | |
} | |
template<class Comparand> | |
typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type | |
operator <= (const Comparand& right)const | |
{ | |
return !(*this > right); | |
} | |
template<class Comparand> | |
typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type | |
operator >= (const Comparand& right)const | |
{ | |
return !(*this < right); | |
} | |
}; | |
//------------------------------------------------------------------------------ | |
template<class FirstT, class SecondT, class StdPairT> | |
inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type | |
operator == ( const StdPairT& left, | |
const mapped_reference<FirstT, SecondT>& right) | |
{ | |
return right == left; | |
} | |
template<class FirstT, class SecondT, class StdPairT> | |
inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type | |
operator != ( const StdPairT& left, | |
const mapped_reference<FirstT, SecondT>& right) | |
{ | |
return !(right == left); | |
} | |
//------------------------------------------------------------------------------ | |
template<class FirstT, class SecondT, class StdPairT> | |
inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type | |
operator < ( const StdPairT& left, | |
const mapped_reference<FirstT, SecondT>& right) | |
{ | |
return right > left; | |
} | |
//------------------------------------------------------------------------------ | |
template<class FirstT, class SecondT, class StdPairT> | |
inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type | |
operator > ( const StdPairT& left, | |
const mapped_reference<FirstT, SecondT>& right) | |
{ | |
return right < left; | |
} | |
//------------------------------------------------------------------------------ | |
template<class FirstT, class SecondT, class StdPairT> | |
inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type | |
operator <= ( const StdPairT& left, | |
const mapped_reference<FirstT, SecondT>& right) | |
{ | |
return !(right < left); | |
} | |
//------------------------------------------------------------------------------ | |
template<class FirstT, class SecondT, class StdPairT> | |
inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type | |
operator >= ( const StdPairT& left, | |
const mapped_reference<FirstT, SecondT>& right) | |
{ | |
return !(left < right); | |
} | |
//------------------------------------------------------------------------------ | |
//------------------------------------------------------------------------------ | |
template<class FirstT, class SecondT> | |
inline mapped_reference<FirstT, SecondT> make_mapped_reference(const FirstT& left, SecondT& right) | |
{ return mapped_reference<FirstT, SecondT>(left, right); } | |
}} // namespace icl boost | |
#endif // BOOST_ICL_DETAIL_MAPPED_REFERENCE_HPP_JOFA_091108 |