More conformance fixes

[SVN r13494]
This commit is contained in:
Dave Abrahams
2002-04-15 16:30:53 +00:00
parent db10a86c04
commit 10b04fb413
4 changed files with 139 additions and 44 deletions

View File

@ -51,6 +51,9 @@
#ifndef BOOST_TT_ARRAY_TRAITS_HPP
# include <boost/type_traits/array_traits.hpp>
#endif
#ifndef BOOST_TYPE_TRAITS_IS_CLASS_HPP
# include <boost/type_traits/is_class.hpp>
#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 <bool arithmetic_or_reference>
template <bool is_class_arithmetic_or_reference = true>
struct is_enum_helper
{
template <class T>
@ -271,11 +274,26 @@ template <typename T> struct is_enum
{
private:
typedef typename ::boost::add_reference<T>::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<T>::value
::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)...
, ::boost::is_class<T>::value
>::value));
# else
BOOST_STATIC_CONSTANT(bool, selector =
(::boost::type_traits::ice_or<
::boost::is_arithmetic<T>::value
, ::boost::is_reference<T>::value
// However, not doing this on non-conforming compilers prevents
// a dependency recursion.
>::value));
# endif
typedef typename ::boost::detail::is_enum_helper<selector>::template type<r_type> helper;
public:
BOOST_STATIC_CONSTANT(bool, value = helper::value);

View File

@ -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 <boost/type_traits/ice.hpp>
# endif
# define BOOST_TYPE_TRAITS_IS_CLASS_DEFINED
namespace boost {
template <typename T>
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 <class U> static ::boost::type_traits::yes_type is_class_helper(void(U::*)(void));
template <class U> static ::boost::type_traits::no_type is_class_helper(...);
public:
BOOST_STATIC_CONSTANT(
bool, value = sizeof(
is_class_helper<T>(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

View File

@ -30,6 +30,9 @@
#ifndef BOOST_FUNCTION_TYPE_TRAITS_HPP
#include <boost/type_traits/function_traits.hpp>
#endif
#ifndef BOOST_TYPE_TRAITS_IS_CLASS_HPP
# include <boost/type_traits/is_class.hpp>
#endif
#ifdef BOOST_HAS_SGI_TYPE_TRAITS
# include <type_traits.h>
@ -79,6 +82,8 @@ struct is_scalar
>::value));
};
# ifndef BOOST_TYPE_TRAITS_IS_CLASS_DEFINED
// conforming compilers use the implementation in <boost/type_traits/is_class.hpp>
/**********************************************
*
* is_class
@ -87,24 +92,8 @@ struct is_scalar
template <typename T>
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 <class U> static ::boost::type_traits::yes_type is_class_helper(void(U::*)(void));
template <class U> static ::boost::type_traits::no_type is_class_helper(...);
public:
BOOST_STATIC_CONSTANT(
bool, value = sizeof(
is_class_helper<T>(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<T>::value >::value,
@ -114,8 +103,7 @@ struct is_class
::boost::type_traits::ice_not< ::boost::is_void<T>::value >::value,
::boost::type_traits::ice_not< ::boost::is_function<T>::value >::value
>::value));
# endif
#else
# else
BOOST_STATIC_CONSTANT(bool, value =
(::boost::type_traits::ice_and<
::boost::type_traits::ice_not< ::boost::is_union<T>::value >::value,
@ -124,9 +112,9 @@ struct is_class
::boost::type_traits::ice_not< ::boost::is_reference<T>::value>::value,
::boost::type_traits::ice_not< ::boost::is_void<T>::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 <typename T>
struct empty_helper_t1 : public T
namespace detail
{
template <typename T>
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 <typename T, bool is_a_class = false>
struct empty_helper{ BOOST_STATIC_CONSTANT(bool, value = false); };
# ifndef __BORLANDC__
namespace detail
{
template <typename T, bool is_a_class = false>
struct empty_helper{ BOOST_STATIC_CONSTANT(bool, value = false); };
template <typename T>
struct empty_helper<T, true>
{
BOOST_STATIC_CONSTANT(
bool, value = (sizeof(empty_helper_t1<T>) == sizeof(empty_helper_t2)));
};
}
template <typename T>
struct empty_helper<T, true>
struct is_empty
{
BOOST_STATIC_CONSTANT(bool, value =
(sizeof(empty_helper_t1<T>) == sizeof(empty_helper_t2)));
private:
typedef typename remove_cv<T>::type cvt;
public:
BOOST_STATIC_CONSTANT(
bool, value = (
::boost::type_traits::ice_or<
::boost::detail::empty_helper<T,::boost::is_class<T>::value>::value
, BOOST_IS_EMPTY(cvt)
>::value
));
};
# else // __BORLANDC__
namespace detail
{
template <typename T, bool is_a_class, bool convertible_to_int>
struct empty_helper{ BOOST_STATIC_CONSTANT(bool, value = false); };
template <typename T>
struct empty_helper<T, true, false>
{
BOOST_STATIC_CONSTANT(bool, value =
(sizeof(empty_helper_t1<T>) == sizeof(empty_helper_t2)));
};
}
template <typename T>
@ -384,14 +407,18 @@ private:
typedef typename remove_cv<T>::type cvt;
typedef typename add_reference<T>::type r_type;
public:
BOOST_STATIC_CONSTANT(bool, value =
(::boost::type_traits::ice_or<
::boost::detail::empty_helper<T,
::boost::is_class<T>::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<T>::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

View File

@ -121,7 +121,8 @@ int cpp_main(int argc, char* argv[])
value_test(false, boost::is_enum<int>::value)
value_test(true, boost::is_enum<enum_UDT>::value)
value_test(false, boost::is_enum<int_convertible>::value)
//value_test(false, boost::is_enum<int&>::value)
value_test(false, boost::is_enum<int&>::value)
value_test(false, boost::is_enum<boost::noncopyable>::value)
value_test(false, boost::is_enum<void>::value)
value_test(false, boost::is_enum<test_abc1>::value)