From 32f2d33eedfb3766c410dc04b1b7ba10f4f03206 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Tue, 6 Jan 2004 13:37:10 +0000 Subject: [PATCH] Added fixes for gcc, to fix remaining regressions with is_class/is_convertible and is_enum [SVN r21513] --- include/boost/type_traits/config.hpp | 2 +- include/boost/type_traits/is_class.hpp | 19 +++++++++++ include/boost/type_traits/is_convertible.hpp | 9 ++++-- include/boost/type_traits/is_enum.hpp | 34 +++++++++++++++++++- test/tricky_function_type_test.cpp | 2 ++ 5 files changed, 61 insertions(+), 5 deletions(-) diff --git a/include/boost/type_traits/config.hpp b/include/boost/type_traits/config.hpp index 59fdcce..59d90e8 100644 --- a/include/boost/type_traits/config.hpp +++ b/include/boost/type_traits/config.hpp @@ -24,7 +24,7 @@ # define BOOST_TT_DECL /**/ #endif -# if (defined(__MWERKS__) && __MWERKS__ >= 0x3000) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1301)) || defined(__EDG_VERSION__) || defined(BOOST_NO_COMPILER_CONFIG) +# if (defined(__MWERKS__) && __MWERKS__ >= 0x3000) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1301)) || defined(__EDG_VERSION__) || (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(BOOST_NO_COMPILER_CONFIG) # define BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION #endif diff --git a/include/boost/type_traits/is_class.hpp b/include/boost/type_traits/is_class.hpp index bf6dc18..5d72be3 100644 --- a/include/boost/type_traits/is_class.hpp +++ b/include/boost/type_traits/is_class.hpp @@ -48,6 +48,24 @@ namespace detail { // is_class<> metafunction due to Paul Mensonides // (leavings@attbi.com). For more details: // http://groups.google.com/groups?hl=en&selm=000001c1cc83%24e154d5e0%247772e50c%40c161550a&rnum=1 +#ifdef __GNUC__ + +template static ::boost::type_traits::yes_type is_class_tester(void(U::*)(void)); +template static ::boost::type_traits::no_type is_class_tester(...); + +template +struct is_class_impl +{ + + BOOST_STATIC_CONSTANT(bool, value = + (::boost::type_traits::ice_and< + sizeof(is_class_tester(0)) == sizeof(::boost::type_traits::yes_type), + ::boost::type_traits::ice_not< ::boost::is_union::value >::value + >::value) + ); +}; + +#else template struct is_class_impl @@ -82,6 +100,7 @@ struct is_class_impl { }; # endif +#endif #else diff --git a/include/boost/type_traits/is_convertible.hpp b/include/boost/type_traits/is_convertible.hpp index 877d4ad..528cd31 100644 --- a/include/boost/type_traits/is_convertible.hpp +++ b/include/boost/type_traits/is_convertible.hpp @@ -107,7 +107,7 @@ struct is_convertible_impl struct any_conversion { template any_conversion(const volatile T&); - //template any_conversion(T&); + template any_conversion(T&); }; template struct checker @@ -124,8 +124,7 @@ struct is_convertible_basic_impl == sizeof(::boost::type_traits::yes_type); }; -#elif (defined(BOOST_MSVC) && (BOOST_MSVC > 1310)) \ - || (defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 245) && !defined(__ICL)) \ +#elif (defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 245) && !defined(__ICL)) \ || defined(__IBMCPP__) // // This is *almost* an ideal world implementation as it doesn't rely @@ -133,6 +132,10 @@ struct is_convertible_basic_impl // 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 any_conversion(const volatile T&); diff --git a/include/boost/type_traits/is_enum.hpp b/include/boost/type_traits/is_enum.hpp index 7ae3cc4..0661c97 100644 --- a/include/boost/type_traits/is_enum.hpp +++ b/include/boost/type_traits/is_enum.hpp @@ -19,6 +19,11 @@ #include #endif #include "boost/type_traits/config.hpp" +#if defined(BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION) +# include +# include +#endif + // should be the last #include #include "boost/type_traits/detail/bool_trait_def.hpp" @@ -29,6 +34,20 @@ namespace boost { namespace detail { +#if defined(BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION) + +template +struct is_class_or_union +{ + BOOST_STATIC_CONSTANT(bool, value = + (::boost::type_traits::ice_or< + ::boost::is_class::value + , ::boost::is_union::value + >::value)); +}; + +#else + template struct is_class_or_union { @@ -50,6 +69,7 @@ struct is_class_or_union # endif # endif }; +#endif struct int_convertible { @@ -81,13 +101,25 @@ template struct is_enum_impl typedef ::boost::add_reference ar_t; typedef typename ar_t::type r_type; -#if defined __GNUC__ +#if defined(__GNUC__) + +#ifdef BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION + BOOST_STATIC_CONSTANT(bool, selector = + (::boost::type_traits::ice_or< + ::boost::is_arithmetic::value + , ::boost::is_reference::value + , ::boost::is_function::value + , is_class_or_union::value + >::value)); +#else BOOST_STATIC_CONSTANT(bool, selector = (::boost::type_traits::ice_or< ::boost::is_arithmetic::value , ::boost::is_reference::value , ::boost::is_function::value >::value)); +#endif // BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION + #else BOOST_STATIC_CONSTANT(bool, selector = (::boost::type_traits::ice_or< diff --git a/test/tricky_function_type_test.cpp b/test/tricky_function_type_test.cpp index 33ea4e2..8e2e16e 100644 --- a/test/tricky_function_type_test.cpp +++ b/test/tricky_function_type_test.cpp @@ -21,6 +21,7 @@ # include # include # include +# include #endif TT_TEST_BEGIN(tricky_function_type_test) @@ -39,6 +40,7 @@ BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_copy::value, false); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_assign::value, false); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_destructor::value, false); BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_base_and_derived::value), false); +BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible::value), false); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_class::value, false);