diff --git a/include/boost/type_traits/is_base_and_derived.hpp b/include/boost/type_traits/is_base_and_derived.hpp index b6c69bf..267ade1 100644 --- a/include/boost/type_traits/is_base_and_derived.hpp +++ b/include/boost/type_traits/is_base_and_derived.hpp @@ -1,5 +1,5 @@ -// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// (C) Copyright Rani Sharoni 2002. // Permission to copy, use, modify, sell and distribute this software is // granted provided this copyright notice appears in all copies. This software // is provided "as is" without express or implied warranty, and with no claim @@ -11,8 +11,10 @@ #define BOOST_TT_IS_BASE_AND_DERIVED_HPP_INCLUDED #include "boost/type_traits/is_class.hpp" +#include "boost/type_traits/is_same.hpp" #include "boost/type_traits/is_convertible.hpp" #include "boost/type_traits/detail/ice_and.hpp" +#include "boost/type_traits/remove_cv.hpp" #include "boost/config.hpp" // should be the last #include @@ -22,16 +24,92 @@ namespace boost { namespace detail { -template +#if !defined(__BORLANDC__) + +/************************************************************************* + +This version detects ambiguous base classes and private base classes +correctly, and was devised by Rani Sharoni. + +*************************************************************************/ + +template +struct bd_helper +{ + template + static type_traits::yes_type check(D const volatile *, T); + static type_traits::no_type check(B const volatile *, int); +}; + +template +struct is_base_and_derived_impl2 +{ + struct Host + { + operator B const volatile *() const; + operator D const volatile *(); + }; + + BOOST_STATIC_CONSTANT(bool, value = + sizeof(bd_helper::check(Host(), 0)) == sizeof(type_traits::yes_type)); +}; + +#else + +// +// broken version: +// +template +struct is_base_and_derived_impl2 +{ + BOOST_STATIC_CONSTANT(bool, value = + (::boost::is_convertible::value)); +}; + +#define BOOST_BROKEN_IS_BASE_AND_DERIVED + +#endif + +template +struct is_base_and_derived_impl3 +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +template +struct is_base_and_derived_select +{ + template + struct rebind + { + typedef is_base_and_derived_impl3 type; + }; +}; + +template <> +struct is_base_and_derived_select +{ + template + struct rebind + { + typedef is_base_and_derived_impl2 type; + }; +}; + +template struct is_base_and_derived_impl { - BOOST_STATIC_CONSTANT(bool, value = - (::boost::type_traits::ice_and< - ::boost::is_convertible::value, - ::boost::is_class::value, - ::boost::is_class::value - >::value) - ); + typedef typename remove_cv::type ncvB; + typedef typename remove_cv::type ncvD; + + typedef is_base_and_derived_select< + ::boost::is_class::value, + ::boost::is_class::value, + ::boost::is_same::value> selector; + typedef typename selector::template rebind binder; + typedef typename binder::type bound_type; + + BOOST_STATIC_CONSTANT(bool, value = bound_type::value); }; } // namespace detail @@ -54,3 +132,5 @@ BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC2_2(typename Base,typename Derived,is_base_a #include "boost/type_traits/detail/bool_trait_undef.hpp" #endif // BOOST_TT_IS_BASE_AND_DERIVED_HPP_INCLUDED + + diff --git a/include/boost/type_traits/is_convertible.hpp b/include/boost/type_traits/is_convertible.hpp index 8c5345f..3479d88 100644 --- a/include/boost/type_traits/is_convertible.hpp +++ b/include/boost/type_traits/is_convertible.hpp @@ -18,6 +18,9 @@ #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" #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300) # include "boost/type_traits/is_void.hpp" @@ -166,16 +169,30 @@ struct is_convertible_impl static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To); static From _m_from; - BOOST_STATIC_CONSTANT(bool, value = + BOOST_STATIC_CONSTANT(bool, value = sizeof( _m_check(_m_from) ) == sizeof(::boost::type_traits::yes_type) ); }; #endif // is_convertible_impl +template +struct is_convertible_forwarder +{ + typedef typename add_reference::type ref_type; + BOOST_STATIC_CONSTANT(bool, value = + (::boost::type_traits::ice_and< + ::boost::detail::is_convertible_impl::value, + ::boost::type_traits::ice_not< + ::boost::is_array::value + >::value + >::value) + ); +}; + } // namespace detail -BOOST_TT_AUX_BOOL_TRAIT_DEF2(is_convertible,From,To,(::boost::detail::is_convertible_impl::value)) +BOOST_TT_AUX_BOOL_TRAIT_DEF2(is_convertible,From,To,(::boost::detail::is_convertible_forwarder::value)) // // Now add the full and partial specialisations