Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r68373 - in trunk: boost/utility boost/utility/detail libs/utility/test
From: daniel.j.walker_at_[hidden]
Date: 2011-01-22 17:18:49


Author: djwalker
Date: 2011-01-22 17:18:48 EST (Sat, 22 Jan 2011)
New Revision: 68373
URL: http://svn.boost.org/trac/boost/changeset/68373

Log:
use declval to fix #5098
Text files modified:
   trunk/boost/utility/detail/result_of_iterate.hpp | 20 +++++++-------------
   trunk/boost/utility/result_of.hpp | 3 +++
   trunk/libs/utility/test/result_of_test.cpp | 18 ++++++++++++++++++
   3 files changed, 28 insertions(+), 13 deletions(-)

Modified: trunk/boost/utility/detail/result_of_iterate.hpp
==============================================================================
--- trunk/boost/utility/detail/result_of_iterate.hpp (original)
+++ trunk/boost/utility/detail/result_of_iterate.hpp 2011-01-22 17:18:48 EST (Sat, 22 Jan 2011)
@@ -35,10 +35,7 @@
 
 #if !defined(BOOST_NO_DECLTYPE) && defined(BOOST_RESULT_OF_USE_DECLTYPE)
 
-// As of N2588, C++0x result_of only supports function call
-// expressions of the form f(x). This precludes support for member
-// function pointers, which are invoked with expressions of the form
-// o->*f(x). This implementation supports both.
+// Uses declval following N3225 20.7.7.6 when F is not a pointer.
 template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
          BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
 struct result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
@@ -56,18 +53,15 @@
 
 namespace detail {
 
-# define BOOST_RESULT_OF_STATIC_MEMBERS(z, n, _) \
- static T ## n t ## n; \
- /**/
-
 template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
          BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
-class cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
+struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
 {
- static F f;
- BOOST_PP_REPEAT(BOOST_PP_ITERATION(), BOOST_RESULT_OF_STATIC_MEMBERS, _)
-public:
- typedef decltype(f(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),t))) type;
+ typedef decltype(
+ boost::declval<F>()(
+ BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), declval<T, >() BOOST_PP_INTERCEPT)
+ )
+ ) type;
 };
 
 } // namespace detail

Modified: trunk/boost/utility/result_of.hpp
==============================================================================
--- trunk/boost/utility/result_of.hpp (original)
+++ trunk/boost/utility/result_of.hpp 2011-01-22 17:18:48 EST (Sat, 22 Jan 2011)
@@ -13,7 +13,9 @@
 #include <boost/preprocessor/iteration/iterate.hpp>
 #include <boost/preprocessor/punctuation/comma_if.hpp>
 #include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
 #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
+#include <boost/preprocessor/facilities/intercept.hpp>
 #include <boost/detail/workaround.hpp>
 #include <boost/mpl/has_xxx.hpp>
 #include <boost/mpl/if.hpp>
@@ -22,6 +24,7 @@
 #include <boost/type_traits/is_pointer.hpp>
 #include <boost/type_traits/is_member_function_pointer.hpp>
 #include <boost/type_traits/remove_cv.hpp>
+#include <boost/utility/declval.hpp>
 
 #ifndef BOOST_RESULT_OF_NUM_ARGS
 # define BOOST_RESULT_OF_NUM_ARGS 10

Modified: trunk/libs/utility/test/result_of_test.cpp
==============================================================================
--- trunk/libs/utility/test/result_of_test.cpp (original)
+++ trunk/libs/utility/test/result_of_test.cpp 2011-01-22 17:18:48 EST (Sat, 22 Jan 2011)
@@ -98,6 +98,11 @@
   unsigned int operator()();
   unsigned short operator()() volatile;
   const unsigned short operator()() const volatile;
+#if !defined(BOOST_NO_RVALUE_REFERENCES)
+ short operator()(int&&);
+ int operator()(int&);
+ long operator()(int const&);
+#endif
 };
 
 template<typename T>
@@ -108,6 +113,11 @@
   unsigned int operator()();
   unsigned short operator()() volatile;
   const unsigned short operator()() const volatile;
+#if !defined(BOOST_NO_RVALUE_REFERENCES)
+ short operator()(int&&);
+ int operator()(int&);
+ long operator()(int const&);
+#endif
 };
 
 struct X {};
@@ -232,6 +242,14 @@
   BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_of_template<void>(double)>::type, short>::value));
   BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_of_template<void>(void)>::type, unsigned short>::value));
   BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_of_template<void>(void)>::type, const unsigned short>::value));
+#if !defined(BOOST_NO_RVALUE_REFERENCES)
+ BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(int&&)>::type, short>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(int&)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(int const&)>::type, long>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(int&&)>::type, short>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(int&)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(int const&)>::type, long>::value));
+#endif
 #endif
 
   return 0;


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