use declval to fix #5098

[SVN r68373]
This commit is contained in:
Daniel Walker 2011-01-22 22:18:48 +00:00
parent 58bb88d4bd
commit c58748cfd9
3 changed files with 28 additions and 13 deletions

View File

@ -35,10 +35,7 @@ struct tr1_result_of<F(BOOST_RESULT_OF_ARGS)>
#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 @@ struct result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
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

View File

@ -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

View File

@ -98,6 +98,11 @@ struct no_result_type_or_result_of
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 @@ struct no_result_type_or_result_of_template
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 @@ int main()
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;