Use conforming is_class for EDG compilers

Make is_enum work for class types which are convertible to anything at
all (on many compilers).

smart_ptr library workarounds for __MWERKS__ (must use member function
pointer for unspecified_bool_type).


[SVN r20244]
This commit is contained in:
Dave Abrahams
2003-10-02 17:49:06 +00:00
parent 9c7099c693
commit 416038f37d
5 changed files with 80 additions and 21 deletions

View File

@ -25,7 +25,7 @@
# define BOOST_TT_DECL /**/
#endif
# if (defined(__MWERKS__) && __MWERKS__ >= 0x3000) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1301)) || defined(BOOST_NO_COMPILER_CONFIG)
# if (defined(__MWERKS__) && __MWERKS__ >= 0x3000) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1301)) || defined(__EDG_VERSION__) || defined(BOOST_NO_COMPILER_CONFIG)
# define BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION
#endif

View File

@ -1,5 +1,5 @@
// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard
// Hinnant & John Maddock 2000-2002. Permission to copy, use,
// Hinnant & John Maddock 2000-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
@ -17,6 +17,10 @@
#ifdef BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION
# include "boost/type_traits/detail/yes_no_type.hpp"
# ifdef __EDG_VERSION__
# include "boost/type_traits/is_const.hpp"
# include "boost/type_traits/is_volatile.hpp"
# endif
#else
# include "boost/type_traits/is_scalar.hpp"
# include "boost/type_traits/is_array.hpp"
@ -59,6 +63,26 @@ struct is_class_impl
);
};
# ifdef __EDG_VERSION__
template <typename T>
struct is_class_impl<T const>
: is_class_impl<T>
{
};
template <typename T>
struct is_class_impl<T volatile>
: is_class_impl<T>
{
};
template <typename T>
struct is_class_impl<T const volatile>
: is_class_impl<T>
{
};
# endif
#else
template <typename T>

View File

@ -20,10 +20,6 @@
#endif
#include "boost/type_traits/config.hpp"
#ifdef BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION
# include "boost/type_traits/is_class.hpp"
#endif
// should be the last #include
#include "boost/type_traits/detail/bool_trait_def.hpp"
@ -32,7 +28,29 @@ namespace boost {
#if !(defined(__BORLANDC__) && (__BORLANDC__ <= 0x551))
namespace detail {
template <typename T>
struct is_class_or_union
{
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200) // we simply can't detect it this way.
BOOST_STATIC_CONSTANT(bool, value = false);
# else
template <class U> static ::boost::type_traits::yes_type is_class_or_union_tester(void(U::*)(void));
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) \
|| BOOST_WORKAROUND(__MWERKS__, <= 0x3000) // no SFINAE
static ::boost::type_traits::no_type is_class_or_union_tester(...);
BOOST_STATIC_CONSTANT(
bool, value = sizeof(is_class_or_union_tester(0)) == sizeof(::boost::type_traits::yes_type));
# else
template <class U>
static ::boost::type_traits::no_type is_class_or_union_tester(...);
BOOST_STATIC_CONSTANT(
bool, value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(::boost::type_traits::yes_type));
# endif
# endif
};
struct int_convertible
{
int_convertible(int);
@ -63,20 +81,7 @@ template <typename T> struct is_enum_impl
typedef ::boost::add_reference<T> ar_t;
typedef typename ar_t::type r_type;
#if defined(BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION)
BOOST_STATIC_CONSTANT(bool, selector =
(::boost::type_traits::ice_or<
::boost::is_arithmetic<T>::value
, ::boost::is_reference<T>::value
// We MUST do this on conforming compilers in order to
// correctly deduce that noncopyable types are not enums (dwa
// 2002/04/15)...
// strictly speaking is_convertible should work with non-copyable
// types rendering this fix unnecessary - unfortunately this is not
// the case for all compilers yet (JM 2003/04/16)...
, ::boost::is_class<T>::value
>::value));
#elif defined __GNUC__
#if defined __GNUC__
BOOST_STATIC_CONSTANT(bool, selector =
(::boost::type_traits::ice_or<
::boost::is_arithmetic<T>::value
@ -88,6 +93,7 @@ template <typename T> struct is_enum_impl
(::boost::type_traits::ice_or<
::boost::is_arithmetic<T>::value
, ::boost::is_reference<T>::value
, is_class_or_union<T>::value
// However, not doing this on non-conforming compilers prevents
// a dependency recursion.
>::value));
@ -100,6 +106,7 @@ template <typename T> struct is_enum_impl
#else
typedef ::boost::detail::is_enum_helper<selector> se_t;
#endif
typedef typename se_t::template type<r_type> helper;
BOOST_STATIC_CONSTANT(bool, value = helper::value);
};

View File

@ -81,6 +81,7 @@ test-suite type_traits :
[ type-traits-run tricky_add_pointer_test.cpp ]
[ type-traits-run tricky_function_type_test.cpp ]
[ type-traits-run tricky_incomplete_type_test.cpp ]
[ type-traits-run tricky_is_enum_test.cpp ]
[ type-traits-run tricky_partial_spec_test.cpp ]
[ type-traits-run type_with_alignment_test.cpp ]

27
test/tricky_is_enum_test.cpp Executable file
View File

@ -0,0 +1,27 @@
// (C) Copyright Dave Abrahams 2003. Use, modification and distribution is
// 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)
#include "test.hpp"
#include "check_integral_constant.hpp"
#include TYPE_TRAITS(is_enum)
struct convertible_to_anything
{
template<typename T> operator T() { return 0; }
};
TT_TEST_BEGIN(is_enum)
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_enum<convertible_to_anything>::value, false);
TT_TEST_END