Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r80713 - in branches/release: . boost boost/utility boost/utility/detail libs libs/utility libs/utility/test
From: eric_at_[hidden]
Date: 2012-09-26 14:52:09


Author: eric_niebler
Date: 2012-09-26 14:52:08 EDT (Wed, 26 Sep 2012)
New Revision: 80713
URL: http://svn.boost.org/trac/boost/changeset/80713

Log:
result_of: merge [80636],[80654],[80655],[80656],[80712] from trunk
Properties modified:
   branches/release/ (props changed)
   branches/release/boost/ (props changed)
   branches/release/boost/utility/ (props changed)
   branches/release/libs/ (props changed)
   branches/release/libs/utility/ (props changed)
Text files modified:
   branches/release/boost/utility/detail/result_of_iterate.hpp | 129 +++++++++++++++++++--------------------
   branches/release/boost/utility/result_of.hpp | 73 +++++++++++++++++++---
   branches/release/libs/utility/test/result_of_test.cpp | 12 +++
   3 files changed, 138 insertions(+), 76 deletions(-)

Modified: branches/release/boost/utility/detail/result_of_iterate.hpp
==============================================================================
--- branches/release/boost/utility/detail/result_of_iterate.hpp (original)
+++ branches/release/boost/utility/detail/result_of_iterate.hpp 2012-09-26 14:52:08 EDT (Wed, 26 Sep 2012)
@@ -23,31 +23,29 @@
 #endif
 
 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
-template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
- BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
+template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
 struct tr1_result_of<F(BOOST_RESULT_OF_ARGS)>
     : mpl::if_<
           mpl::or_< is_pointer<F>, is_member_function_pointer<F> >
         , boost::detail::tr1_result_of_impl<
- typename remove_cv<F>::type,
- typename remove_cv<F>::type(BOOST_RESULT_OF_ARGS),
+ typename remove_cv<F>::type,
+ typename remove_cv<F>::type(BOOST_RESULT_OF_ARGS),
             (boost::detail::has_result_type<F>::value)>
         , boost::detail::tr1_result_of_impl<
             F,
- F(BOOST_RESULT_OF_ARGS),
+ F(BOOST_RESULT_OF_ARGS),
             (boost::detail::has_result_type<F>::value)> >::type { };
 #endif
 
 #ifdef BOOST_RESULT_OF_USE_DECLTYPE
 
 // Uses declval following N3225 20.7.7.6 when F is not a pointer.
-template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
- BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
+template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
 struct result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
     : mpl::if_<
           is_member_function_pointer<F>
         , detail::tr1_result_of_impl<
- typename remove_cv<F>::type,
+ typename remove_cv<F>::type,
             typename remove_cv<F>::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false
>
         , detail::cpp0x_result_of_impl<
@@ -58,51 +56,60 @@
 
 namespace detail {
 
-#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1700))
+#ifdef BOOST_NO_SFINAE_EXPR
 
-template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
- BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
-class is_callable<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))> {
- typedef char (&pass)[1];
- typedef char (&fail)[2];
-
- template<typename G BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
- BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename S)>
- struct sub {};
- template<typename S>
- struct stub {};
-
- template<typename G BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
- BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename S)>
- static pass test(sub<G BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
- BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),S)>
- , stub<
- decltype(
- boost::declval<G>()(
- BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval<S, >() BOOST_PP_INTERCEPT)
- )
- )
- >* x = 0);
- static fail test(...);
-
-public:
- const static bool value = sizeof(pass) == sizeof(test(sub<F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
- BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)
- >()));
- typedef typename boost::mpl::bool_<value>::type type;
+template<typename F>
+struct BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION());
+
+template<typename R BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename T)>
+struct BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<R(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T))> {
+ 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<typename F>
+struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION());
+
+template<typename F>
+struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<F *>
+ : BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<F>
+{};
+
+template<typename F>
+struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<F &>
+ : BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<F>
+{};
+
+template<typename F>
+struct BOOST_PP_CAT(result_of_select_call_wrapper_type_, BOOST_PP_ITERATION())
+ : mpl::eval_if<
+ is_class<typename remove_reference<F>::type>,
+ result_of_wrap_callable_class<F>,
+ mpl::identity<BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<typename remove_cv<F>::type> >
+ >
+{};
+
+template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename T)>
+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())<F>::type wrapper_t;
+ static const bool value = (
+ sizeof(result_of_no_type) == sizeof(detail::result_of_is_private_type(
+ (boost::declval<wrapper_t>()(BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval<T, >() BOOST_PP_INTERCEPT)), result_of_weird_type())
+ ))
+ );
+ typedef mpl::bool_<value> type;
 };
 
-template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
- BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
+template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
 struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), true>
     : lazy_enable_if<
- is_callable<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
+ BOOST_PP_CAT(result_of_is_callable_, BOOST_PP_ITERATION())<F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), T)>
         , cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false>
>
 {};
 
-template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
- BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
+template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
 struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false>
 {
   typedef decltype(
@@ -112,11 +119,10 @@
   ) type;
 };
 
-#else // BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1700))
+#else // BOOST_NO_SFINAE_EXPR
 
-template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
- BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
-struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)),
+template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
+struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)),
                             typename result_of_always_void<decltype(
                                 boost::declval<F>()(
                                     BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval<T, >() BOOST_PP_INTERCEPT)
@@ -129,15 +135,14 @@
   ) type;
 };
 
-#endif // BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1700))
+#endif // BOOST_NO_SFINAE_EXPR
 
-} // namespace detail
+} // namespace detail
 
 #else // defined(BOOST_RESULT_OF_USE_DECLTYPE)
 
 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
-template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
- BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
+template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
 struct result_of<F(BOOST_RESULT_OF_ARGS)>
     : tr1_result_of<F(BOOST_RESULT_OF_ARGS)> { };
 #endif
@@ -146,27 +151,24 @@
 
 #undef BOOST_RESULT_OF_ARGS
 
-#if BOOST_PP_ITERATION() >= 1
+#if BOOST_PP_ITERATION() >= 1
 
 namespace detail {
 
-template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
- BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
+template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
 struct tr1_result_of_impl<R (*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false>
 {
   typedef R type;
 };
 
-template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
- BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
+template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
 struct tr1_result_of_impl<R (&)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false>
 {
   typedef R type;
 };
 
 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
-template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
- BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
+template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
 struct tr1_result_of_impl<R (T0::*)
                      (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)),
                  FArgs, false>
@@ -174,8 +176,7 @@
   typedef R type;
 };
 
-template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
- BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
+template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
 struct tr1_result_of_impl<R (T0::*)
                      (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
                      const,
@@ -184,8 +185,7 @@
   typedef R type;
 };
 
-template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
- BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
+template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
 struct tr1_result_of_impl<R (T0::*)
                      (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
                      volatile,
@@ -194,8 +194,7 @@
   typedef R type;
 };
 
-template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
- BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
+template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
 struct tr1_result_of_impl<R (T0::*)
                      (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
                      const volatile,

Modified: branches/release/boost/utility/result_of.hpp
==============================================================================
--- branches/release/boost/utility/result_of.hpp (original)
+++ branches/release/boost/utility/result_of.hpp 2012-09-26 14:52:08 EDT (Wed, 26 Sep 2012)
@@ -10,20 +10,25 @@
 #define BOOST_RESULT_OF_HPP
 
 #include <boost/config.hpp>
-#include <boost/preprocessor/iteration/iterate.hpp>
-#include <boost/preprocessor/punctuation/comma_if.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
-#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
-#include <boost/preprocessor/facilities/intercept.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
+#include <boost/preprocessor/facilities/intercept.hpp>
 #include <boost/detail/workaround.hpp>
 #include <boost/mpl/has_xxx.hpp>
 #include <boost/mpl/if.hpp>
+#include <boost/mpl/eval_if.hpp>
 #include <boost/mpl/bool.hpp>
+#include <boost/mpl/identity.hpp>
 #include <boost/mpl/or.hpp>
+#include <boost/type_traits/is_class.hpp>
 #include <boost/type_traits/is_pointer.hpp>
 #include <boost/type_traits/is_member_function_pointer.hpp>
 #include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
 #include <boost/utility/declval.hpp>
 #include <boost/utility/enable_if.hpp>
 
@@ -61,21 +66,67 @@
 
 template<typename F, typename FArgs, bool HasResultType> struct tr1_result_of_impl;
 
-#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1700))
+#ifdef BOOST_NO_SFINAE_EXPR
+
+struct result_of_private_type {};
+
+struct result_of_weird_type {
+ template<typename T>
+ friend result_of_weird_type operator,(T const &, result_of_weird_type);
+ friend result_of_private_type operator,(result_of_private_type, result_of_weird_type);
+};
+
+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
+
+result_of_no_type result_of_is_private_type(result_of_weird_type);
+result_of_yes_type result_of_is_private_type(result_of_private_type);
+
+template<typename C>
+struct result_of_callable_class : C {
+ result_of_callable_class();
+ typedef result_of_private_type const &(*pfn_t)(...);
+ operator pfn_t() const volatile;
+};
+
+template<typename C>
+struct result_of_wrap_callable_class {
+ typedef result_of_callable_class<C> type;
+};
+
+template<typename C>
+struct result_of_wrap_callable_class<C const> {
+ typedef result_of_callable_class<C> const type;
+};
+
+template<typename C>
+struct result_of_wrap_callable_class<C volatile> {
+ typedef result_of_callable_class<C> volatile type;
+};
+
+template<typename C>
+struct result_of_wrap_callable_class<C const volatile> {
+ typedef result_of_callable_class<C> const volatile type;
+};
+
+template<typename C>
+struct result_of_wrap_callable_class<C &> {
+ typedef typename result_of_wrap_callable_class<C>::type &type;
+};
 
-template<typename F> class is_callable;
 template<typename F, bool TestCallability = true> struct cpp0x_result_of_impl;
 
-#else // BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1700))
+#else // BOOST_NO_SFINAE_EXPR
 
 template<typename T>
 struct result_of_always_void
 {
- typedef void type;
+ typedef void type;
 };
+
 template<typename F, typename Enable = void> struct cpp0x_result_of_impl {};
 
-#endif // BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1700))
+#endif // BOOST_NO_SFINAE_EXPR
 
 template<typename F>
 struct result_of_void_impl

Modified: branches/release/libs/utility/test/result_of_test.cpp
==============================================================================
--- branches/release/libs/utility/test/result_of_test.cpp (original)
+++ branches/release/libs/utility/test/result_of_test.cpp 2012-09-26 14:52:08 EDT (Wed, 26 Sep 2012)
@@ -160,6 +160,10 @@
   typedef int (&func_ref)(float, double);
   typedef int (*func_ptr_0)();
   typedef int (&func_ref_0)();
+ typedef void (*func_ptr_void)(float, double);
+ typedef void (&func_ref_void)(float, double);
+ typedef void (*func_ptr_void_0)();
+ typedef void (&func_ref_void_0)();
   typedef int (X::*mem_func_ptr)(float);
   typedef int (X::*mem_func_ptr_c)(float) const;
   typedef int (X::*mem_func_ptr_v)(float) volatile;
@@ -218,6 +222,10 @@
   BOOST_STATIC_ASSERT((is_same<result_of<func_ref(char, float)>::type, int>::value));
   BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_0()>::type, int>::value));
   BOOST_STATIC_ASSERT((is_same<result_of<func_ref_0()>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_void(char, float)>::type, void>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<func_ref_void(char, float)>::type, void>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_void_0()>::type, void>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<func_ref_void_0()>::type, void>::value));
   BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr(X,char)>::type, int>::value));
   BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_c(X,char)>::type, int>::value));
   BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_v(X,char)>::type, int>::value));
@@ -228,6 +236,10 @@
   BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref(char, float)>::type, int>::value));
   BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr_0()>::type, int>::value));
   BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref_0()>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr_void(char, float)>::type, void>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref_void(char, float)>::type, void>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr_void_0()>::type, void>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref_void_0()>::type, void>::value));
   BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr(X,char)>::type, int>::value));
   BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_c(X,char)>::type, int>::value));
   BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_v(X,char)>::type, int>::value));


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk