Ticket #7753: result_of.diff
File result_of.diff, 13.9 KB (added by , 10 years ago) |
---|
-
boost/utility/detail/result_of_iterate.hpp
37 37 (boost::detail::has_result_type<F>::value)> >::type { }; 38 38 #endif 39 39 40 #if def BOOST_RESULT_OF_USE_DECLTYPE40 #if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) 41 41 42 42 // Uses declval following N3225 20.7.7.6 when F is not a pointer. 43 43 template<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))>44 struct cpp0x_result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))> 45 45 : mpl::if_< 46 46 is_member_function_pointer<F> 47 47 , detail::tr1_result_of_impl< … … 139 139 140 140 } // namespace detail 141 141 142 #else // defined(BOOST_RESULT_OF_USE_DECLTYPE)143 142 143 #if defined(BOOST_RESULT_OF_USE_DECLTYPE) 144 template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> 145 struct 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) 150 template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> 151 struct 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 144 159 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) 145 160 template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> 146 161 struct result_of<F(BOOST_RESULT_OF_ARGS)> -
boost/utility/result_of.hpp
38 38 39 39 // Use the decltype-based version of result_of by default if the compiler 40 40 // 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. 45 48 #endif 46 49 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 47 54 #ifndef BOOST_RESULT_OF_USE_TR1 48 55 # ifndef BOOST_RESULT_OF_USE_DECLTYPE 49 # ifndef BOOST_NO_DECLTYPE_N3276 // this implies !defined(BOOST_NO_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_DECLTYPE_N3276 // this implies !defined(BOOST_NO_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 53 66 # endif 54 67 # endif 55 68 #endif … … 58 71 59 72 template<typename F> struct result_of; 60 73 template<typename F> struct tr1_result_of; // a TR1-style implementation of result_of 74 template<typename F> struct cpp0x_result_of; 61 75 62 76 #if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) 63 77 namespace detail { 64 78 65 79 BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) 66 80 81 BOOST_MPL_HAS_XXX_TEMPLATE_DEF(result) 82 67 83 template<typename F, typename FArgs, bool HasResultType> struct tr1_result_of_impl; 68 84 69 85 #ifdef BOOST_NO_SFINAE_EXPR -
libs/utility/test/result_of_test.cpp
150 150 return i; 151 151 } 152 152 153 #if !defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_RESULT_OF_USE_TR1) 154 template <typename R, typename F> 155 void 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 } 160 template <typename R, typename F> 161 void 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 153 168 struct X {}; 154 169 155 170 int main() … … 169 184 typedef int (X::*mem_func_ptr_v)(float) volatile; 170 185 typedef int (X::*mem_func_ptr_cv)(float) const volatile; 171 186 typedef int (X::*mem_func_ptr_0)(); 187 typedef int (*pf_t)(int); 172 188 173 189 BOOST_STATIC_ASSERT((is_same<result_of<int_result_type(float)>::type, int>::value)); 174 190 BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(double)>::type, int>::value)); … … 215 231 BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value)); 216 232 #endif 217 233 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 218 264 BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, int>::value)); 219 265 BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value)); 220 266 … … 266 312 BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value)); 267 313 BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int const volatile &, int)>::type, int const volatile &>::value)); 268 314 269 typedef int (*pf_t)(int);270 315 BOOST_STATIC_ASSERT((is_same<result_of<pf_t(int)>::type, int>::value)); 271 316 BOOST_STATIC_ASSERT((is_same<result_of<pf_t const(int)>::type,int>::value)); 272 317 273 318 BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t(int)>::type, int>::value)); 274 319 BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t const(int)>::type,int>::value)); 275 320 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) 277 322 BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(double)>::type, short>::value)); 278 323 BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result(double)>::type, cv_overload_check<const short> >::value)); 279 324 BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result(double)>::type, cv_overload_check<volatile short> >::value)); … … 306 351 sfinae_test(sfinae_test_f, i); 307 352 #endif // defined(BOOST_RESULT_OF_USE_DECLTYPE) 308 353 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 309 364 return 0; 310 365 } -
libs/utility/utility.htm
185 185 >::type type; // type is int</pre> 186 186 </blockquote> 187 187 188 <p>You can test whether <code>result_of</code> is using189 <code>decltype</code> by checking if the macro188 <p>You can test whether <code>result_of</code> is automatically 189 using <code>decltype</code> by checking if the macro 190 190 <code>BOOST_RESULT_OF_USE_DECLTYPE</code> is defined after 191 191 including <code>result_of.hpp</code>. You can also force 192 192 <code>result_of</code> to use <code>decltype</code> by 193 193 defining <code>BOOST_RESULT_OF_USE_DECLTYPE</code> prior 194 194 to including <code>result_of.hpp</code>.</p> 195 195 196 <p>If <code>decltype</code> is not used,196 <p>If <code>decltype</code> is not supported by the compiler, 197 197 then automatic result type deduction of function 198 198 objects is not possible. Instead, <code>result_of</code> 199 199 uses the following protocol to allow the programmer to … … 255 255 represent the return type of 256 256 <code>operator()</code> given a call expression.</p> 257 257 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 258 280 <a name="BOOST_NO_RESULT_OF"></a> 259 281 <p>This implementation of <code>result_of</code> 260 282 requires class template partial specialization, the