diff --git a/include/boost/type_traits/composite_traits.hpp b/include/boost/type_traits/composite_traits.hpp index fee249e..31ddcff 100644 --- a/include/boost/type_traits/composite_traits.hpp +++ b/include/boost/type_traits/composite_traits.hpp @@ -51,6 +51,9 @@ #ifndef BOOST_TT_ARRAY_TRAITS_HPP # include #endif +#ifndef BOOST_TYPE_TRAITS_IS_CLASS_HPP +# include +#endif namespace boost{ @@ -246,7 +249,7 @@ namespace detail // Don't evaluate convertibility to int_convertible unless the type // is non-arithmetic. This suppresses warnings with GCC. - template + template struct is_enum_helper { template @@ -271,11 +274,26 @@ template struct is_enum { private: typedef typename ::boost::add_reference::type r_type; + +# if (defined(__MWERKS__) && __MWERKS__ >= 0x3000) || BOOST_MSVC > 1300 || defined(BOOST_NO_COMPILER_CONFIG) BOOST_STATIC_CONSTANT(bool, selector = (::boost::type_traits::ice_or< - ::boost::is_arithmetic::value + ::boost::is_arithmetic::value , ::boost::is_reference::value + // We MUST do this on conforming compilers in order to + // correctly deduce that noncopyable types are not enums (dwa + // 2002/04/15)... + , ::boost::is_class::value >::value)); +# else + BOOST_STATIC_CONSTANT(bool, selector = + (::boost::type_traits::ice_or< + ::boost::is_arithmetic::value + , ::boost::is_reference::value + // However, not doing this on non-conforming compilers prevents + // a dependency recursion. + >::value)); +# endif typedef typename ::boost::detail::is_enum_helper::template type helper; public: BOOST_STATIC_CONSTANT(bool, value = helper::value); diff --git a/include/boost/type_traits/is_class.hpp b/include/boost/type_traits/is_class.hpp new file mode 100644 index 0000000..496a0ca --- /dev/null +++ b/include/boost/type_traits/is_class.hpp @@ -0,0 +1,49 @@ +// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard +// Hinnant & John Maddock 2000-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 as +// to its suitability for any purpose. +// +// See http://www.boost.org for most recent version including documentation. +// +#ifndef BOOST_TYPE_TRAITS_IS_CLASS_HPP +# define BOOST_TYPE_TRAITS_IS_CLASS_HPP + +# if (defined(__MWERKS__) && __MWERKS__ >= 0x3000) || BOOST_MSVC > 1300 || defined(BOOST_NO_COMPILER_CONFIG) +# ifndef BOOST_ICE_TYPE_TRAITS_HPP +# include +# endif + +# define BOOST_TYPE_TRAITS_IS_CLASS_DEFINED +namespace boost { + +template +struct is_class +{ + // This is actually the conforming implementation which works with + // abstract classes. However, enough compilers have trouble with + // it that most will use the one in + // boost/type_traits/object_traits.hpp. This implementation + // actually works with VC7.0, but other interactions seem to fail + // when we use it. + +// 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 + private: + template static ::boost::type_traits::yes_type is_class_helper(void(U::*)(void)); + template static ::boost::type_traits::no_type is_class_helper(...); + public: + BOOST_STATIC_CONSTANT( + bool, value = sizeof( + is_class_helper(0) + ) == sizeof(::boost::type_traits::yes_type)); +}; +} + +# else // nonconforming compilers will use a different impelementation, in object_traits.hpp + +# endif // nonconforming implementations + +#endif // BOOST_TYPE_TRAITS_IS_CLASS_HPP diff --git a/include/boost/type_traits/object_traits.hpp b/include/boost/type_traits/object_traits.hpp index 22bcfcc..4386e9c 100644 --- a/include/boost/type_traits/object_traits.hpp +++ b/include/boost/type_traits/object_traits.hpp @@ -30,6 +30,9 @@ #ifndef BOOST_FUNCTION_TYPE_TRAITS_HPP #include #endif +#ifndef BOOST_TYPE_TRAITS_IS_CLASS_HPP +# include +#endif #ifdef BOOST_HAS_SGI_TYPE_TRAITS # include @@ -79,6 +82,8 @@ struct is_scalar >::value)); }; +# ifndef BOOST_TYPE_TRAITS_IS_CLASS_DEFINED +// conforming compilers use the implementation in /********************************************** * * is_class @@ -87,24 +92,8 @@ struct is_scalar template struct is_class { -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -# if (defined(__MWERKS__) && __MWERKS__ >= 0x3000) || BOOST_MSVC >= 1300 || defined(BOOST_NO_COMPILER_CONFIG) - // This is actually the conforming implementation which works with - // abstract classes. However, enough compilers have trouble with - // it that most will use the following one. +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -// 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 - private: - template static ::boost::type_traits::yes_type is_class_helper(void(U::*)(void)); - template static ::boost::type_traits::no_type is_class_helper(...); - public: - BOOST_STATIC_CONSTANT( - bool, value = sizeof( - is_class_helper(0) - ) == sizeof(::boost::type_traits::yes_type)); -# else BOOST_STATIC_CONSTANT(bool, value = (::boost::type_traits::ice_and< ::boost::type_traits::ice_not< ::boost::is_union::value >::value, @@ -114,8 +103,7 @@ struct is_class ::boost::type_traits::ice_not< ::boost::is_void::value >::value, ::boost::type_traits::ice_not< ::boost::is_function::value >::value >::value)); -# endif -#else +# else BOOST_STATIC_CONSTANT(bool, value = (::boost::type_traits::ice_and< ::boost::type_traits::ice_not< ::boost::is_union::value >::value, @@ -124,9 +112,9 @@ struct is_class ::boost::type_traits::ice_not< ::boost::is_reference::value>::value, ::boost::type_traits::ice_not< ::boost::is_void::value >::value >::value)); -#endif +# endif }; - +# endif // nonconforming implementations /********************************************** * * is_compound @@ -354,27 +342,62 @@ struct has_nothrow_assign * **********************************************/ #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -namespace detail{ - -template -struct empty_helper_t1 : public T +namespace detail { + template + struct empty_helper_t1 : public T + { //#ifdef __MWERKS__ - empty_helper_t1(); // hh compiler bug workaround + empty_helper_t1(); // hh compiler bug workaround //#endif - int i[256]; -}; -struct empty_helper_t2 { int i[256]; }; + int i[256]; + }; + struct empty_helper_t2 { int i[256]; }; +} -template -struct empty_helper{ BOOST_STATIC_CONSTANT(bool, value = false); }; +# ifndef __BORLANDC__ +namespace detail +{ + template + struct empty_helper{ BOOST_STATIC_CONSTANT(bool, value = false); }; + + template + struct empty_helper + { + BOOST_STATIC_CONSTANT( + bool, value = (sizeof(empty_helper_t1) == sizeof(empty_helper_t2))); + }; +} template -struct empty_helper +struct is_empty { - BOOST_STATIC_CONSTANT(bool, value = - (sizeof(empty_helper_t1) == sizeof(empty_helper_t2))); + private: + typedef typename remove_cv::type cvt; + + public: + BOOST_STATIC_CONSTANT( + bool, value = ( + ::boost::type_traits::ice_or< + ::boost::detail::empty_helper::value>::value + , BOOST_IS_EMPTY(cvt) + >::value + )); }; + +# else // __BORLANDC__ + +namespace detail +{ + template + struct empty_helper{ BOOST_STATIC_CONSTANT(bool, value = false); }; + + template + struct empty_helper + { + BOOST_STATIC_CONSTANT(bool, value = + (sizeof(empty_helper_t1) == sizeof(empty_helper_t2))); + }; } template @@ -384,14 +407,18 @@ private: typedef typename remove_cv::type cvt; typedef typename add_reference::type r_type; public: - BOOST_STATIC_CONSTANT(bool, value = - (::boost::type_traits::ice_or< - ::boost::detail::empty_helper::value - >::value, - BOOST_IS_EMPTY(cvt) - >::value)); + BOOST_STATIC_CONSTANT( + bool, value = ( + ::boost::type_traits::ice_or< + ::boost::detail::empty_helper< + T + , ::boost::is_class::value + , ::boost::is_convertible< r_type,int>::value + >::value + , BOOST_IS_EMPTY(cvt) + >::value)); }; +# endif // __BORLANDC__ #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #ifdef BOOST_MSVC6_MEMBER_TEMPLATES diff --git a/tests/composite_traits_test.cpp b/tests/composite_traits_test.cpp index 034278e..629682b 100644 --- a/tests/composite_traits_test.cpp +++ b/tests/composite_traits_test.cpp @@ -121,7 +121,8 @@ int cpp_main(int argc, char* argv[]) value_test(false, boost::is_enum::value) value_test(true, boost::is_enum::value) value_test(false, boost::is_enum::value) - //value_test(false, boost::is_enum::value) + value_test(false, boost::is_enum::value) + value_test(false, boost::is_enum::value) value_test(false, boost::is_enum::value) value_test(false, boost::is_enum::value)