Ticket #7343: djw_result_of_sfinae.patch

File djw_result_of_sfinae.patch, 4.5 KB (added by Daniel Walker, 10 years ago)

updated patch incorporating suggestions from Michel Morin

  • boost/utility/detail/result_of_iterate.hpp

     
    5151            typename remove_cv<F>::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false
    5252          >
    5353        , detail::cpp0x_result_of_impl<
    54               F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))
     54              F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), true
    5555          >
    5656      >::type
    5757{};
     
    6060
    6161template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
    6262         BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
    63 struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
     63class is_callable<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))> {
     64    typedef char (&pass)[1];
     65    typedef char (&fail)[2];
     66
     67    template<typename G BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
     68             BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename S)>
     69    struct sub {};
     70
     71    template<typename G BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
     72             BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename S)>
     73    static pass test(sub<G BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
     74                         BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),S)>
     75                   , boost::remove_reference<
     76                          decltype(
     77                              boost::declval<G>()(
     78                                  BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), declval<S, >() BOOST_PP_INTERCEPT)
     79                              )
     80                          )
     81                      >* x = 0);
     82    static fail test(...);
     83
     84public:
     85    const static bool value = sizeof(pass) == sizeof(test(sub<F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
     86                                                              BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)
     87                                                          >()));
     88    typedef typename boost::mpl::bool_<value>::type type;
     89};
     90
     91template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
     92         BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
     93struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), true>
     94    : lazy_enable_if<
     95          is_callable<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
     96        , cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false>
     97      >
     98{};
     99
     100template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
     101         BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
     102struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false>
    64103{
    65104  typedef decltype(
    66105    boost::declval<F>()(
  • boost/utility/result_of.hpp

     
    2424#include <boost/type_traits/is_pointer.hpp>
    2525#include <boost/type_traits/is_member_function_pointer.hpp>
    2626#include <boost/type_traits/remove_cv.hpp>
     27#include <boost/type_traits/remove_reference.hpp>
    2728#include <boost/utility/declval.hpp>
     29#include <boost/utility/enable_if.hpp>
    2830
    2931#ifndef BOOST_RESULT_OF_NUM_ARGS
    3032#  define BOOST_RESULT_OF_NUM_ARGS 16
     
    5860
    5961BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
    6062
     63template<typename F> struct is_callable;
     64
    6165template<typename F, typename FArgs, bool HasResultType> struct tr1_result_of_impl;
    62 template<typename F> struct cpp0x_result_of_impl;
     66template<typename F, bool> struct cpp0x_result_of_impl;
    6367
    6468template<typename F>
    6569struct result_of_void_impl
  • libs/utility/test/result_of_test.cpp

     
    129129#endif
    130130};
    131131
     132// sfinae_tests are derived from example code from Joel de Guzman,
     133// which demonstrated the interaction between result_of and SFINAE.
     134template <typename F, typename Arg>
     135typename boost::result_of<F(Arg const&)>::type
     136sfinae_test(F f, Arg const& arg)
     137{
     138    return f(arg);
     139}
     140
     141template <typename F, typename Arg>
     142typename boost::result_of<F(Arg&)>::type
     143sfinae_test(F f, Arg& arg)
     144{
     145    return f(arg);
     146}
     147
     148int sfinae_test_f(int& i)
     149{
     150    return i;
     151}
     152
    132153struct X {};
    133154
    134155int main()
     
    268289#endif
    269290#endif
    270291
     292#if defined(BOOST_RESULT_OF_USE_DECLTYPE)
     293  int i = 123;
     294  sfinae_test(sfinae_test_f, i);
     295#endif // defined(BOOST_RESULT_OF_USE_DECLTYPE)
     296
    271297  return 0;
    272298}