Index: boost/utility/detail/result_of_iterate.hpp =================================================================== --- boost/utility/detail/result_of_iterate.hpp (revision 80349) +++ boost/utility/detail/result_of_iterate.hpp (working copy) @@ -51,7 +51,7 @@ typename remove_cv::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false > , detail::cpp0x_result_of_impl< - F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)) + F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), true > >::type {}; @@ -60,7 +60,46 @@ template -struct cpp0x_result_of_impl +class is_callable { + typedef char (&pass)[1]; + typedef char (&fail)[2]; + + template + struct sub {}; + + template + static pass test(sub + , boost::remove_reference< + decltype( + boost::declval()( + BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), declval() BOOST_PP_INTERCEPT) + ) + ) + >* x = 0); + static fail test(...); + +public: + const static bool value = sizeof(pass) == sizeof(test(sub())); + typedef typename boost::mpl::bool_::type type; +}; + +template +struct cpp0x_result_of_impl + : lazy_enable_if< + is_callable + , cpp0x_result_of_impl + > +{}; + +template +struct cpp0x_result_of_impl { typedef decltype( boost::declval()( Index: boost/utility/result_of.hpp =================================================================== --- boost/utility/result_of.hpp (revision 80349) +++ boost/utility/result_of.hpp (working copy) @@ -24,7 +24,9 @@ #include #include #include +#include #include +#include #ifndef BOOST_RESULT_OF_NUM_ARGS # define BOOST_RESULT_OF_NUM_ARGS 16 @@ -58,8 +60,10 @@ BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) +template struct is_callable; + template struct tr1_result_of_impl; -template struct cpp0x_result_of_impl; +template struct cpp0x_result_of_impl; template struct result_of_void_impl Index: libs/utility/test/result_of_test.cpp =================================================================== --- libs/utility/test/result_of_test.cpp (revision 80352) +++ libs/utility/test/result_of_test.cpp (working copy) @@ -129,6 +129,27 @@ #endif }; +// sfinae_tests are derived from example code from Joel de Guzman, +// which demonstrated the interaction between result_of and SFINAE. +template +typename boost::result_of::type +sfinae_test(F f, Arg const& arg) +{ + return f(arg); +} + +template +typename boost::result_of::type +sfinae_test(F f, Arg& arg) +{ + return f(arg); +} + +int sfinae_test_f(int& i) +{ + return i; +} + struct X {}; int main() @@ -268,5 +289,10 @@ #endif #endif +#if defined(BOOST_RESULT_OF_USE_DECLTYPE) + int i = 123; + sfinae_test(sfinae_test_f, i); +#endif // defined(BOOST_RESULT_OF_USE_DECLTYPE) + return 0; }