summaryrefslogtreecommitdiffstats
path: root/contrib/src/boost/type_traits/is_convertible.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/src/boost/type_traits/is_convertible.hpp')
-rw-r--r--contrib/src/boost/type_traits/is_convertible.hpp976
1 files changed, 488 insertions, 488 deletions
diff --git a/contrib/src/boost/type_traits/is_convertible.hpp b/contrib/src/boost/type_traits/is_convertible.hpp
index 417ece2..2332cdb 100644
--- a/contrib/src/boost/type_traits/is_convertible.hpp
+++ b/contrib/src/boost/type_traits/is_convertible.hpp
@@ -1,488 +1,488 @@
-
-// Copyright 2000 John Maddock (john@johnmaddock.co.uk)
-// Copyright 2000 Jeremy Siek (jsiek@lsc.nd.edu)
-// Copyright 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
-//
-// Use, modification and distribution are 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).
-//
-// See http://www.boost.org/libs/type_traits for most recent version including documentation.
-
-#ifndef BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED
-#define BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED
-
-#include <boost/type_traits/intrinsics.hpp>
-#include <boost/type_traits/integral_constant.hpp>
-#ifndef BOOST_IS_CONVERTIBLE
-#include <boost/type_traits/detail/yes_no_type.hpp>
-#include <boost/type_traits/detail/config.hpp>
-#include <boost/type_traits/is_array.hpp>
-#include <boost/type_traits/is_arithmetic.hpp>
-#include <boost/type_traits/is_void.hpp>
-#if !defined(BOOST_NO_IS_ABSTRACT)
-#include <boost/type_traits/is_abstract.hpp>
-#endif
-#include <boost/type_traits/add_lvalue_reference.hpp>
-#include <boost/type_traits/add_rvalue_reference.hpp>
-#include <boost/type_traits/is_function.hpp>
-
-#if defined(__MWERKS__)
-#include <boost/type_traits/remove_reference.hpp>
-#endif
-#if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
-# include <boost/type_traits/declval.hpp>
-#endif
-#elif defined(BOOST_MSVC) || defined(BOOST_INTEL)
-#include <boost/type_traits/is_function.hpp>
-#include <boost/type_traits/is_same.hpp>
-#endif // BOOST_IS_CONVERTIBLE
-
-namespace boost {
-
-#ifndef BOOST_IS_CONVERTIBLE
-
-// is one type convertible to another?
-//
-// there are multiple versions of the is_convertible
-// template, almost every compiler seems to require its
-// own version.
-//
-// Thanks to Andrei Alexandrescu for the original version of the
-// conversion detection technique!
-//
-
-namespace detail {
-
-#if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !(defined(BOOST_GCC) && (BOOST_GCC < 40700))
-
- // This is a C++11 conforming version, place this first and use it wherever possible:
-
-# define BOOST_TT_CXX11_IS_CONVERTIBLE
-
- template <class A, class B, class C>
- struct or_helper
- {
- static const bool value = (A::value || B::value || C::value);
- };
-
- template<typename From, typename To, bool b = or_helper<boost::is_void<From>, boost::is_function<To>, boost::is_array<To> >::value>
- struct is_convertible_basic_impl
- {
- // Nothing converts to function or array, but void converts to void:
- static const bool value = is_void<To>::value;
- };
-
- template<typename From, typename To>
- class is_convertible_basic_impl<From, To, false>
- {
- typedef char one;
- typedef int two;
-
- template<typename To1>
- static void test_aux(To1);
-
- template<typename From1, typename To1>
- static decltype(test_aux<To1>(boost::declval<From1>()), one()) test(int);
-
- template<typename, typename>
- static two test(...);
-
- public:
- static const bool value = sizeof(test<From, To>(0)) == 1;
- };
-
-#elif defined(__BORLANDC__) && (__BORLANDC__ < 0x560)
-//
-// special version for Borland compilers
-// this version breaks when used for some
-// UDT conversions:
-//
-template <typename From, typename To>
-struct is_convertible_impl
-{
-#pragma option push -w-8074
- // This workaround for Borland breaks the EDG C++ frontend,
- // so we only use it for Borland.
- template <typename T> struct checker
- {
- static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...);
- static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(T);
- };
-
- static typename add_lvalue_reference<From>::type _m_from;
- static bool const value = sizeof( checker<To>::_m_check(_m_from) )
- == sizeof(::boost::type_traits::yes_type);
-#pragma option pop
-};
-
-#elif defined(__GNUC__) || defined(__BORLANDC__) && (__BORLANDC__ < 0x600)
-// special version for gcc compiler + recent Borland versions
-// note that this does not pass UDT's through (...)
-
-struct any_conversion
-{
- template <typename T> any_conversion(const volatile T&);
- template <typename T> any_conversion(const T&);
- template <typename T> any_conversion(volatile T&);
- template <typename T> any_conversion(T&);
-};
-
-template <typename T> struct checker
-{
- static boost::type_traits::no_type _m_check(any_conversion ...);
- static boost::type_traits::yes_type _m_check(T, int);
-};
-
-template <typename From, typename To>
-struct is_convertible_basic_impl
-{
- typedef typename add_lvalue_reference<From>::type lvalue_type;
- typedef typename add_rvalue_reference<From>::type rvalue_type;
- static lvalue_type _m_from;
-#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 6)))
- static bool const value =
- sizeof( boost::detail::checker<To>::_m_check(static_cast<rvalue_type>(_m_from), 0) )
- == sizeof(::boost::type_traits::yes_type);
-#else
- static bool const value =
- sizeof( boost::detail::checker<To>::_m_check(_m_from, 0) )
- == sizeof(::boost::type_traits::yes_type);
-#endif
-};
-
-#elif (defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 245) && !defined(__ICL)) \
- || defined(__IBMCPP__) || defined(__HP_aCC)
-//
-// This is *almost* an ideal world implementation as it doesn't rely
-// on undefined behaviour by passing UDT's through (...).
-// Unfortunately it doesn't quite pass all the tests for most compilers (sigh...)
-// Enable this for your compiler if is_convertible_test.cpp will compile it...
-//
-// Note we do not enable this for VC7.1, because even though it passes all the
-// type_traits tests it is known to cause problems when instantiation occurs
-// deep within the instantiation tree :-(
-//
-struct any_conversion
-{
- template <typename T> any_conversion(const volatile T&);
- template <typename T> any_conversion(const T&);
- template <typename T> any_conversion(volatile T&);
- // we need this constructor to catch references to functions
- // (which can not be cv-qualified):
- template <typename T> any_conversion(T&);
-};
-
-template <typename From, typename To>
-struct is_convertible_basic_impl
-{
- static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion ...);
- static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int);
- typedef typename add_lvalue_reference<From>::type lvalue_type;
- typedef typename add_rvalue_reference<From>::type rvalue_type;
- static lvalue_type _m_from;
-
-#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
- BOOST_STATIC_CONSTANT(bool, value =
- sizeof( _m_check(static_cast<rvalue_type>(_m_from), 0) ) == sizeof(::boost::type_traits::yes_type)
- );
-#else
- BOOST_STATIC_CONSTANT(bool, value =
- sizeof( _m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type)
- );
-#endif
-};
-
-#elif defined(__DMC__)
-
-struct any_conversion
-{
- template <typename T> any_conversion(const volatile T&);
- template <typename T> any_conversion(const T&);
- template <typename T> any_conversion(volatile T&);
- // we need this constructor to catch references to functions
- // (which can not be cv-qualified):
- template <typename T> any_conversion(T&);
-};
-
-template <typename From, typename To>
-struct is_convertible_basic_impl
-{
- // Using '...' doesn't always work on Digital Mars. This version seems to.
- template <class T>
- static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion, float, T);
- static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int, int);
- typedef typename add_lvalue_reference<From>::type lvalue_type;
- typedef typename add_rvalue_reference<From>::type rvalue_type;
- static lvalue_type _m_from;
-
- // Static constants sometime cause the conversion of _m_from to To to be
- // called. This doesn't happen with an enum.
-#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
- enum { value =
- sizeof( _m_check(static_cast<rvalue_type>(_m_from), 0, 0) ) == sizeof(::boost::type_traits::yes_type)
- };
-#else
- enum { value =
- sizeof( _m_check(_m_from, 0, 0) ) == sizeof(::boost::type_traits::yes_type)
- };
-#endif
-};
-
-#elif defined(__MWERKS__)
-//
-// CW works with the technique implemented above for EDG, except when From
-// is a function type (or a reference to such a type), in which case
-// any_conversion won't be accepted as a valid conversion. We detect this
-// exceptional situation and channel it through an alternative algorithm.
-//
-
-template <typename From, typename To,bool FromIsFunctionRef>
-struct is_convertible_basic_impl_aux;
-
-struct any_conversion
-{
- template <typename T> any_conversion(const volatile T&);
- template <typename T> any_conversion(const T&);
- template <typename T> any_conversion(volatile T&);
- template <typename T> any_conversion(T&);
-};
-
-template <typename From, typename To>
-struct is_convertible_basic_impl_aux<From,To,false /*FromIsFunctionRef*/>
-{
- static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion ...);
- static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int);
- typedef typename add_lvalue_reference<From>::type lvalue_type;
- typedef typename add_rvalue_reference<From>::type rvalue_type;
- static lvalue_type _m_from;
-
-#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
- BOOST_STATIC_CONSTANT(bool, value =
- sizeof( _m_check(static_cast<rvalue_type>(_m_from), 0) ) == sizeof(::boost::type_traits::yes_type)
- );
-#else
- BOOST_STATIC_CONSTANT(bool, value =
- sizeof( _m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type)
- );
-#endif
-};
-
-template <typename From, typename To>
-struct is_convertible_basic_impl_aux<From,To,true /*FromIsFunctionRef*/>
-{
- static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...);
- static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To);
- typedef typename add_lvalue_reference<From>::type lvalue_type;
- typedef typename add_rvalue_reference<From>::type rvalue_type;
- static lvalue_type _m_from;
-#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
- BOOST_STATIC_CONSTANT(bool, value =
- sizeof( _m_check(static_cast<rvalue_type>(_m_from)) ) == sizeof(::boost::type_traits::yes_type)
- );
-#else
- BOOST_STATIC_CONSTANT(bool, value =
- sizeof( _m_check(_m_from) ) == sizeof(::boost::type_traits::yes_type)
- );
-#endif
-};
-
-template <typename From, typename To>
-struct is_convertible_basic_impl:
- is_convertible_basic_impl_aux<
- From,To,
- ::boost::is_function<typename ::boost::remove_reference<From>::type>::value
- >
-{};
-
-#else
-//
-// This version seems to work pretty well for a wide spectrum of compilers,
-// however it does rely on undefined behaviour by passing UDT's through (...).
-//
-
-//Workaround for old compilers like MSVC 7.1 to avoid
-//forming a reference to an array of unknown bound
-template <typename From>
-struct is_convertible_basic_impl_add_lvalue_reference
- : add_lvalue_reference<From>
-{};
-
-template <typename From>
-struct is_convertible_basic_impl_add_lvalue_reference<From[]>
-{
- typedef From type [];
-};
-
-template <typename From, typename To>
-struct is_convertible_basic_impl
-{
- static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...);
- static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To);
- typedef typename is_convertible_basic_impl_add_lvalue_reference<From>::type lvalue_type;
- static lvalue_type _m_from;
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#pragma warning(disable:4244)
-#if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000)
-#pragma warning(disable:6334)
-#endif
-#endif
-#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
- typedef typename add_rvalue_reference<From>::type rvalue_type;
- BOOST_STATIC_CONSTANT(bool, value =
- sizeof( _m_check(static_cast<rvalue_type>(_m_from)) ) == sizeof(::boost::type_traits::yes_type)
- );
-#else
- BOOST_STATIC_CONSTANT(bool, value =
- sizeof( _m_check(_m_from) ) == sizeof(::boost::type_traits::yes_type)
- );
-#endif
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
-};
-
-#endif // is_convertible_impl
-
-#if defined(__DMC__)
-// As before, a static constant sometimes causes errors on Digital Mars.
-template <typename From, typename To>
-struct is_convertible_impl
-{
- enum {
- value = ( ::boost::detail::is_convertible_basic_impl<From,To>::value && ! ::boost::is_array<To>::value && ! ::boost::is_function<To>::value)
- };
-};
-#elif !defined(__BORLANDC__) || __BORLANDC__ > 0x551
-template <typename From, typename To>
-struct is_convertible_impl
-{
- BOOST_STATIC_CONSTANT(bool, value = ( ::boost::detail::is_convertible_basic_impl<From, To>::value && !::boost::is_array<To>::value && !::boost::is_function<To>::value));
-};
-#endif
-
-template <bool trivial1, bool trivial2, bool abstract_target>
-struct is_convertible_impl_select
-{
- template <class From, class To>
- struct rebind
- {
- typedef is_convertible_impl<From, To> type;
- };
-};
-
-template <>
-struct is_convertible_impl_select<true, true, false>
-{
- template <class From, class To>
- struct rebind
- {
- typedef true_type type;
- };
-};
-
-template <>
-struct is_convertible_impl_select<false, false, true>
-{
- template <class From, class To>
- struct rebind
- {
- typedef false_type type;
- };
-};
-
-template <>
-struct is_convertible_impl_select<true, false, true>
-{
- template <class From, class To>
- struct rebind
- {
- typedef false_type type;
- };
-};
-
-template <typename From, typename To>
-struct is_convertible_impl_dispatch_base
-{
-#if !BOOST_WORKAROUND(__HP_aCC, < 60700)
- typedef is_convertible_impl_select<
- ::boost::is_arithmetic<From>::value,
- ::boost::is_arithmetic<To>::value,
-#if !defined(BOOST_NO_IS_ABSTRACT) && !defined(BOOST_TT_CXX11_IS_CONVERTIBLE)
- // We need to filter out abstract types, only if we don't have a strictly conforming C++11 version:
- ::boost::is_abstract<To>::value
-#else
- false
-#endif
- > selector;
-#else
- typedef is_convertible_impl_select<false, false, false> selector;
-#endif
- typedef typename selector::template rebind<From, To> isc_binder;
- typedef typename isc_binder::type type;
-};
-
-template <typename From, typename To>
-struct is_convertible_impl_dispatch
- : public is_convertible_impl_dispatch_base<From, To>::type
-{};
-
-//
-// Now add the full and partial specialisations
-// for void types, these are common to all the
-// implementation above:
-//
-#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
-
-template <> struct is_convertible_impl_dispatch<void, void> : public true_type{};
-template <> struct is_convertible_impl_dispatch<void, void const> : public true_type{};
-template <> struct is_convertible_impl_dispatch<void, void const volatile> : public true_type{};
-template <> struct is_convertible_impl_dispatch<void, void volatile> : public true_type{};
-
-template <> struct is_convertible_impl_dispatch<void const, void> : public true_type{};
-template <> struct is_convertible_impl_dispatch<void const, void const> : public true_type{};
-template <> struct is_convertible_impl_dispatch<void const, void const volatile> : public true_type{};
-template <> struct is_convertible_impl_dispatch<void const, void volatile> : public true_type{};
-
-template <> struct is_convertible_impl_dispatch<void const volatile, void> : public true_type{};
-template <> struct is_convertible_impl_dispatch<void const volatile, void const> : public true_type{};
-template <> struct is_convertible_impl_dispatch<void const volatile, void const volatile> : public true_type{};
-template <> struct is_convertible_impl_dispatch<void const volatile, void volatile> : public true_type{};
-
-template <> struct is_convertible_impl_dispatch<void volatile, void> : public true_type{};
-template <> struct is_convertible_impl_dispatch<void volatile, void const> : public true_type{};
-template <> struct is_convertible_impl_dispatch<void volatile, void const volatile> : public true_type{};
-template <> struct is_convertible_impl_dispatch<void volatile, void volatile> : public true_type{};
-
-#else
-template <> struct is_convertible_impl_dispatch<void, void> : public true_type{};
-#endif // BOOST_NO_CV_VOID_SPECIALIZATIONS
-
-template <class To> struct is_convertible_impl_dispatch<void, To> : public false_type{};
-template <class From> struct is_convertible_impl_dispatch<From, void> : public false_type{};
-
-#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
-template <class To> struct is_convertible_impl_dispatch<void const, To> : public false_type{};
-template <class From> struct is_convertible_impl_dispatch<From, void const> : public false_type{};
-template <class To> struct is_convertible_impl_dispatch<void const volatile, To> : public false_type{};
-template <class From> struct is_convertible_impl_dispatch<From, void const volatile> : public false_type{};
-template <class To> struct is_convertible_impl_dispatch<void volatile, To> : public false_type{};
-template <class From> struct is_convertible_impl_dispatch<From, void volatile> : public false_type{};
-#endif
-
-} // namespace detail
-
-template <class From, class To>
-struct is_convertible : public integral_constant<bool, ::boost::detail::is_convertible_impl_dispatch<From, To>::value> {};
-
-#else
-
-template <class From, class To>
-struct is_convertible : public integral_constant<bool, BOOST_IS_CONVERTIBLE(From, To)> {};
-
-#endif
-
-} // namespace boost
-
-#endif // BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED
+
+// Copyright 2000 John Maddock (john@johnmaddock.co.uk)
+// Copyright 2000 Jeremy Siek (jsiek@lsc.nd.edu)
+// Copyright 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
+//
+// Use, modification and distribution are 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).
+//
+// See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED
+#define BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED
+
+#include <boost/type_traits/intrinsics.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+#ifndef BOOST_IS_CONVERTIBLE
+#include <boost/type_traits/detail/yes_no_type.hpp>
+#include <boost/type_traits/detail/config.hpp>
+#include <boost/type_traits/is_array.hpp>
+#include <boost/type_traits/is_arithmetic.hpp>
+#include <boost/type_traits/is_void.hpp>
+#if !defined(BOOST_NO_IS_ABSTRACT)
+#include <boost/type_traits/is_abstract.hpp>
+#endif
+#include <boost/type_traits/add_lvalue_reference.hpp>
+#include <boost/type_traits/add_rvalue_reference.hpp>
+#include <boost/type_traits/is_function.hpp>
+
+#if defined(__MWERKS__)
+#include <boost/type_traits/remove_reference.hpp>
+#endif
+#if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+# include <boost/type_traits/declval.hpp>
+#endif
+#elif defined(BOOST_MSVC) || defined(BOOST_INTEL)
+#include <boost/type_traits/is_function.hpp>
+#include <boost/type_traits/is_same.hpp>
+#endif // BOOST_IS_CONVERTIBLE
+
+namespace boost {
+
+#ifndef BOOST_IS_CONVERTIBLE
+
+// is one type convertible to another?
+//
+// there are multiple versions of the is_convertible
+// template, almost every compiler seems to require its
+// own version.
+//
+// Thanks to Andrei Alexandrescu for the original version of the
+// conversion detection technique!
+//
+
+namespace detail {
+
+#if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !(defined(BOOST_GCC) && (BOOST_GCC < 40700))
+
+ // This is a C++11 conforming version, place this first and use it wherever possible:
+
+# define BOOST_TT_CXX11_IS_CONVERTIBLE
+
+ template <class A, class B, class C>
+ struct or_helper
+ {
+ static const bool value = (A::value || B::value || C::value);
+ };
+
+ template<typename From, typename To, bool b = or_helper<boost::is_void<From>, boost::is_function<To>, boost::is_array<To> >::value>
+ struct is_convertible_basic_impl
+ {
+ // Nothing converts to function or array, but void converts to void:
+ static const bool value = is_void<To>::value;
+ };
+
+ template<typename From, typename To>
+ class is_convertible_basic_impl<From, To, false>
+ {
+ typedef char one;
+ typedef int two;
+
+ template<typename To1>
+ static void test_aux(To1);
+
+ template<typename From1, typename To1>
+ static decltype(test_aux<To1>(boost::declval<From1>()), one()) test(int);
+
+ template<typename, typename>
+ static two test(...);
+
+ public:
+ static const bool value = sizeof(test<From, To>(0)) == 1;
+ };
+
+#elif defined(__BORLANDC__) && (__BORLANDC__ < 0x560)
+//
+// special version for Borland compilers
+// this version breaks when used for some
+// UDT conversions:
+//
+template <typename From, typename To>
+struct is_convertible_impl
+{
+#pragma option push -w-8074
+ // This workaround for Borland breaks the EDG C++ frontend,
+ // so we only use it for Borland.
+ template <typename T> struct checker
+ {
+ static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...);
+ static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(T);
+ };
+
+ static typename add_lvalue_reference<From>::type _m_from;
+ static bool const value = sizeof( checker<To>::_m_check(_m_from) )
+ == sizeof(::boost::type_traits::yes_type);
+#pragma option pop
+};
+
+#elif defined(__GNUC__) || defined(__BORLANDC__) && (__BORLANDC__ < 0x600)
+// special version for gcc compiler + recent Borland versions
+// note that this does not pass UDT's through (...)
+
+struct any_conversion
+{
+ template <typename T> any_conversion(const volatile T&);
+ template <typename T> any_conversion(const T&);
+ template <typename T> any_conversion(volatile T&);
+ template <typename T> any_conversion(T&);
+};
+
+template <typename T> struct checker
+{
+ static boost::type_traits::no_type _m_check(any_conversion ...);
+ static boost::type_traits::yes_type _m_check(T, int);
+};
+
+template <typename From, typename To>
+struct is_convertible_basic_impl
+{
+ typedef typename add_lvalue_reference<From>::type lvalue_type;
+ typedef typename add_rvalue_reference<From>::type rvalue_type;
+ static lvalue_type _m_from;
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 6)))
+ static bool const value =
+ sizeof( boost::detail::checker<To>::_m_check(static_cast<rvalue_type>(_m_from), 0) )
+ == sizeof(::boost::type_traits::yes_type);
+#else
+ static bool const value =
+ sizeof( boost::detail::checker<To>::_m_check(_m_from, 0) )
+ == sizeof(::boost::type_traits::yes_type);
+#endif
+};
+
+#elif (defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 245) && !defined(__ICL)) \
+ || defined(__IBMCPP__) || defined(__HP_aCC)
+//
+// This is *almost* an ideal world implementation as it doesn't rely
+// on undefined behaviour by passing UDT's through (...).
+// Unfortunately it doesn't quite pass all the tests for most compilers (sigh...)
+// Enable this for your compiler if is_convertible_test.cpp will compile it...
+//
+// Note we do not enable this for VC7.1, because even though it passes all the
+// type_traits tests it is known to cause problems when instantiation occurs
+// deep within the instantiation tree :-(
+//
+struct any_conversion
+{
+ template <typename T> any_conversion(const volatile T&);
+ template <typename T> any_conversion(const T&);
+ template <typename T> any_conversion(volatile T&);
+ // we need this constructor to catch references to functions
+ // (which can not be cv-qualified):
+ template <typename T> any_conversion(T&);
+};
+
+template <typename From, typename To>
+struct is_convertible_basic_impl
+{
+ static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion ...);
+ static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int);
+ typedef typename add_lvalue_reference<From>::type lvalue_type;
+ typedef typename add_rvalue_reference<From>::type rvalue_type;
+ static lvalue_type _m_from;
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ BOOST_STATIC_CONSTANT(bool, value =
+ sizeof( _m_check(static_cast<rvalue_type>(_m_from), 0) ) == sizeof(::boost::type_traits::yes_type)
+ );
+#else
+ BOOST_STATIC_CONSTANT(bool, value =
+ sizeof( _m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type)
+ );
+#endif
+};
+
+#elif defined(__DMC__)
+
+struct any_conversion
+{
+ template <typename T> any_conversion(const volatile T&);
+ template <typename T> any_conversion(const T&);
+ template <typename T> any_conversion(volatile T&);
+ // we need this constructor to catch references to functions
+ // (which can not be cv-qualified):
+ template <typename T> any_conversion(T&);
+};
+
+template <typename From, typename To>
+struct is_convertible_basic_impl
+{
+ // Using '...' doesn't always work on Digital Mars. This version seems to.
+ template <class T>
+ static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion, float, T);
+ static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int, int);
+ typedef typename add_lvalue_reference<From>::type lvalue_type;
+ typedef typename add_rvalue_reference<From>::type rvalue_type;
+ static lvalue_type _m_from;
+
+ // Static constants sometime cause the conversion of _m_from to To to be
+ // called. This doesn't happen with an enum.
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ enum { value =
+ sizeof( _m_check(static_cast<rvalue_type>(_m_from), 0, 0) ) == sizeof(::boost::type_traits::yes_type)
+ };
+#else
+ enum { value =
+ sizeof( _m_check(_m_from, 0, 0) ) == sizeof(::boost::type_traits::yes_type)
+ };
+#endif
+};
+
+#elif defined(__MWERKS__)
+//
+// CW works with the technique implemented above for EDG, except when From
+// is a function type (or a reference to such a type), in which case
+// any_conversion won't be accepted as a valid conversion. We detect this
+// exceptional situation and channel it through an alternative algorithm.
+//
+
+template <typename From, typename To,bool FromIsFunctionRef>
+struct is_convertible_basic_impl_aux;
+
+struct any_conversion
+{
+ template <typename T> any_conversion(const volatile T&);
+ template <typename T> any_conversion(const T&);
+ template <typename T> any_conversion(volatile T&);
+ template <typename T> any_conversion(T&);
+};
+
+template <typename From, typename To>
+struct is_convertible_basic_impl_aux<From,To,false /*FromIsFunctionRef*/>
+{
+ static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion ...);
+ static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int);
+ typedef typename add_lvalue_reference<From>::type lvalue_type;
+ typedef typename add_rvalue_reference<From>::type rvalue_type;
+ static lvalue_type _m_from;
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ BOOST_STATIC_CONSTANT(bool, value =
+ sizeof( _m_check(static_cast<rvalue_type>(_m_from), 0) ) == sizeof(::boost::type_traits::yes_type)
+ );
+#else
+ BOOST_STATIC_CONSTANT(bool, value =
+ sizeof( _m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type)
+ );
+#endif
+};
+
+template <typename From, typename To>
+struct is_convertible_basic_impl_aux<From,To,true /*FromIsFunctionRef*/>
+{
+ static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...);
+ static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To);
+ typedef typename add_lvalue_reference<From>::type lvalue_type;
+ typedef typename add_rvalue_reference<From>::type rvalue_type;
+ static lvalue_type _m_from;
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ BOOST_STATIC_CONSTANT(bool, value =
+ sizeof( _m_check(static_cast<rvalue_type>(_m_from)) ) == sizeof(::boost::type_traits::yes_type)
+ );
+#else
+ BOOST_STATIC_CONSTANT(bool, value =
+ sizeof( _m_check(_m_from) ) == sizeof(::boost::type_traits::yes_type)
+ );
+#endif
+};
+
+template <typename From, typename To>
+struct is_convertible_basic_impl:
+ is_convertible_basic_impl_aux<
+ From,To,
+ ::boost::is_function<typename ::boost::remove_reference<From>::type>::value
+ >
+{};
+
+#else
+//
+// This version seems to work pretty well for a wide spectrum of compilers,
+// however it does rely on undefined behaviour by passing UDT's through (...).
+//
+
+//Workaround for old compilers like MSVC 7.1 to avoid
+//forming a reference to an array of unknown bound
+template <typename From>
+struct is_convertible_basic_impl_add_lvalue_reference
+ : add_lvalue_reference<From>
+{};
+
+template <typename From>
+struct is_convertible_basic_impl_add_lvalue_reference<From[]>
+{
+ typedef From type [];
+};
+
+template <typename From, typename To>
+struct is_convertible_basic_impl
+{
+ static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...);
+ static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To);
+ typedef typename is_convertible_basic_impl_add_lvalue_reference<From>::type lvalue_type;
+ static lvalue_type _m_from;
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4244)
+#if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000)
+#pragma warning(disable:6334)
+#endif
+#endif
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ typedef typename add_rvalue_reference<From>::type rvalue_type;
+ BOOST_STATIC_CONSTANT(bool, value =
+ sizeof( _m_check(static_cast<rvalue_type>(_m_from)) ) == sizeof(::boost::type_traits::yes_type)
+ );
+#else
+ BOOST_STATIC_CONSTANT(bool, value =
+ sizeof( _m_check(_m_from) ) == sizeof(::boost::type_traits::yes_type)
+ );
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+};
+
+#endif // is_convertible_impl
+
+#if defined(__DMC__)
+// As before, a static constant sometimes causes errors on Digital Mars.
+template <typename From, typename To>
+struct is_convertible_impl
+{
+ enum {
+ value = ( ::boost::detail::is_convertible_basic_impl<From,To>::value && ! ::boost::is_array<To>::value && ! ::boost::is_function<To>::value)
+ };
+};
+#elif !defined(__BORLANDC__) || __BORLANDC__ > 0x551
+template <typename From, typename To>
+struct is_convertible_impl
+{
+ BOOST_STATIC_CONSTANT(bool, value = ( ::boost::detail::is_convertible_basic_impl<From, To>::value && !::boost::is_array<To>::value && !::boost::is_function<To>::value));
+};
+#endif
+
+template <bool trivial1, bool trivial2, bool abstract_target>
+struct is_convertible_impl_select
+{
+ template <class From, class To>
+ struct rebind
+ {
+ typedef is_convertible_impl<From, To> type;
+ };
+};
+
+template <>
+struct is_convertible_impl_select<true, true, false>
+{
+ template <class From, class To>
+ struct rebind
+ {
+ typedef true_type type;
+ };
+};
+
+template <>
+struct is_convertible_impl_select<false, false, true>
+{
+ template <class From, class To>
+ struct rebind
+ {
+ typedef false_type type;
+ };
+};
+
+template <>
+struct is_convertible_impl_select<true, false, true>
+{
+ template <class From, class To>
+ struct rebind
+ {
+ typedef false_type type;
+ };
+};
+
+template <typename From, typename To>
+struct is_convertible_impl_dispatch_base
+{
+#if !BOOST_WORKAROUND(__HP_aCC, < 60700)
+ typedef is_convertible_impl_select<
+ ::boost::is_arithmetic<From>::value,
+ ::boost::is_arithmetic<To>::value,
+#if !defined(BOOST_NO_IS_ABSTRACT) && !defined(BOOST_TT_CXX11_IS_CONVERTIBLE)
+ // We need to filter out abstract types, only if we don't have a strictly conforming C++11 version:
+ ::boost::is_abstract<To>::value
+#else
+ false
+#endif
+ > selector;
+#else
+ typedef is_convertible_impl_select<false, false, false> selector;
+#endif
+ typedef typename selector::template rebind<From, To> isc_binder;
+ typedef typename isc_binder::type type;
+};
+
+template <typename From, typename To>
+struct is_convertible_impl_dispatch
+ : public is_convertible_impl_dispatch_base<From, To>::type
+{};
+
+//
+// Now add the full and partial specialisations
+// for void types, these are common to all the
+// implementation above:
+//
+#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
+
+template <> struct is_convertible_impl_dispatch<void, void> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void, void const> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void, void const volatile> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void, void volatile> : public true_type{};
+
+template <> struct is_convertible_impl_dispatch<void const, void> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void const, void const> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void const, void const volatile> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void const, void volatile> : public true_type{};
+
+template <> struct is_convertible_impl_dispatch<void const volatile, void> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void const volatile, void const> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void const volatile, void const volatile> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void const volatile, void volatile> : public true_type{};
+
+template <> struct is_convertible_impl_dispatch<void volatile, void> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void volatile, void const> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void volatile, void const volatile> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void volatile, void volatile> : public true_type{};
+
+#else
+template <> struct is_convertible_impl_dispatch<void, void> : public true_type{};
+#endif // BOOST_NO_CV_VOID_SPECIALIZATIONS
+
+template <class To> struct is_convertible_impl_dispatch<void, To> : public false_type{};
+template <class From> struct is_convertible_impl_dispatch<From, void> : public false_type{};
+
+#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
+template <class To> struct is_convertible_impl_dispatch<void const, To> : public false_type{};
+template <class From> struct is_convertible_impl_dispatch<From, void const> : public false_type{};
+template <class To> struct is_convertible_impl_dispatch<void const volatile, To> : public false_type{};
+template <class From> struct is_convertible_impl_dispatch<From, void const volatile> : public false_type{};
+template <class To> struct is_convertible_impl_dispatch<void volatile, To> : public false_type{};
+template <class From> struct is_convertible_impl_dispatch<From, void volatile> : public false_type{};
+#endif
+
+} // namespace detail
+
+template <class From, class To>
+struct is_convertible : public integral_constant<bool, ::boost::detail::is_convertible_impl_dispatch<From, To>::value> {};
+
+#else
+
+template <class From, class To>
+struct is_convertible : public integral_constant<bool, BOOST_IS_CONVERTIBLE(From, To)> {};
+
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED