-// (C) Copyright Rani Sharoni 2003.
-// 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
-// as to its suitability for any purpose.
+// (C) Copyright Rani Sharoni 2003.
+// 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 for most recent version including documentation.
-
+// See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
#ifndef BOOST_TT_IS_BASE_AND_DERIVED_HPP_INCLUDED
#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"
+#include <boost/type_traits/intrinsics.hpp>
+#ifndef BOOST_IS_BASE_OF
+#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/config.hpp>
+#include <boost/static_assert.hpp>
+#endif
+#include <boost/type_traits/remove_cv.hpp>
// should be the last #include
-#include "boost/type_traits/detail/bool_trait_def.hpp"
+#include <boost/type_traits/detail/bool_trait_def.hpp>
namespace boost {
namespace detail {
-#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)) \
- && !BOOST_WORKAROUND(__SUNPRO_CC , BOOST_TESTED_AT(0x540)) \
- && !BOOST_WORKAROUND(__EDG_VERSION__, <= 243)
+#ifndef BOOST_IS_BASE_OF
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581)) \
+ && !BOOST_WORKAROUND(__SUNPRO_CC , <= 0x540) \
+ && !BOOST_WORKAROUND(__EDG_VERSION__, <= 243) \
+ && !BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840))
+
// The EDG version number is a lower estimate.
// It is not currently known which EDG version
// exactly fixes the problem.
This version detects ambiguous base classes and private base classes
correctly, and was devised by Rani Sharoni.
-Explanation by Terje SlettebΓΈ and Rani Sharoni.
+Explanation by Terje Slettebo and Rani Sharoni.
Let's take the multiple base class below as an example, and the following
will also show why there's not a problem with private or ambiguous base
A user-defined conversion sequence consists of an SC, followed by an UDC,
followed by another SC. Either SC may be the identity conversion.
-When passing the default-constructed Host object to the overloaded check()
+When passing the default-constructed Host object to the overloaded check_sig()
functions (initialization 8.5/14/4/3), we have several viable implicit
conversion sequences:
-For "static no_type check(B const volatile *, int)" we have the conversion
+For "static no_type check_sig(B const volatile *, int)" we have the conversion
sequences:
C -> C const (SC - Qualification Adjustment) -> B const volatile* (UDC)
C -> D const volatile* (UDC) -> B1 const volatile* / B2 const volatile* ->
B const volatile* (SC - Conversion)
-For "static yes_type check(D const volatile *, T)" we have the conversion
+For "static yes_type check_sig(D const volatile *, T)" we have the conversion
sequence:
C -> D const volatile* (UDC)
If D is not derived from B, it has to choose between C -> C const -> B const
volatile* for the first function, and C -> D const volatile* for the second
function, which are just as good (both requires a UDC, 13.3.3.2), had it not
-been for the fact that "static no_type check(B const volatile *, int)" is
+been for the fact that "static no_type check_sig(B const volatile *, int)" is
not templated, which makes C -> C const -> B const volatile* the best choice
(13.3.3/1/4), resulting in "no".
Also, if Host::operator B const volatile* hadn't been const, the two
-conversion sequences for "static no_type check(B const volatile *, int)", in
+conversion sequences for "static no_type check_sig(B const volatile *, int)", in
the case where D is derived from B, would have been ambiguous.
See also
template <typename B, typename D>
struct bd_helper
{
+ //
+ // This VC7.1 specific workaround stops the compiler from generating
+ // an internal compiler error when compiling with /vmg (thanks to
+ // Aleksey Gurtovoy for figuring out the workaround).
+ //
+#if !BOOST_WORKAROUND(BOOST_MSVC, == 1310)
template <typename T>
- static type_traits::yes_type check(D const volatile *, T);
- static type_traits::no_type check(B const volatile *, int);
+ static type_traits::yes_type check_sig(D const volatile *, T);
+ static type_traits::no_type check_sig(B const volatile *, int);
+#else
+ static type_traits::yes_type check_sig(D const volatile *, long);
+ static type_traits::no_type check_sig(B const volatile * const&, int);
+#endif
};
template<typename B, typename D>
struct is_base_and_derived_impl2
{
+#if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000)
+#pragma warning(push)
+#pragma warning(disable:6334)
+#endif
+ //
+ // May silently do the wrong thing with incomplete types
+ // unless we trap them here:
+ //
+ BOOST_STATIC_ASSERT(sizeof(B) != 0);
+ BOOST_STATIC_ASSERT(sizeof(D) != 0);
+
struct Host
{
+#if !BOOST_WORKAROUND(BOOST_MSVC, == 1310)
operator B const volatile *() const;
+#else
+ operator B const volatile * const&() const;
+#endif
operator D const volatile *();
};
BOOST_STATIC_CONSTANT(bool, value =
- sizeof(bd_helper<B,D>::check(Host(), 0)) == sizeof(type_traits::yes_type));
+ sizeof(bd_helper<B,D>::check_sig(Host(), 0)) == sizeof(type_traits::yes_type));
+#if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000)
+#pragma warning(pop)
+#endif
};
#else
typedef is_base_and_derived_select<
::boost::is_class<B>::value,
::boost::is_class<D>::value,
- ::boost::is_same<B,D>::value> selector;
+ ::boost::is_same<ncvB,ncvD>::value> selector;
typedef typename selector::template rebind<ncvB,ncvD> binder;
typedef typename binder::type bound_type;
BOOST_STATIC_CONSTANT(bool, value = bound_type::value);
};
+#else
+template <typename B, typename D>
+struct is_base_and_derived_impl
+{
+ typedef typename remove_cv<B>::type ncvB;
+ typedef typename remove_cv<D>::type ncvD;
+ BOOST_STATIC_CONSTANT(bool, value = (BOOST_IS_BASE_OF(B,D) && ! ::boost::is_same<ncvB,ncvD>::value));
+};
+#endif
} // namespace detail
BOOST_TT_AUX_BOOL_TRAIT_DEF2(
BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC2_2(typename Base,typename Derived,is_base_and_derived,Base&,Derived&,false)
#endif
+#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x610))
+BOOST_TT_AUX_BOOL_TRAIT_PARTIAL_SPEC2_1(typename Base,is_base_and_derived,Base,Base,false)
+#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_BASE_AND_DERIVED_HPP_INCLUDED