diff --git a/include/boost/utility/detail/result_of_iterate.hpp b/include/boost/utility/detail/result_of_iterate.hpp index 4d35fc0..98063cd 100644 --- a/include/boost/utility/detail/result_of_iterate.hpp +++ b/include/boost/utility/detail/result_of_iterate.hpp @@ -23,31 +23,29 @@ #endif #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) -template +template struct tr1_result_of : mpl::if_< mpl::or_< is_pointer, is_member_function_pointer > , boost::detail::tr1_result_of_impl< - typename remove_cv::type, - typename remove_cv::type(BOOST_RESULT_OF_ARGS), + typename remove_cv::type, + typename remove_cv::type(BOOST_RESULT_OF_ARGS), (boost::detail::has_result_type::value)> , boost::detail::tr1_result_of_impl< F, - F(BOOST_RESULT_OF_ARGS), + F(BOOST_RESULT_OF_ARGS), (boost::detail::has_result_type::value)> >::type { }; #endif #ifdef BOOST_RESULT_OF_USE_DECLTYPE // Uses declval following N3225 20.7.7.6 when F is not a pointer. -template +template struct result_of : mpl::if_< is_member_function_pointer , detail::tr1_result_of_impl< - typename remove_cv::type, + typename remove_cv::type, typename remove_cv::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false > , detail::cpp0x_result_of_impl< @@ -58,51 +56,60 @@ struct result_of namespace detail { -#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1700)) +#ifdef BOOST_NO_SFINAE_EXPR -template -class is_callable { - typedef char (&pass)[1]; - typedef char (&fail)[2]; +template +struct BOOST_PP_CAT(result_of_is_callable_fun_2_, BOOST_PP_ITERATION()); - template - struct sub {}; - template - struct stub {}; - - template - static pass test(sub - , stub< - decltype( - boost::declval()( - BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::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 BOOST_PP_CAT(result_of_is_callable_fun_2_, BOOST_PP_ITERATION()) { + R operator()(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)) const; + typedef result_of_private_type const &(*pfn_t)(...); + operator pfn_t() const volatile; }; -template +template +struct BOOST_PP_CAT(result_of_is_callable_fun_, BOOST_PP_ITERATION()); + +template +struct BOOST_PP_CAT(result_of_is_callable_fun_, BOOST_PP_ITERATION()) + : BOOST_PP_CAT(result_of_is_callable_fun_2_, BOOST_PP_ITERATION()) +{}; + +template +struct BOOST_PP_CAT(result_of_is_callable_fun_, BOOST_PP_ITERATION()) + : BOOST_PP_CAT(result_of_is_callable_fun_2_, BOOST_PP_ITERATION()) +{}; + +template +struct BOOST_PP_CAT(result_of_select_call_wrapper_type_, BOOST_PP_ITERATION()) + : mpl::eval_if< + is_class::type>, + result_of_wrap_callable, + mpl::identity::type> > + > +{}; + +template +struct BOOST_PP_CAT(result_of_is_callable_, BOOST_PP_ITERATION()) { + typedef typename BOOST_PP_CAT(result_of_select_call_wrapper_type_, BOOST_PP_ITERATION())::type wrapper_t; + static const bool value = ( + sizeof(result_of_no_type) == sizeof(detail::result_of_is_private_type( + (boost::declval()(BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval() BOOST_PP_INTERCEPT)), 0) + )) + ); + typedef mpl::bool_ type; +}; + +template struct cpp0x_result_of_impl : lazy_enable_if< - is_callable + BOOST_PP_CAT(result_of_is_callable_, BOOST_PP_ITERATION()) , cpp0x_result_of_impl > {}; -template +template struct cpp0x_result_of_impl { typedef decltype( @@ -112,11 +119,10 @@ struct cpp0x_result_of_impl -struct cpp0x_result_of_impl +struct cpp0x_result_of_impl()( BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval() BOOST_PP_INTERCEPT) @@ -129,15 +135,14 @@ struct cpp0x_result_of_impl +template struct result_of : tr1_result_of { }; #endif @@ -146,27 +151,24 @@ struct result_of #undef BOOST_RESULT_OF_ARGS -#if BOOST_PP_ITERATION() >= 1 +#if BOOST_PP_ITERATION() >= 1 namespace detail { -template +template struct tr1_result_of_impl { typedef R type; }; -template +template struct tr1_result_of_impl { typedef R type; }; #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) -template +template struct tr1_result_of_impl @@ -174,8 +176,7 @@ struct tr1_result_of_impl +template struct tr1_result_of_impl +template struct tr1_result_of_impl +template struct tr1_result_of_impl -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include #include +#include #include +#include #include #include #include +#include #include #include @@ -61,21 +66,68 @@ BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) template struct tr1_result_of_impl; -#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1700)) +#ifdef BOOST_NO_SFINAE_EXPR + +template T result_of_decay(T); + +struct result_of_private_type +{ + result_of_private_type const &operator,(int) const; +}; + +template +struct result_of_callable_class : C { + result_of_callable_class(); + typedef result_of_private_type const &(*pfn_t)(...); + operator pfn_t() const volatile; +}; + +typedef char result_of_yes_type; // sizeof(result_of_yes_type) == 1 +typedef char (&result_of_no_type)[2]; // sizeof(result_of_no_type) == 2 + +template +result_of_no_type result_of_is_private_type(T const &); + +result_of_yes_type result_of_is_private_type(result_of_private_type const &); + +template class Wrapper, typename C> +struct result_of_wrap_callable { + typedef Wrapper type; +}; + +template class Wrapper, typename C> +struct result_of_wrap_callable { + typedef typename result_of_wrap_callable::type &type; +}; + +template class Wrapper, typename C> +struct result_of_wrap_callable { + typedef typename result_of_wrap_callable::type const type; +}; + +template class Wrapper, typename C> +struct result_of_wrap_callable { + typedef typename result_of_wrap_callable::type volatile type; +}; + +template class Wrapper, typename C> +struct result_of_wrap_callable { + typedef typename result_of_wrap_callable::type const volatile type; +}; -template class is_callable; template struct cpp0x_result_of_impl; -#else // BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1700)) +#else // BOOST_NO_SFINAE_EXPR template struct result_of_always_void { - typedef void type; + typedef void type; }; + template struct cpp0x_result_of_impl {}; -#endif // BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1700)) +#endif // BOOST_NO_SFINAE_EXPR template struct result_of_void_impl