]> git.lyx.org Git - lyx.git/blobdiff - boost/boost/type_traits/is_convertible.hpp
update boost to version 1.36
[lyx.git] / boost / boost / type_traits / is_convertible.hpp
index 8f90dd820eff5f8b434587b529f300e82760939e..ce522a08429fa6fec1faa2819048061a8e8eadd5 100644 (file)
@@ -1,36 +1,44 @@
 
-// Copyright (C) 2000 John Maddock (john_maddock@compuserve.com)
-// Copyright (C) 2000 Jeremy Siek (jsiek@lsc.nd.edu)
-// Copyright (C) 1999, 2000 Jaakko J\84rvi (jaakko.jarvi@cs.utu.fi)
+// 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)
 //
-// Permission to copy and use this software is granted, 
-// provided this copyright notice appears in all copies. 
-// Permission to modify the code and to distribute modified code is granted, 
-// provided this copyright notice appears in all copies, and a notice 
-// that the code was modified is included with the copyright notice.
-//
-// This software is provided "as is" without express or implied warranty, 
-// and with no claim as to its suitability for any purpose.
+//  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/detail/yes_no_type.hpp"
-#include "boost/type_traits/config.hpp"
-#include "boost/type_traits/is_array.hpp"
-#include "boost/type_traits/add_reference.hpp"
-#include "boost/type_traits/ice.hpp"
+#include <boost/type_traits/intrinsics.hpp>
+#ifndef BOOST_IS_CONVERTIBLE
+#include <boost/type_traits/detail/yes_no_type.hpp>
+#include <boost/type_traits/config.hpp>
+#include <boost/type_traits/is_array.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/ice.hpp>
+#include <boost/type_traits/is_arithmetic.hpp>
+#include <boost/type_traits/is_void.hpp>
+#ifndef BOOST_NO_IS_ABSTRACT
+#include <boost/type_traits/is_abstract.hpp>
+#endif
 
-#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
-#   include "boost/type_traits/is_void.hpp"
+#if defined(__MWERKS__)
+#include <boost/type_traits/is_function.hpp>
+#include <boost/type_traits/remove_reference.hpp>
 #endif
 
+#endif // BOOST_IS_CONVERTIBLE
+
 // should be always the last #include directive
-#include "boost/type_traits/detail/bool_trait_def.hpp"
+#include <boost/type_traits/detail/bool_trait_def.hpp>
 
 namespace boost {
 
+#ifndef BOOST_IS_CONVERTIBLE
+
 // is one type convertable to another?
 //
 // there are multiple versions of the is_convertible
@@ -99,19 +107,19 @@ struct is_convertible_impl
     };
 
     static From _m_from;
-    static bool const value = sizeof( checker<To>::_m_check(_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__)
+#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(T&);
+    template <typename T> any_conversion(T&);
 };
 
 template <typename T> struct checker
@@ -124,18 +132,44 @@ template <typename From, typename To>
 struct is_convertible_basic_impl
 {
     static From _m_from;
-    static bool const value = sizeof( detail::checker<To>::_m_check(_m_from, 0) ) 
+    static bool const value = sizeof( detail::checker<To>::_m_check(_m_from, 0) )
         == sizeof(::boost::type_traits::yes_type);
 };
 
-#elif (defined(BOOST_MSVC) && (BOOST_MSVC >= 1310) && _MSC_FULL_VER > 13102292) \
-      || (defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 245) && !defined(__ICL))
+#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&);
+    // 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);
+       static From _m_from;
+
+    BOOST_STATIC_CONSTANT(bool, value =
+        sizeof( _m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type)
+        );
+};
+
+#elif defined(__DMC__)
+
 struct any_conversion
 {
     template <typename T> any_conversion(const volatile T&);
@@ -146,20 +180,71 @@ struct any_conversion
 
 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);
+    static From _m_from;
+
+    // Static constants sometime cause the conversion of _m_from to To to be
+    // called. This doesn't happen with an enum.
+    enum { value =
+        sizeof( _m_check(_m_from, 0, 0) ) == sizeof(::boost::type_traits::yes_type)
+        };
+};
+
+#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 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);
-           static From _m_from;
+    static From _m_from;
 
-    BOOST_STATIC_CONSTANT(bool, value = 
+    BOOST_STATIC_CONSTANT(bool, value =
         sizeof( _m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type)
         );
 };
 
+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);
+    static From _m_from;
+    BOOST_STATIC_CONSTANT(bool, value =
+        sizeof( _m_check(_m_from) ) == sizeof(::boost::type_traits::yes_type)
+        );
+};
+
+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, 
+// 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 (...).
 //
 template <typename From, typename To>
@@ -168,22 +253,51 @@ 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);
     static From _m_from;
-
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4244)
+#if BOOST_WORKAROUND(_MSC_FULL_VER, >= 140050000)
+#pragma warning(disable:6334)
+#endif
+#endif
     BOOST_STATIC_CONSTANT(bool, value =
         sizeof( _m_check(_m_from) ) == sizeof(::boost::type_traits::yes_type)
         );
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
 };
 
 #endif // is_convertible_impl
 
-#if !defined(__BORLANDC__) || __BORLANDC__ > 0x551
+#if defined(__DMC__)
+// As before, a static constant sometimes causes errors on Digital Mars.
+template <typename From, typename To>
+struct is_convertible_impl
+{
+    typedef typename add_reference<From>::type ref_type;
+    enum { value =
+        (::boost::type_traits::ice_and<
+            ::boost::type_traits::ice_or<
+               ::boost::detail::is_convertible_basic_impl<ref_type,To>::value,
+               ::boost::is_void<To>::value
+            >::value,
+            ::boost::type_traits::ice_not<
+               ::boost::is_array<To>::value
+            >::value
+        >::value) };
+};
+#elif !defined(__BORLANDC__) || __BORLANDC__ > 0x551
 template <typename From, typename To>
 struct is_convertible_impl
 {
     typedef typename add_reference<From>::type ref_type;
     BOOST_STATIC_CONSTANT(bool, value =
         (::boost::type_traits::ice_and<
-            ::boost::detail::is_convertible_basic_impl<ref_type,To>::value,
+            ::boost::type_traits::ice_or<
+               ::boost::detail::is_convertible_basic_impl<ref_type,To>::value,
+               ::boost::is_void<To>::value
+            >::value,
             ::boost::type_traits::ice_not<
                ::boost::is_array<To>::value
             >::value
@@ -192,6 +306,71 @@ struct is_convertible_impl
 };
 #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,
+#ifndef BOOST_NO_IS_ABSTRACT
+      ::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
@@ -223,65 +402,29 @@ struct is_convertible_impl
 
 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename To,is_convertible,void,To,false)
-BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename From,is_convertible,From,void,false)
+BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename From,is_convertible,From,void,true)
 #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
 BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename To,is_convertible,void const,To,false)
 BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename To,is_convertible,void volatile,To,false)
 BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename To,is_convertible,void const volatile,To,false)
-BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename From,is_convertible,From,void const,false)
-BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename From,is_convertible,From,void volatile,false)
-BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename From,is_convertible,From,void const volatile,false)
+BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename From,is_convertible,From,void const,true)
+BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename From,is_convertible,From,void volatile,true)
+BOOST_TT_AUX_BOOL_TRAIT_IMPL_PARTIAL_SPEC2_1(typename From,is_convertible,From,void const volatile,true)
 #endif
 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 
 } // namespace detail
 
-BOOST_TT_AUX_BOOL_TRAIT_DEF2(is_convertible,From,To,(::boost::detail::is_convertible_impl<From,To>::value))
-
+BOOST_TT_AUX_BOOL_TRAIT_DEF2(is_convertible,From,To,(::boost::detail::is_convertible_impl_dispatch<From,To>::value))
 
-#if defined(__GNUC__)
-
-// Declare specializations of is_convertible for all of the floating
-// types to all of the integral types. This suppresses some nasty
-// warnings
-
-#   define TT_AUX_IS_CONVERTIBLE_SPEC(T1,T2) \
-    BOOST_TT_AUX_BOOL_TRAIT_SPEC2(is_convertible,T1,T2,true) \
-    /**/
-
-#   define TT_AUX_IS_CONVERTIBLE_SPEC_2(T1,T2) \
-    TT_AUX_IS_CONVERTIBLE_SPEC(T1,signed T2) \
-    TT_AUX_IS_CONVERTIBLE_SPEC(T1,unsigned T2) \
-    /**/
-
-#   define TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_SPEC(F) \
-    TT_AUX_IS_CONVERTIBLE_SPEC(F,char) \
-    TT_AUX_IS_CONVERTIBLE_SPEC_2(F,char) \
-    TT_AUX_IS_CONVERTIBLE_SPEC_2(F,short) \
-    TT_AUX_IS_CONVERTIBLE_SPEC_2(F,int) \
-    TT_AUX_IS_CONVERTIBLE_SPEC_2(F,long) \
-    TT_AUX_IS_CONVERTIBLE_SPEC_2(F,long long) \
-    /**/
-
-#   define TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_CV_SPEC(F) \
-    TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_SPEC(F const) \
-    TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_SPEC(F volatile) \
-    TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_SPEC(F const volatile) \
-    /**/
-
-TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_CV_SPEC(float)
-TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_CV_SPEC(double)
-TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_CV_SPEC(long double)
+#else
 
-#   undef TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_CV_SPEC
-#   undef TT_AUX_IS_CONVERTIBLE_FROM_FLOAT_SPEC
-#   undef TT_AUX_IS_CONVERTIBLE_SPEC_2
-#   undef TT_AUX_IS_CONVERTIBLE_SPEC
+BOOST_TT_AUX_BOOL_TRAIT_DEF2(is_convertible,From,To,BOOST_IS_CONVERTIBLE(From,To))
 
-#endif // __GNUC__
+#endif
 
 } // namespace boost
 
-#include "boost/type_traits/detail/bool_trait_undef.hpp"
+#include <boost/type_traits/detail/bool_trait_undef.hpp>
 
 #endif // BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED