Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r80234 - in trunk: boost/type_traits libs/type_traits/test
From: john_at_[hidden]
Date: 2012-08-26 08:14:13


Author: johnmaddock
Date: 2012-08-26 08:14:11 EDT (Sun, 26 Aug 2012)
New Revision: 80234
URL: http://svn.boost.org/trac/boost/changeset/80234

Log:
Move new test cases into the "tricky" section as many compilers can't handle them.
Revert previous change that used std::is_convertible on GCC as it breaks code prior to gcc-4.7.
Fix MSVC intrinsic to handle function types better.
Filter out rvalue-refs from is_function.
Partially apply patch from #7251 to make is_convertible behave more according to C++11.
Refs #7251.
Text files modified:
   trunk/boost/type_traits/intrinsics.hpp | 9 +---
   trunk/boost/type_traits/is_convertible.hpp | 62 +++++++++++++++++++++++++++++----------
   trunk/boost/type_traits/is_function.hpp | 5 +++
   trunk/libs/type_traits/test/is_convertible_test.cpp | 13 +------
   trunk/libs/type_traits/test/tricky_function_type_test.cpp | 7 ++++
   trunk/libs/type_traits/test/tricky_rvalue_test.cpp | 2 +
   6 files changed, 66 insertions(+), 32 deletions(-)

Modified: trunk/boost/type_traits/intrinsics.hpp
==============================================================================
--- trunk/boost/type_traits/intrinsics.hpp (original)
+++ trunk/boost/type_traits/intrinsics.hpp 2012-08-26 08:14:11 EDT (Sun, 26 Aug 2012)
@@ -82,6 +82,7 @@
 #if (defined(BOOST_MSVC) && defined(BOOST_MSVC_FULL_VER) && (BOOST_MSVC_FULL_VER >=140050215))\
          || (defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500))
 # include <boost/type_traits/is_same.hpp>
+# include <boost/type_traits/is_function.hpp>
 
 # define BOOST_IS_UNION(T) __is_union(T)
 # define BOOST_IS_POD(T) (__is_pod(T) && __has_trivial_constructor(T))
@@ -98,7 +99,7 @@
 # define BOOST_IS_ABSTRACT(T) __is_abstract(T)
 # define BOOST_IS_BASE_OF(T,U) (__is_base_of(T,U) && !is_same<T,U>::value)
 # define BOOST_IS_CLASS(T) __is_class(T)
-# define BOOST_IS_CONVERTIBLE(T,U) ((__is_convertible_to(T,U) || is_same<T,U>::value) && !__is_abstract(U))
+# define BOOST_IS_CONVERTIBLE(T,U) ((__is_convertible_to(T,U) || (is_same<T,U>::value && !is_function<U>::value)) && !__is_abstract(U))
 # define BOOST_IS_ENUM(T) __is_enum(T)
 // This one doesn't quite always do the right thing:
 // # define BOOST_IS_POLYMORPHIC(T) __is_polymorphic(T)
@@ -222,11 +223,6 @@
 # define BOOST_ALIGNMENT_OF(T) __alignof__(T)
 # endif
 
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
-# include <type_traits>
-# define BOOST_IS_CONVERTIBLE(T,U) (std::is_convertible<T, U>::value)
-#endif
-
 # define BOOST_HAS_TYPE_TRAITS_INTRINSICS
 #endif
 
@@ -293,3 +289,4 @@
 
 
 
+

Modified: trunk/boost/type_traits/is_convertible.hpp
==============================================================================
--- trunk/boost/type_traits/is_convertible.hpp (original)
+++ trunk/boost/type_traits/is_convertible.hpp 2012-08-26 08:14:11 EDT (Sun, 26 Aug 2012)
@@ -17,13 +17,13 @@
 #include <boost/type_traits/detail/yes_no_type.hpp>
 #include <boost/type_traits/config.hpp>
 #include <boost/type_traits/is_array.hpp>
-#include <boost/type_traits/add_reference.hpp>
 #include <boost/type_traits/ice.hpp>
 #include <boost/type_traits/is_arithmetic.hpp>
 #include <boost/type_traits/is_void.hpp>
 #ifndef BOOST_NO_IS_ABSTRACT
 #include <boost/type_traits/is_abstract.hpp>
 #endif
+#include <boost/type_traits/add_lvalue_reference.hpp>
 #include <boost/type_traits/add_rvalue_reference.hpp>
 #include <boost/type_traits/is_function.hpp>
 
@@ -69,7 +69,7 @@
     {
         static no_type BOOST_TT_DECL _m_check(...);
         static yes_type BOOST_TT_DECL _m_check(To);
- static typename add_rvalue_reference<From>::type _m_from;
+ static typename add_lvalue_reference<From>::type _m_from;
         enum { value = sizeof( _m_check(_m_from) ) == sizeof(yes_type) };
     };
 };
@@ -107,7 +107,7 @@
         static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(T);
     };
 
- static typename add_rvalue_reference<From>::type _m_from;
+ static typename add_lvalue_reference<From>::type _m_from;
     static bool const value = sizeof( checker<To>::_m_check(_m_from) )
         == sizeof(::boost::type_traits::yes_type);
 #pragma option pop
@@ -134,10 +134,17 @@
 template <typename From, typename To>
 struct is_convertible_basic_impl
 {
+ typedef typename add_lvalue_reference<From>::type lvalue_type;
     typedef typename add_rvalue_reference<From>::type rvalue_type;
- static From _m_from;
- static bool const value = sizeof( boost::detail::checker<To>::_m_check(static_cast<rvalue_type>(_m_from), 0) )
+ static lvalue_type _m_from;
+ static bool const value =
+#if !defined(BOOST_NO_RVALUE_REFERENCES) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 6)))
+ sizeof( boost::detail::checker<To>::_m_check(static_cast<rvalue_type>(_m_from), 0) )
         == sizeof(::boost::type_traits::yes_type);
+#else
+ sizeof( boost::detail::checker<To>::_m_check(_m_from, 0) )
+ == sizeof(::boost::type_traits::yes_type);
+#endif
 };
 
 #elif (defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 245) && !defined(__ICL)) \
@@ -167,11 +174,16 @@
 {
     static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion ...);
     static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int);
+ typedef typename add_lvalue_reference<From>::type lvalue_type;
     typedef typename add_rvalue_reference<From>::type rvalue_type;
- static From _m_from;
+ static lvalue_type _m_from;
 
     BOOST_STATIC_CONSTANT(bool, value =
+#ifndef BOOST_NO_RVALUE_REFERENCES
         sizeof( _m_check(static_cast<rvalue_type>(_m_from), 0) ) == sizeof(::boost::type_traits::yes_type)
+#else
+ sizeof( _m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type)
+#endif
         );
 };
 
@@ -194,13 +206,18 @@
     template <class T>
     static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion, float, T);
     static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int, int);
- typedef typename add_rvalue_reference<From>::type rvalue_type;
- static From _m_from;
+ typedef typename add_lvalue_reference<From>::type lvalue_type;
+ typedef typename add_rvalue_reference<From>::type rvalue_type;
+ static lvalue_type _m_from;
 
     // Static constants sometime cause the conversion of _m_from to To to be
     // called. This doesn't happen with an enum.
     enum { value =
+#ifndef BOOST_NO_RVALUE_REFERENCES
         sizeof( _m_check(static_cast<rvalue_type>(_m_from), 0, 0) ) == sizeof(::boost::type_traits::yes_type)
+#else
+ sizeof( _m_check(_m_from, 0, 0) ) == sizeof(::boost::type_traits::yes_type)
+#endif
         };
 };
 
@@ -228,11 +245,16 @@
 {
     static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion ...);
     static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int);
+ typedef typename add_lvalue_reference<From>::type lvalue_type;
     typedef typename add_rvalue_reference<From>::type rvalue_type;
- static From _m_from;
+ static lvalue_type _m_from;
 
     BOOST_STATIC_CONSTANT(bool, value =
+#ifndef BOOST_NO_RVALUE_REFERENCES
         sizeof( _m_check(static_cast<rvalue_type>(_m_from), 0) ) == sizeof(::boost::type_traits::yes_type)
+#else
+ sizeof( _m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type)
+#endif
         );
 };
 
@@ -241,10 +263,15 @@
 {
     static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...);
     static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To);
- typedef typename add_rvalue_reference<From>::type rvalue_type;
- static From _m_from;
+ typedef typename add_lvalue_reference<From>::type lvalue_type;
+ typedef typename add_rvalue_reference<From>::type rvalue_type;
+ static lvalue_type _m_from;
     BOOST_STATIC_CONSTANT(bool, value =
+#ifndef BOOST_NO_RVALUE_REFERENCES
         sizeof( _m_check(static_cast<rvalue_type>(_m_from)) ) == sizeof(::boost::type_traits::yes_type)
+#else
+ sizeof( _m_check(_m_from) ) == sizeof(::boost::type_traits::yes_type)
+#endif
         );
 };
 
@@ -266,8 +293,9 @@
 {
     static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...);
     static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To);
+ typedef typename add_lvalue_reference<From>::type lvalue_type;
     typedef typename add_rvalue_reference<From>::type rvalue_type;
- static From _m_from;
+ static lvalue_type _m_from;
 #ifdef BOOST_MSVC
 #pragma warning(push)
 #pragma warning(disable:4244)
@@ -276,7 +304,11 @@
 #endif
 #endif
     BOOST_STATIC_CONSTANT(bool, value =
+#ifndef BOOST_NO_RVALUE_REFERENCES
         sizeof( _m_check(static_cast<rvalue_type>(_m_from)) ) == sizeof(::boost::type_traits::yes_type)
+#else
+ sizeof( _m_check(_m_from) ) == sizeof(::boost::type_traits::yes_type)
+#endif
         );
 #ifdef BOOST_MSVC
 #pragma warning(pop)
@@ -290,11 +322,10 @@
 template <typename From, typename To>
 struct is_convertible_impl
 {
- typedef typename add_reference<From>::type ref_type;
     enum { value =
         (::boost::type_traits::ice_and<
             ::boost::type_traits::ice_or<
- ::boost::detail::is_convertible_basic_impl<ref_type,To>::value,
+ ::boost::detail::is_convertible_basic_impl<From,To>::value,
                ::boost::is_void<To>::value
>::value,
             ::boost::type_traits::ice_not<
@@ -309,11 +340,10 @@
 template <typename From, typename To>
 struct is_convertible_impl
 {
- typedef typename add_reference<From>::type ref_type;
     BOOST_STATIC_CONSTANT(bool, value =
         (::boost::type_traits::ice_and<
             ::boost::type_traits::ice_or<
- ::boost::detail::is_convertible_basic_impl<ref_type,To>::value,
+ ::boost::detail::is_convertible_basic_impl<From,To>::value,
                ::boost::is_void<To>::value
>::value,
             ::boost::type_traits::ice_not<

Modified: trunk/boost/type_traits/is_function.hpp
==============================================================================
--- trunk/boost/type_traits/is_function.hpp (original)
+++ trunk/boost/type_traits/is_function.hpp 2012-08-26 08:14:11 EDT (Sun, 26 Aug 2012)
@@ -83,6 +83,11 @@
 template <typename T>
 struct is_function_impl<T&> : public false_type
 {};
+#ifndef BOOST_NO_RVALUE_REFERENCES
+template <typename T>
+struct is_function_impl<T&&> : public false_type
+{};
+#endif
 #endif
 
 #endif

Modified: trunk/libs/type_traits/test/is_convertible_test.cpp
==============================================================================
--- trunk/libs/type_traits/test/is_convertible_test.cpp (original)
+++ trunk/libs/type_traits/test/is_convertible_test.cpp 2012-08-26 08:14:11 EDT (Sun, 26 Aug 2012)
@@ -103,8 +103,11 @@
 #ifndef BOOST_NO_RVALUE_REFERENCES
 BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<const int&&, int>::value), true);
 BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int&&, const int&>::value), true);
+#if !defined(__GNUC__) || ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 6)))
+// Machinary required to support this, not available prior to gcc-4.7.0:
 BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int, int&>::value), false);
 #endif
+#endif
 BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int(&)[4], const int*>::value), true);
 BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int(&)(int), int(*)(int)>::value), true);
 BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int *, const int*>::value), true);
@@ -115,16 +118,6 @@
 BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int*, int[3]>::value), false);
 BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<test_abc3, const test_abc1&>::value), true);
 
-BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int(), int()>::value), false);
-BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int(), int(*)()>::value), true);
-BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int(), int(* const)()>::value), true);
-BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int(), int(* volatile)()>::value), true);
-BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int(), int(* const volatile)()>::value), true);
-BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int(), int(&)()>::value), true);
-#ifndef BOOST_NO_RVALUE_REFERENCES
-BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int(), int(&&)()>::value), true);
-#endif
-
 BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<non_pointer, void*>::value), true);
 BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<non_pointer, int*>::value), false);
 BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<non_int_pointer, int*>::value), true);

Modified: trunk/libs/type_traits/test/tricky_function_type_test.cpp
==============================================================================
--- trunk/libs/type_traits/test/tricky_function_type_test.cpp (original)
+++ trunk/libs/type_traits/test/tricky_function_type_test.cpp 2012-08-26 08:14:11 EDT (Sun, 26 Aug 2012)
@@ -97,6 +97,13 @@
 typedef void (test_abc1::*vproc3)(int, char, long, long, ...)const;
 BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_member_function_pointer<vproc3>::value, true);
 
+BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int(), int()>::value), false);
+BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int(), int(*)()>::value), true);
+BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int(), int(* const)()>::value), true);
+BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int(), int(* volatile)()>::value), true);
+BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int(), int(* const volatile)()>::value), true);
+BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int(), int(&)()>::value), true);
+
 TT_TEST_END
 
 

Modified: trunk/libs/type_traits/test/tricky_rvalue_test.cpp
==============================================================================
--- trunk/libs/type_traits/test/tricky_rvalue_test.cpp (original)
+++ trunk/libs/type_traits/test/tricky_rvalue_test.cpp 2012-08-26 08:14:11 EDT (Sun, 26 Aug 2012)
@@ -13,6 +13,7 @@
 # include <boost/type_traits/is_lvalue_reference.hpp>
 # include <boost/type_traits/is_rvalue_reference.hpp>
 # include <boost/type_traits/is_reference.hpp>
+# include <boost/type_traits/is_function.hpp>
 #endif
 
 TT_TEST_BEGIN(rvalue_reference_test)
@@ -22,6 +23,7 @@
 BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_rvalue_reference<int (&)(int)>::value, false);
 BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_rvalue_reference<int (&&)(int)>::value, true);
 BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int&&, int&>::value), false);
+BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int(), int(&&)()>::value), true);
 #endif
 
 TT_TEST_END


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk