Ticket #7753: result_of.patch

File result_of.patch, 13.9 KB (added by Nathan Crookston <nathan.crookston+boost@…>, 10 years ago)

Updated to use _CXX11_ style macros.

  • boost/utility/detail/result_of_iterate.hpp

     
    3737            (boost::detail::has_result_type<F>::value)> >::type { };
    3838#endif
    3939
    40 #ifdef BOOST_RESULT_OF_USE_DECLTYPE
     40#if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
    4141
    4242// Uses declval following N3225 20.7.7.6 when F is not a pointer.
    4343template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
    44 struct result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
     44struct cpp0x_result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
    4545    : mpl::if_<
    4646          is_member_function_pointer<F>
    4747        , detail::tr1_result_of_impl<
     
    139139
    140140} // namespace detail
    141141
    142 #else // defined(BOOST_RESULT_OF_USE_DECLTYPE)
    143142
     143#if defined(BOOST_RESULT_OF_USE_DECLTYPE)
     144template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
     145struct result_of<F(BOOST_RESULT_OF_ARGS)>
     146    : cpp0x_result_of<F(BOOST_RESULT_OF_ARGS)> { };
     147#endif
     148
     149#if defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
     150template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
     151struct result_of<F(BOOST_RESULT_OF_ARGS)>
     152    : mpl::if_<mpl::or_<detail::has_result_type<F>, detail::has_result<F> >,
     153               tr1_result_of<F(BOOST_RESULT_OF_ARGS)>,
     154               cpp0x_result_of<F(BOOST_RESULT_OF_ARGS)> >::type { };
     155#endif
     156
     157#else // defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
     158
    144159#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
    145160template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
    146161struct result_of<F(BOOST_RESULT_OF_ARGS)>
  • boost/utility/result_of.hpp

     
    3838
    3939// Use the decltype-based version of result_of by default if the compiler
    4040// supports N3276 <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2011/n3276.pdf>.
    41 // The user can force the choice by defining either BOOST_RESULT_OF_USE_DECLTYPE or
    42 // BOOST_RESULT_OF_USE_TR1, but not both!
    43 #if defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1)
    44 #  error Both BOOST_RESULT_OF_USE_DECLTYPE and BOOST_RESULT_OF_USE_TR1 cannot be defined at the same time.
     41// The user can force the choice by defining BOOST_RESULT_OF_USE_DECLTYPE,
     42// BOOST_RESULT_OF_USE_TR1, or BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK but not more than one!
     43#if (defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1)) || \
     44    (defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)) || \
     45    (defined(BOOST_RESULT_OF_USE_TR1) && defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK))
     46#  error More than one of BOOST_RESULT_OF_USE_DECLTYPE, BOOST_RESULT_OF_USE_TR1 and \
     47  BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK cannot be defined at the same time.
    4548#endif
    4649
     50#if defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) && defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
     51#  error Cannot fallback to decltype if the presence of a nested result struct cannot be tested.
     52#endif
     53
    4754#ifndef BOOST_RESULT_OF_USE_TR1
    4855#  ifndef BOOST_RESULT_OF_USE_DECLTYPE
    49 #    ifndef BOOST_NO_CXX11_DECLTYPE_N3276 // this implies !defined(BOOST_NO_CXX11_DECLTYPE)
    50 #      define BOOST_RESULT_OF_USE_DECLTYPE
    51 #    else
    52 #      define BOOST_RESULT_OF_USE_TR1
     56#    ifndef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
     57#      ifndef BOOST_NO_CXX11_DECLTYPE_N3276 // this implies !defined(BOOST_NO_CXX11_DECLTYPE)
     58#        define BOOST_RESULT_OF_USE_DECLTYPE
     59#      else
     60#        if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
     61#          define BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
     62#        else
     63#          define BOOST_RESULT_OF_USE_TR1
     64#        endif
     65#      endif
    5366#    endif
    5467#  endif
    5568#endif
     
    5871
    5972template<typename F> struct result_of;
    6073template<typename F> struct tr1_result_of; // a TR1-style implementation of result_of
     74template<typename F> struct cpp0x_result_of;
    6175
    6276#if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
    6377namespace detail {
    6478
    6579BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
    6680
     81BOOST_MPL_HAS_XXX_TEMPLATE_DEF(result)
     82
    6783template<typename F, typename FArgs, bool HasResultType> struct tr1_result_of_impl;
    6884
    6985#ifdef BOOST_NO_SFINAE_EXPR
  • libs/utility/utility.htm

     
    185185&gt;::type type; // type is int</pre>
    186186                </blockquote>
    187187
    188                 <p>You can test whether <code>result_of</code> is using
    189                 <code>decltype</code> by checking if the macro
     188                <p>You can test whether <code>result_of</code> is automatically
     189                using <code>decltype</code> by checking if the macro
    190190                <code>BOOST_RESULT_OF_USE_DECLTYPE</code> is defined after
    191191                including <code>result_of.hpp</code>. You can also force
    192192                <code>result_of</code> to use <code>decltype</code> by
    193193                defining <code>BOOST_RESULT_OF_USE_DECLTYPE</code> prior
    194194                to including <code>result_of.hpp</code>.</p>
    195195
    196                 <p>If <code>decltype</code> is not used,
     196                <p>If <code>decltype</code> is not supported by the compiler,
    197197                then automatic result type deduction of function
    198198                objects is not possible. Instead, <code>result_of</code>
    199199                uses the following protocol to allow the programmer to
     
    255255                represent the return type of
    256256                <code>operator()</code> given a call expression.</p>
    257257
     258                <p>If your compiler supports <code>decltype</code> in a form
     259                which is inadequate to justify its automatic use (see the
     260                <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3276.pdf">proposal</a> which the compiler must implement to be considered adequate),
     261                a hybrid approach is used.  If a member type
     262                <code>result_type</code> or a member template struct
     263                <code>result</code> is present, then the
     264                non-<code>decltype</code> <code>result_of</code> protocol is
     265                used.  If neither type is present, then <code>result_of</code>
     266                falls back on the <code>decltype</code>-based protocol.  This
     267                allows <code>result_of</code> to be used on compilers which
     268                support C++11 lambda functions (which define neither
     269                result_type nor result) and partially support
     270                <code>decltype</code>.  You can test whether
     271                <code>result_of</code> is automatically using this hybrid
     272                approach by checking if the macro
     273                <code>BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK</code>
     274                is defined after including <code>result_of.hpp</code>.  You
     275                can also force <code>result_of</code> to use this hybrid
     276                approach by defining
     277                <code>BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK</code>
     278                prior to including <code>result_of.hpp</code>.</p>
     279
    258280                <a name="BOOST_NO_RESULT_OF"></a>
    259281                <p>This implementation of <code>result_of</code>
    260282                requires class template partial specialization, the
  • libs/utility/test/result_of_test.cpp

     
    150150    return i;
    151151}
    152152
     153#if !defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_RESULT_OF_USE_TR1)
     154template <typename R, typename F>
     155void check_void_result_of_lambda_is(F f)
     156{
     157  BOOST_STATIC_ASSERT((boost::is_same<typename boost::result_of<F()>::type, R>::value));
     158  BOOST_STATIC_ASSERT((boost::is_same<typename boost::cpp0x_result_of<F()>::type, R>::value));
     159}
     160template <typename R, typename F>
     161void check_unary_result_of_lambda_is(F f)
     162{
     163  BOOST_STATIC_ASSERT((boost::is_same<typename boost::result_of<F(int)>::type, R>::value));
     164  BOOST_STATIC_ASSERT((boost::is_same<typename boost::cpp0x_result_of<F(int)>::type, R>::value));
     165}
     166#endif
     167
    153168struct X {};
    154169
    155170int main()
     
    169184  typedef int (X::*mem_func_ptr_v)(float) volatile;
    170185  typedef int (X::*mem_func_ptr_cv)(float) const volatile;
    171186  typedef int (X::*mem_func_ptr_0)();
     187  typedef int (*pf_t)(int);
    172188
    173189  BOOST_STATIC_ASSERT((is_same<result_of<int_result_type(float)>::type, int>::value));
    174190  BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(double)>::type, int>::value));
     
    215231  BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value));
    216232#endif
    217233
     234#if !defined(BOOST_NO_CXX11_DECLTYPE)
     235  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, char>::value));
     236  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, char>::value));
     237
     238  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<func_ptr(char, float)>::type, int>::value));
     239  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<func_ref(char, float)>::type, int>::value));
     240  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<func_ptr_0()>::type, int>::value));
     241  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<func_ref_0()>::type, int>::value));
     242  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<func_ptr_void(char, float)>::type, void>::value));
     243  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<func_ref_void(char, float)>::type, void>::value));
     244  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<func_ptr_void_0()>::type, void>::value));
     245  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<func_ref_void_0()>::type, void>::value));
     246  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<mem_func_ptr(X,char)>::type, int>::value));
     247  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<mem_func_ptr_c(X,char)>::type, int>::value));
     248  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<mem_func_ptr_v(X,char)>::type, int>::value));
     249  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<mem_func_ptr_cv(X,char)>::type, int>::value));
     250  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<mem_func_ptr_0(X)>::type, int>::value));
     251  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<pf_t(int)>::type, int>::value));
     252  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<pf_t const(int)>::type,int>::value));
     253
     254  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<result_of_member_function_template(double)>::type, double>::value));
     255  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<const result_of_member_function_template(double)>::type, cv_overload_check<const double> >::value));
     256  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<volatile result_of_member_function_template(double)>::type, cv_overload_check<volatile double> >::value));
     257  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<const volatile result_of_member_function_template(double)>::type, cv_overload_check<const volatile double> >::value));
     258  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<result_of_member_function_template(int &, int)>::type, int &>::value));
     259  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<result_of_member_function_template(int const &, int)>::type, int const &>::value));
     260  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value));
     261  BOOST_STATIC_ASSERT((is_same<cpp0x_result_of<result_of_member_function_template(int const volatile &, int)>::type, int const volatile &>::value));
     262#endif
     263
    218264  BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, int>::value));
    219265  BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value));
    220266
     
    266312  BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value));
    267313  BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int const volatile &, int)>::type, int const volatile &>::value));
    268314
    269   typedef int (*pf_t)(int);
    270315  BOOST_STATIC_ASSERT((is_same<result_of<pf_t(int)>::type, int>::value));
    271316  BOOST_STATIC_ASSERT((is_same<result_of<pf_t const(int)>::type,int>::value));
    272317
    273318  BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t(int)>::type, int>::value));
    274319  BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t const(int)>::type,int>::value));
    275320
    276 #if defined(BOOST_RESULT_OF_USE_DECLTYPE)
     321#if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
    277322  BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(double)>::type, short>::value));
    278323  BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result(double)>::type, cv_overload_check<const short> >::value));
    279324  BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result(double)>::type, cv_overload_check<volatile short> >::value));
     
    306351  sfinae_test(sfinae_test_f, i);
    307352#endif // defined(BOOST_RESULT_OF_USE_DECLTYPE)
    308353
     354#if !defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_RESULT_OF_USE_TR1)
     355  check_void_result_of_lambda_is<float>([]{ return 0.f; });
     356  check_void_result_of_lambda_is<double>([]() -> double { return 0; });
     357  check_void_result_of_lambda_is<void>([]{});
     358
     359  check_unary_result_of_lambda_is<float>([](int){ return 0.f; });
     360  check_unary_result_of_lambda_is<double>([](int) -> double { return 0; });
     361  check_unary_result_of_lambda_is<void>([](int){});
     362#endif
     363
    309364  return 0;
    310365}