// Copyright David Abrahams 2003. Use, modification and distribution is | |
// subject to the Boost Software License, Version 1.0. (See accompanying | |
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
#ifndef MINIMUM_CATEGORY_DWA20031119_HPP | |
# define MINIMUM_CATEGORY_DWA20031119_HPP | |
# include <boost/type_traits/is_convertible.hpp> | |
# include <boost/type_traits/is_same.hpp> | |
# include <boost/mpl/aux_/lambda_support.hpp> | |
namespace boost { namespace detail { | |
// | |
// Returns the minimum category type or error_type | |
// if T1 and T2 are unrelated. | |
// | |
// For compilers not supporting is_convertible this only | |
// works with the new boost return and traversal category | |
// types. The exact boost _types_ are required. No derived types | |
// will work. | |
// | |
// | |
template <bool GreaterEqual, bool LessEqual> | |
struct minimum_category_impl | |
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) | |
{ | |
template <class T1, class T2> struct apply | |
{ | |
typedef T2 type; | |
}; | |
typedef void type; | |
} | |
# endif | |
; | |
template <class T1, class T2> | |
struct error_not_related_by_convertibility; | |
template <> | |
struct minimum_category_impl<true,false> | |
{ | |
template <class T1, class T2> struct apply | |
{ | |
typedef T2 type; | |
}; | |
}; | |
template <> | |
struct minimum_category_impl<false,true> | |
{ | |
template <class T1, class T2> struct apply | |
{ | |
typedef T1 type; | |
}; | |
}; | |
template <> | |
struct minimum_category_impl<true,true> | |
{ | |
template <class T1, class T2> struct apply | |
{ | |
BOOST_STATIC_ASSERT((is_same<T1,T2>::value)); | |
typedef T1 type; | |
}; | |
}; | |
template <> | |
struct minimum_category_impl<false,false> | |
{ | |
template <class T1, class T2> struct apply | |
: error_not_related_by_convertibility<T1,T2> | |
{ | |
}; | |
}; | |
template <class T1 = mpl::_1, class T2 = mpl::_2> | |
struct minimum_category | |
{ | |
typedef minimum_category_impl< | |
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround | |
is_same<T2,int>::value || | |
# endif | |
::boost::is_convertible<T1,T2>::value | |
, ::boost::is_convertible<T2,T1>::value | |
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround | |
|| is_same<T1,int>::value | |
# endif | |
> outer; | |
typedef typename outer::template apply<T1,T2> inner; | |
typedef typename inner::type type; | |
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,minimum_category,(T1,T2)) | |
}; | |
template <> | |
struct minimum_category<mpl::_1,mpl::_2> | |
{ | |
template <class T1, class T2> | |
struct apply : minimum_category<T1,T2> | |
{}; | |
BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2,minimum_category,(mpl::_1,mpl::_2)) | |
}; | |
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround | |
template <> | |
struct minimum_category<int,int> | |
{ | |
typedef int type; | |
}; | |
# endif | |
}} // namespace boost::detail | |
#endif // MINIMUM_CATEGORY_DWA20031119_HPP |