summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/at_exit_unittest.cc2
-rw-r--r--base/bind.h442
-rw-r--r--base/bind.h.pump115
-rw-r--r--base/bind_helpers.h123
-rw-r--r--base/bind_internal.h3585
-rw-r--r--base/bind_internal.h.pump631
-rw-r--r--base/bind_internal_win.h388
-rw-r--r--base/bind_internal_win.h.pump56
-rw-r--r--base/bind_unittest.cc94
-rw-r--r--base/bind_unittest.nc11
-rw-r--r--base/callback.h280
-rw-r--r--base/callback.h.pump46
-rw-r--r--base/callback_internal.cc12
-rw-r--r--base/callback_internal.h38
-rw-r--r--base/callback_unittest.cc18
-rw-r--r--base/file_util_proxy.cc3
-rw-r--r--base/task_unittest.cc4
-rw-r--r--base/template_util.h2
-rw-r--r--base/template_util_unittest.cc6
-rw-r--r--build/nocompile.gypi1
-rw-r--r--chrome/browser/chrome_browser_main_x11.cc2
-rw-r--r--chrome/browser/extensions/extension_service.cc2
-rw-r--r--chrome/browser/extensions/extension_updater.cc4
-rw-r--r--chrome/browser/net/net_pref_observer.cc2
-rw-r--r--chrome/browser/net/predictor.cc2
-rw-r--r--chrome/browser/password_manager/password_store_x.cc2
-rw-r--r--chrome/common/profiling.cc4
-rw-r--r--content/browser/cancelable_request.h90
-rw-r--r--content/browser/debugger/worker_devtools_manager.cc11
-rw-r--r--content/browser/plugin_service_browsertest.cc4
-rw-r--r--content/renderer/render_widget_fullscreen_pepper.cc2
-rw-r--r--media/tools/player_x11/player_x11.cc4
-rw-r--r--remoting/protocol/jingle_session_unittest.cc2
33 files changed, 3286 insertions, 2702 deletions
diff --git a/base/at_exit_unittest.cc b/base/at_exit_unittest.cc
index 89fc9d0..cda7340 100644
--- a/base/at_exit_unittest.cc
+++ b/base/at_exit_unittest.cc
@@ -81,7 +81,7 @@ TEST_F(AtExitTest, Param) {
TEST_F(AtExitTest, Task) {
ZeroTestCounters();
- base::AtExitManager::RegisterTask(base::Bind(ExpectParamIsCounter,
+ base::AtExitManager::RegisterTask(base::Bind(&ExpectParamIsCounter,
&g_test_counter_1));
base::AtExitManager::ProcessCallbacksNow();
}
diff --git a/base/bind.h b/base/bind.h
index f023308e..1637207 100644
--- a/base/bind.h
+++ b/base/bind.h
@@ -15,7 +15,10 @@
#include "base/bind_internal.h"
#include "base/callback_internal.h"
-// See base/callback.h for how to use these functions.
+// See base/callback.h for how to use these functions. If reading the
+// implementation, before proceeding further, you should read the top
+// comment of base/bind_internal.h for a definition of common terms and
+// concepts.
//
// IMPLEMENTATION NOTE
// Though Bind()'s result is meant to be stored in a Callback<> type, it
@@ -28,116 +31,383 @@
// Each unique combination of (arity, function_type, num_prebound) where
// function_type is one of {function, method, const_method} would require
// one specialization. We eventually have to do a similar number of
-// specializations anyways in the implementation (see the FunctionTraitsN,
+// specializations anyways in the implementation (see the Invoker<>,
// classes). However, it is avoidable in Bind if we return the result
// via an indirection like we do below.
+//
+// TODO(ajwong): We might be able to avoid this now, but need to test.
+//
+// It is possible to move most of the COMPILE_ASSERT asserts into BindState<>,
+// but it feels a little nicer to have the asserts here so people do not
+// need to crack open bind_internal.h. On the other hand, it makes Bind()
+// harder to read.
namespace base {
-template <typename Sig>
-internal::InvokerStorageHolder<internal::InvokerStorage0<Sig> >
-Bind(Sig f) {
- return internal::MakeInvokerStorageHolder(
- new internal::InvokerStorage0<Sig>(f));
-}
+template <typename Functor>
+internal::BindStateHolder<
+ internal::BindState<
+ typename internal::FunctorTraits<Functor>::RunnableType,
+ typename internal::FunctorTraits<Functor>::RunType,
+ void()> >
+Bind(Functor functor) {
+ // Typedefs for how to store and run the functor.
+ typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
+ typedef typename internal::FunctorTraits<Functor>::RunType RunType;
-template <typename Sig, typename P1>
-internal::InvokerStorageHolder<internal::InvokerStorage1<Sig,P1> >
-Bind(Sig f, const P1& p1) {
- return internal::MakeInvokerStorageHolder(
- new internal::InvokerStorage1<Sig, P1>(
- f, p1));
-}
+ // Use RunnableType::RunType instead of RunType above because our
+ // checks should below for bound references need to know what the actual
+ // functor is going to interpret the argument as.
+ typedef internal::FunctionTraits<typename RunnableType::RunType>
+ BoundFunctorTraits;
-template <typename Sig, typename P1, typename P2>
-internal::InvokerStorageHolder<internal::InvokerStorage2<Sig,P1, P2> >
-Bind(Sig f, const P1& p1, const P2& p2) {
- return internal::MakeInvokerStorageHolder(
- new internal::InvokerStorage2<Sig, P1, P2>(
- f, p1, p2));
-}
-template <typename Sig, typename P1, typename P2, typename P3>
-internal::InvokerStorageHolder<internal::InvokerStorage3<Sig,P1, P2, P3> >
-Bind(Sig f, const P1& p1, const P2& p2, const P3& p3) {
- return internal::MakeInvokerStorageHolder(
- new internal::InvokerStorage3<Sig, P1, P2, P3>(
- f, p1, p2, p3));
+ return internal::MakeBindStateHolder(
+ new internal::BindState<RunnableType, RunType, void()>(
+ internal::MakeRunnable(functor)));
}
-template <typename Sig, typename P1, typename P2, typename P3, typename P4>
-internal::InvokerStorageHolder<internal::InvokerStorage4<Sig,P1, P2, P3, P4> >
-Bind(Sig f, const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
- return internal::MakeInvokerStorageHolder(
- new internal::InvokerStorage4<Sig, P1, P2, P3, P4>(
- f, p1, p2, p3, p4));
-}
+template <typename Functor, typename P1>
+internal::BindStateHolder<
+ internal::BindState<
+ typename internal::FunctorTraits<Functor>::RunnableType,
+ typename internal::FunctorTraits<Functor>::RunType,
+ void(typename internal::CallbackParamTraits<P1>::StorageType)> >
+Bind(Functor functor, const P1& p1) {
+ // Typedefs for how to store and run the functor.
+ typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
+ typedef typename internal::FunctorTraits<Functor>::RunType RunType;
-template <typename Sig, typename P1, typename P2, typename P3, typename P4,
- typename P5>
-internal::InvokerStorageHolder<internal::InvokerStorage5<Sig,P1, P2, P3, P4,
- P5> >
-Bind(Sig f, const P1& p1, const P2& p2, const P3& p3, const P4& p4,
- const P5& p5) {
- return internal::MakeInvokerStorageHolder(
- new internal::InvokerStorage5<Sig, P1, P2, P3, P4, P5>(
- f, p1, p2, p3, p4, p5));
-}
+ // Use RunnableType::RunType instead of RunType above because our
+ // checks should below for bound references need to know what the actual
+ // functor is going to interpret the argument as.
+ typedef internal::FunctionTraits<typename RunnableType::RunType>
+ BoundFunctorTraits;
-template <typename Sig, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6>
-internal::InvokerStorageHolder<internal::InvokerStorage6<Sig,P1, P2, P3, P4,
- P5, P6> >
-Bind(Sig f, const P1& p1, const P2& p2, const P3& p3, const P4& p4,
- const P5& p5, const P6& p6) {
- return internal::MakeInvokerStorageHolder(
- new internal::InvokerStorage6<Sig, P1, P2, P3, P4, P5, P6>(
- f, p1, p2, p3, p4, p5, p6));
-}
+ // Do not allow binding a non-const reference parameter. Non-const reference
+ // parameters are disallowed by the Google style guide. Also, binding a
+ // non-const reference parameter can make for subtle bugs because the
+ // invoked function will receive a reference to the stored copy of the
+ // argument and not the original.
+ COMPILE_ASSERT(
+ !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ),
+ do_not_bind_functions_with_nonconst_ref);
-// Specializations to allow binding all the free arguments in a
-// pre-existing base::Callback<>. This does not give full support for
-// currying, but is significantly simpler and addresses the use case
-// where a base::Callback<> needs to be invoked on another context/thread.
-template <typename Sig, typename P1>
-base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1) {
- return base::Bind(&internal::BindMoreFunc1<Sig, P1>, callback, p1);
+ // For methods, we need to be careful for parameter 1. We do not require
+ // a scoped_refptr because BindState<> itself takes care of AddRef() for
+ // methods. We also disallow binding of an array as the method's target
+ // object.
+ COMPILE_ASSERT(
+ internal::HasIsMethodTag<RunnableType>::value ||
+ !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
+ p1_is_refcounted_type_and_needs_scoped_refptr);
+ COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
+ !is_array<P1>::value,
+ first_bound_argument_to_method_cannot_be_array);
+
+ return internal::MakeBindStateHolder(
+ new internal::BindState<RunnableType, RunType,
+ void(typename internal::CallbackParamTraits<P1>::StorageType)>(
+ internal::MakeRunnable(functor), p1));
}
-template <typename Sig, typename P1, typename P2>
-base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1,
- const P2& p2) {
- return base::Bind(&internal::BindMoreFunc2<Sig, P1, P2>, callback, p1, p2);
+template <typename Functor, typename P1, typename P2>
+internal::BindStateHolder<
+ internal::BindState<
+ typename internal::FunctorTraits<Functor>::RunnableType,
+ typename internal::FunctorTraits<Functor>::RunType,
+ void(typename internal::CallbackParamTraits<P1>::StorageType,
+ typename internal::CallbackParamTraits<P2>::StorageType)> >
+Bind(Functor functor, const P1& p1, const P2& p2) {
+ // Typedefs for how to store and run the functor.
+ typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
+ typedef typename internal::FunctorTraits<Functor>::RunType RunType;
+
+ // Use RunnableType::RunType instead of RunType above because our
+ // checks should below for bound references need to know what the actual
+ // functor is going to interpret the argument as.
+ typedef internal::FunctionTraits<typename RunnableType::RunType>
+ BoundFunctorTraits;
+
+ // Do not allow binding a non-const reference parameter. Non-const reference
+ // parameters are disallowed by the Google style guide. Also, binding a
+ // non-const reference parameter can make for subtle bugs because the
+ // invoked function will receive a reference to the stored copy of the
+ // argument and not the original.
+ COMPILE_ASSERT(
+ !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
+ is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ),
+ do_not_bind_functions_with_nonconst_ref);
+
+ // For methods, we need to be careful for parameter 1. We do not require
+ // a scoped_refptr because BindState<> itself takes care of AddRef() for
+ // methods. We also disallow binding of an array as the method's target
+ // object.
+ COMPILE_ASSERT(
+ internal::HasIsMethodTag<RunnableType>::value ||
+ !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
+ p1_is_refcounted_type_and_needs_scoped_refptr);
+ COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
+ !is_array<P1>::value,
+ first_bound_argument_to_method_cannot_be_array);
+ COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
+ p2_is_refcounted_type_and_needs_scoped_refptr);
+
+ return internal::MakeBindStateHolder(
+ new internal::BindState<RunnableType, RunType,
+ void(typename internal::CallbackParamTraits<P1>::StorageType,
+ typename internal::CallbackParamTraits<P2>::StorageType)>(
+ internal::MakeRunnable(functor), p1, p2));
}
-template <typename Sig, typename P1, typename P2, typename P3>
-base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1,
- const P2& p2, const P3& p3) {
- return base::Bind(&internal::BindMoreFunc3<Sig, P1, P2, P3>, callback, p1,
- p2, p3);
+template <typename Functor, typename P1, typename P2, typename P3>
+internal::BindStateHolder<
+ internal::BindState<
+ typename internal::FunctorTraits<Functor>::RunnableType,
+ typename internal::FunctorTraits<Functor>::RunType,
+ void(typename internal::CallbackParamTraits<P1>::StorageType,
+ typename internal::CallbackParamTraits<P2>::StorageType,
+ typename internal::CallbackParamTraits<P3>::StorageType)> >
+Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3) {
+ // Typedefs for how to store and run the functor.
+ typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
+ typedef typename internal::FunctorTraits<Functor>::RunType RunType;
+
+ // Use RunnableType::RunType instead of RunType above because our
+ // checks should below for bound references need to know what the actual
+ // functor is going to interpret the argument as.
+ typedef internal::FunctionTraits<typename RunnableType::RunType>
+ BoundFunctorTraits;
+
+ // Do not allow binding a non-const reference parameter. Non-const reference
+ // parameters are disallowed by the Google style guide. Also, binding a
+ // non-const reference parameter can make for subtle bugs because the
+ // invoked function will receive a reference to the stored copy of the
+ // argument and not the original.
+ COMPILE_ASSERT(
+ !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
+ is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
+ is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ),
+ do_not_bind_functions_with_nonconst_ref);
+
+ // For methods, we need to be careful for parameter 1. We do not require
+ // a scoped_refptr because BindState<> itself takes care of AddRef() for
+ // methods. We also disallow binding of an array as the method's target
+ // object.
+ COMPILE_ASSERT(
+ internal::HasIsMethodTag<RunnableType>::value ||
+ !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
+ p1_is_refcounted_type_and_needs_scoped_refptr);
+ COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
+ !is_array<P1>::value,
+ first_bound_argument_to_method_cannot_be_array);
+ COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
+ p2_is_refcounted_type_and_needs_scoped_refptr);
+ COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
+ p3_is_refcounted_type_and_needs_scoped_refptr);
+
+ return internal::MakeBindStateHolder(
+ new internal::BindState<RunnableType, RunType,
+ void(typename internal::CallbackParamTraits<P1>::StorageType,
+ typename internal::CallbackParamTraits<P2>::StorageType,
+ typename internal::CallbackParamTraits<P3>::StorageType)>(
+ internal::MakeRunnable(functor), p1, p2, p3));
}
-template <typename Sig, typename P1, typename P2, typename P3, typename P4>
-base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1,
- const P2& p2, const P3& p3, const P4& p4) {
- return base::Bind(&internal::BindMoreFunc4<Sig, P1, P2, P3, P4>, callback,
- p1, p2, p3, p4);
+template <typename Functor, typename P1, typename P2, typename P3, typename P4>
+internal::BindStateHolder<
+ internal::BindState<
+ typename internal::FunctorTraits<Functor>::RunnableType,
+ typename internal::FunctorTraits<Functor>::RunType,
+ void(typename internal::CallbackParamTraits<P1>::StorageType,
+ typename internal::CallbackParamTraits<P2>::StorageType,
+ typename internal::CallbackParamTraits<P3>::StorageType,
+ typename internal::CallbackParamTraits<P4>::StorageType)> >
+Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
+ // Typedefs for how to store and run the functor.
+ typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
+ typedef typename internal::FunctorTraits<Functor>::RunType RunType;
+
+ // Use RunnableType::RunType instead of RunType above because our
+ // checks should below for bound references need to know what the actual
+ // functor is going to interpret the argument as.
+ typedef internal::FunctionTraits<typename RunnableType::RunType>
+ BoundFunctorTraits;
+
+ // Do not allow binding a non-const reference parameter. Non-const reference
+ // parameters are disallowed by the Google style guide. Also, binding a
+ // non-const reference parameter can make for subtle bugs because the
+ // invoked function will receive a reference to the stored copy of the
+ // argument and not the original.
+ COMPILE_ASSERT(
+ !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
+ is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
+ is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ||
+ is_non_const_reference<typename BoundFunctorTraits::A4Type>::value ),
+ do_not_bind_functions_with_nonconst_ref);
+
+ // For methods, we need to be careful for parameter 1. We do not require
+ // a scoped_refptr because BindState<> itself takes care of AddRef() for
+ // methods. We also disallow binding of an array as the method's target
+ // object.
+ COMPILE_ASSERT(
+ internal::HasIsMethodTag<RunnableType>::value ||
+ !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
+ p1_is_refcounted_type_and_needs_scoped_refptr);
+ COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
+ !is_array<P1>::value,
+ first_bound_argument_to_method_cannot_be_array);
+ COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
+ p2_is_refcounted_type_and_needs_scoped_refptr);
+ COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
+ p3_is_refcounted_type_and_needs_scoped_refptr);
+ COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P4>::value,
+ p4_is_refcounted_type_and_needs_scoped_refptr);
+
+ return internal::MakeBindStateHolder(
+ new internal::BindState<RunnableType, RunType,
+ void(typename internal::CallbackParamTraits<P1>::StorageType,
+ typename internal::CallbackParamTraits<P2>::StorageType,
+ typename internal::CallbackParamTraits<P3>::StorageType,
+ typename internal::CallbackParamTraits<P4>::StorageType)>(
+ internal::MakeRunnable(functor), p1, p2, p3, p4));
}
-template <typename Sig, typename P1, typename P2, typename P3, typename P4,
+template <typename Functor, typename P1, typename P2, typename P3, typename P4,
typename P5>
-base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1,
- const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
- return base::Bind(&internal::BindMoreFunc5<Sig, P1, P2, P3, P4, P5>,
- callback, p1, p2, p3, p4, p5);
+internal::BindStateHolder<
+ internal::BindState<
+ typename internal::FunctorTraits<Functor>::RunnableType,
+ typename internal::FunctorTraits<Functor>::RunType,
+ void(typename internal::CallbackParamTraits<P1>::StorageType,
+ typename internal::CallbackParamTraits<P2>::StorageType,
+ typename internal::CallbackParamTraits<P3>::StorageType,
+ typename internal::CallbackParamTraits<P4>::StorageType,
+ typename internal::CallbackParamTraits<P5>::StorageType)> >
+Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4,
+ const P5& p5) {
+ // Typedefs for how to store and run the functor.
+ typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
+ typedef typename internal::FunctorTraits<Functor>::RunType RunType;
+
+ // Use RunnableType::RunType instead of RunType above because our
+ // checks should below for bound references need to know what the actual
+ // functor is going to interpret the argument as.
+ typedef internal::FunctionTraits<typename RunnableType::RunType>
+ BoundFunctorTraits;
+
+ // Do not allow binding a non-const reference parameter. Non-const reference
+ // parameters are disallowed by the Google style guide. Also, binding a
+ // non-const reference parameter can make for subtle bugs because the
+ // invoked function will receive a reference to the stored copy of the
+ // argument and not the original.
+ COMPILE_ASSERT(
+ !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
+ is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
+ is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ||
+ is_non_const_reference<typename BoundFunctorTraits::A4Type>::value ||
+ is_non_const_reference<typename BoundFunctorTraits::A5Type>::value ),
+ do_not_bind_functions_with_nonconst_ref);
+
+ // For methods, we need to be careful for parameter 1. We do not require
+ // a scoped_refptr because BindState<> itself takes care of AddRef() for
+ // methods. We also disallow binding of an array as the method's target
+ // object.
+ COMPILE_ASSERT(
+ internal::HasIsMethodTag<RunnableType>::value ||
+ !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
+ p1_is_refcounted_type_and_needs_scoped_refptr);
+ COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
+ !is_array<P1>::value,
+ first_bound_argument_to_method_cannot_be_array);
+ COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
+ p2_is_refcounted_type_and_needs_scoped_refptr);
+ COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
+ p3_is_refcounted_type_and_needs_scoped_refptr);
+ COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P4>::value,
+ p4_is_refcounted_type_and_needs_scoped_refptr);
+ COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P5>::value,
+ p5_is_refcounted_type_and_needs_scoped_refptr);
+
+ return internal::MakeBindStateHolder(
+ new internal::BindState<RunnableType, RunType,
+ void(typename internal::CallbackParamTraits<P1>::StorageType,
+ typename internal::CallbackParamTraits<P2>::StorageType,
+ typename internal::CallbackParamTraits<P3>::StorageType,
+ typename internal::CallbackParamTraits<P4>::StorageType,
+ typename internal::CallbackParamTraits<P5>::StorageType)>(
+ internal::MakeRunnable(functor), p1, p2, p3, p4, p5));
}
-template <typename Sig, typename P1, typename P2, typename P3, typename P4,
+template <typename Functor, typename P1, typename P2, typename P3, typename P4,
typename P5, typename P6>
-base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1,
- const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6) {
- return base::Bind(&internal::BindMoreFunc6<Sig, P1, P2, P3, P4, P5, P6>,
- callback, p1, p2, p3, p4, p5, p6);
+internal::BindStateHolder<
+ internal::BindState<
+ typename internal::FunctorTraits<Functor>::RunnableType,
+ typename internal::FunctorTraits<Functor>::RunType,
+ void(typename internal::CallbackParamTraits<P1>::StorageType,
+ typename internal::CallbackParamTraits<P2>::StorageType,
+ typename internal::CallbackParamTraits<P3>::StorageType,
+ typename internal::CallbackParamTraits<P4>::StorageType,
+ typename internal::CallbackParamTraits<P5>::StorageType,
+ typename internal::CallbackParamTraits<P6>::StorageType)> >
+Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4,
+ const P5& p5, const P6& p6) {
+ // Typedefs for how to store and run the functor.
+ typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
+ typedef typename internal::FunctorTraits<Functor>::RunType RunType;
+
+ // Use RunnableType::RunType instead of RunType above because our
+ // checks should below for bound references need to know what the actual
+ // functor is going to interpret the argument as.
+ typedef internal::FunctionTraits<typename RunnableType::RunType>
+ BoundFunctorTraits;
+
+ // Do not allow binding a non-const reference parameter. Non-const reference
+ // parameters are disallowed by the Google style guide. Also, binding a
+ // non-const reference parameter can make for subtle bugs because the
+ // invoked function will receive a reference to the stored copy of the
+ // argument and not the original.
+ COMPILE_ASSERT(
+ !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
+ is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
+ is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ||
+ is_non_const_reference<typename BoundFunctorTraits::A4Type>::value ||
+ is_non_const_reference<typename BoundFunctorTraits::A5Type>::value ||
+ is_non_const_reference<typename BoundFunctorTraits::A6Type>::value ),
+ do_not_bind_functions_with_nonconst_ref);
+
+ // For methods, we need to be careful for parameter 1. We do not require
+ // a scoped_refptr because BindState<> itself takes care of AddRef() for
+ // methods. We also disallow binding of an array as the method's target
+ // object.
+ COMPILE_ASSERT(
+ internal::HasIsMethodTag<RunnableType>::value ||
+ !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
+ p1_is_refcounted_type_and_needs_scoped_refptr);
+ COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
+ !is_array<P1>::value,
+ first_bound_argument_to_method_cannot_be_array);
+ COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
+ p2_is_refcounted_type_and_needs_scoped_refptr);
+ COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
+ p3_is_refcounted_type_and_needs_scoped_refptr);
+ COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P4>::value,
+ p4_is_refcounted_type_and_needs_scoped_refptr);
+ COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P5>::value,
+ p5_is_refcounted_type_and_needs_scoped_refptr);
+ COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P6>::value,
+ p6_is_refcounted_type_and_needs_scoped_refptr);
+
+ return internal::MakeBindStateHolder(
+ new internal::BindState<RunnableType, RunType,
+ void(typename internal::CallbackParamTraits<P1>::StorageType,
+ typename internal::CallbackParamTraits<P2>::StorageType,
+ typename internal::CallbackParamTraits<P3>::StorageType,
+ typename internal::CallbackParamTraits<P4>::StorageType,
+ typename internal::CallbackParamTraits<P5>::StorageType,
+ typename internal::CallbackParamTraits<P6>::StorageType)>(
+ internal::MakeRunnable(functor), p1, p2, p3, p4, p5, p6));
}
} // namespace base
diff --git a/base/bind.h.pump b/base/bind.h.pump
index eca00cd..11b4667 100644
--- a/base/bind.h.pump
+++ b/base/bind.h.pump
@@ -18,7 +18,10 @@ $var MAX_ARITY = 6
#include "base/bind_internal.h"
#include "base/callback_internal.h"
-// See base/callback.h for how to use these functions.
+// See base/callback.h for how to use these functions. If reading the
+// implementation, before proceeding further, you should read the top
+// comment of base/bind_internal.h for a definition of common terms and
+// concepts.
//
// IMPLEMENTATION NOTE
// Though Bind()'s result is meant to be stored in a Callback<> type, it
@@ -31,60 +34,88 @@ $var MAX_ARITY = 6
// Each unique combination of (arity, function_type, num_prebound) where
// function_type is one of {function, method, const_method} would require
// one specialization. We eventually have to do a similar number of
-// specializations anyways in the implementation (see the FunctionTraitsN,
+// specializations anyways in the implementation (see the Invoker<>,
// classes). However, it is avoidable in Bind if we return the result
// via an indirection like we do below.
+//
+// TODO(ajwong): We might be able to avoid this now, but need to test.
+//
+// It is possible to move most of the COMPILE_ASSERT asserts into BindState<>,
+// but it feels a little nicer to have the asserts here so people do not
+// need to crack open bind_internal.h. On the other hand, it makes Bind()
+// harder to read.
namespace base {
-$range BOUND 0..MAX_ARITY
-$for BOUND [[
-$range BOUND_ARG 1..BOUND
+$range ARITY 0..MAX_ARITY
+$for ARITY [[
+$range ARG 1..ARITY
+
+template <typename Functor[[]]
+$if ARITY > 0 [[, ]] $for ARG , [[typename P$(ARG)]]>
+internal::BindStateHolder<
+ internal::BindState<
+ typename internal::FunctorTraits<Functor>::RunnableType,
+ typename internal::FunctorTraits<Functor>::RunType,
+ void($for ARG , [[typename internal::CallbackParamTraits<P$(ARG)>::StorageType]])> >
+Bind(Functor functor
+$if ARITY > 0 [[, ]] $for ARG , [[const P$(ARG)& p$(ARG)]]) {
+ // Typedefs for how to store and run the functor.
+ typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
+ typedef typename internal::FunctorTraits<Functor>::RunType RunType;
+
+ // Use RunnableType::RunType instead of RunType above because our
+ // checks should below for bound references need to know what the actual
+ // functor is going to interpret the argument as.
+ typedef internal::FunctionTraits<typename RunnableType::RunType>
+ BoundFunctorTraits;
+
+$if ARITY > 0 [[
+
+ // Do not allow binding a non-const reference parameter. Non-const reference
+ // parameters are disallowed by the Google style guide. Also, binding a
+ // non-const reference parameter can make for subtle bugs because the
+ // invoked function will receive a reference to the stored copy of the
+ // argument and not the original.
+ COMPILE_ASSERT(
+ !($for ARG || [[
+is_non_const_reference<typename BoundFunctorTraits::A$(ARG)Type>::value ]]),
+ do_not_bind_functions_with_nonconst_ref);
+
+]]
-$if BOUND == 0 [[
-template <typename Sig>
-internal::InvokerStorageHolder<internal::InvokerStorage0<Sig> >
-Bind(Sig f) {
- return internal::MakeInvokerStorageHolder(
- new internal::InvokerStorage0<Sig>(f));
-}
+$for ARG [[
+
+$if ARG == 1 [[
+ // For methods, we need to be careful for parameter 1. We do not require
+ // a scoped_refptr because BindState<> itself takes care of AddRef() for
+ // methods. We also disallow binding of an array as the method's target
+ // object.
+ COMPILE_ASSERT(
+ internal::HasIsMethodTag<RunnableType>::value ||
+ !internal::NeedsScopedRefptrButGetsRawPtr<P$(ARG)>::value,
+ p$(ARG)_is_refcounted_type_and_needs_scoped_refptr);
+ COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
+ !is_array<P$(ARG)>::value,
+ first_bound_argument_to_method_cannot_be_array);
]] $else [[
+ COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P$(ARG)>::value,
+ p$(ARG)_is_refcounted_type_and_needs_scoped_refptr);
+]] $$ $if ARG
-template <typename Sig, $for BOUND_ARG , [[typename P$(BOUND_ARG)]]>
-internal::InvokerStorageHolder<internal::InvokerStorage$(BOUND)<Sig,
-$for BOUND_ARG , [[P$(BOUND_ARG)]]> >
-Bind(Sig f, $for BOUND_ARG , [[const P$(BOUND_ARG)& p$(BOUND_ARG)]]) {
- return internal::MakeInvokerStorageHolder(
- new internal::InvokerStorage$(BOUND)<Sig, [[]]
-$for BOUND_ARG , [[P$(BOUND_ARG)]]>(
- f, $for BOUND_ARG , [[p$(BOUND_ARG)]]));
-}
+]] $$ $for ARG
-]]
-]] $$ for BOUND
-
-// Specializations to allow binding all the free arguments in a
-// pre-existing base::Callback<>. This does not give full support for
-// currying, but is significantly simpler and addresses the use case
-// where a base::Callback<> needs to be invoked on another context/thread.
-$for BOUND [[
-$range BOUND_ARG 1..BOUND
-$if BOUND != 0 [[
-
-template <typename Sig, $for BOUND_ARG , [[typename P$(BOUND_ARG)]]>
-base::Closure Bind(const base::Callback<Sig>& callback, [[]]
-$for BOUND_ARG , [[const P$(BOUND_ARG)& p$(BOUND_ARG)]]) {
- return base::Bind([[]]
-&internal::BindMoreFunc$(BOUND)<Sig, $for BOUND_ARG , [[P$(BOUND_ARG)]]>, [[]]
-callback, [[]]
-$for BOUND_ARG , [[p$(BOUND_ARG)]]);
-}
-]]
+ return internal::MakeBindStateHolder(
+ new internal::BindState<RunnableType, RunType, [[]]
+void($for ARG , [[typename internal::CallbackParamTraits<P$(ARG)>::StorageType]])>(
+ internal::MakeRunnable(functor)[[]]
+$if ARITY > 0 [[, ]] $for ARG , [[p$(ARG)]]));
+}
-]] $$ for BOUND
+]] $$ for ARITY
} // namespace base
diff --git a/base/bind_helpers.h b/base/bind_helpers.h
index d7ddb2c..6e0f8fe 100644
--- a/base/bind_helpers.h
+++ b/base/bind_helpers.h
@@ -198,7 +198,6 @@ class SupportsAddRefAndRelease {
static const bool value = sizeof(Check<Base>(0)) == sizeof(Yes);
};
-
// Helpers to assert that arguments of a recounted type are bound with a
// scoped_refptr.
template <bool IsClasstype, typename T>
@@ -219,6 +218,20 @@ struct UnsafeBindtoRefCountedArg<T*>
: UnsafeBindtoRefCountedArgHelper<is_class<T>::value, T> {
};
+template <typename T>
+class HasIsMethodTag {
+ typedef char Yes[1];
+ typedef char No[2];
+
+ template <typename U>
+ static Yes& Check(typename U::IsMethod*);
+
+ template <typename U>
+ static No& Check(...);
+
+ public:
+ static const bool value = sizeof(Check<T>(0)) == sizeof(Yes);
+};
template <typename T>
class UnretainedWrapper {
@@ -238,6 +251,20 @@ class ConstRefWrapper {
const T* ptr_;
};
+template <typename T>
+struct IgnoreResultHelper {
+ explicit IgnoreResultHelper(T functor) : functor_(functor) {}
+
+ T functor_;
+};
+
+template <typename T>
+struct IgnoreResultHelper<Callback<T> > {
+ explicit IgnoreResultHelper(const Callback<T>& functor) : functor_(functor) {}
+
+ const Callback<T>& functor_;
+};
+
// An alternate implementation is to avoid the destructive copy, and instead
// specialize ParamTraits<> for OwnedWrapper<> to change the StorageType to
// a class that is essentially a scoped_ptr<>.
@@ -260,61 +287,80 @@ class OwnedWrapper {
mutable T* ptr_;
};
-
// Unwrap the stored parameters for the wrappers above.
template <typename T>
-T Unwrap(T o) { return o; }
+struct UnwrapTraits {
+ typedef const T& ForwardType;
+ static ForwardType Unwrap(const T& o) { return o; }
+};
template <typename T>
-T* Unwrap(UnretainedWrapper<T> unretained) { return unretained.get(); }
+struct UnwrapTraits<UnretainedWrapper<T> > {
+ typedef T* ForwardType;
+ static ForwardType Unwrap(UnretainedWrapper<T> unretained) {
+ return unretained.get();
+ }
+};
template <typename T>
-const T& Unwrap(ConstRefWrapper<T> const_ref) {
- return const_ref.get();
-}
+struct UnwrapTraits<ConstRefWrapper<T> > {
+ typedef const T& ForwardType;
+ static ForwardType Unwrap(ConstRefWrapper<T> const_ref) {
+ return const_ref.get();
+ }
+};
template <typename T>
-T* Unwrap(const scoped_refptr<T>& o) { return o.get(); }
+struct UnwrapTraits<scoped_refptr<T> > {
+ typedef T* ForwardType;
+ static ForwardType Unwrap(const scoped_refptr<T>& o) { return o.get(); }
+};
template <typename T>
-const WeakPtr<T>& Unwrap(const WeakPtr<T>& o) { return o; }
+struct UnwrapTraits<WeakPtr<T> > {
+ typedef const WeakPtr<T>& ForwardType;
+ static ForwardType Unwrap(const WeakPtr<T>& o) { return o; }
+};
template <typename T>
-T* Unwrap(const OwnedWrapper<T>& o) {
- return o.get();
-}
+struct UnwrapTraits<OwnedWrapper<T> > {
+ typedef T* ForwardType;
+ static ForwardType Unwrap(const OwnedWrapper<T>& o) {
+ return o.get();
+ }
+};
// Utility for handling different refcounting semantics in the Bind()
// function.
-template <typename IsMethod, typename T>
+template <bool, typename T>
struct MaybeRefcount;
template <typename T>
-struct MaybeRefcount<base::false_type, T> {
+struct MaybeRefcount<false, T> {
static void AddRef(const T&) {}
static void Release(const T&) {}
};
template <typename T, size_t n>
-struct MaybeRefcount<base::false_type, T[n]> {
+struct MaybeRefcount<false, T[n]> {
static void AddRef(const T*) {}
static void Release(const T*) {}
};
template <typename T>
-struct MaybeRefcount<base::true_type, T*> {
+struct MaybeRefcount<true, T*> {
static void AddRef(T* o) { o->AddRef(); }
static void Release(T* o) { o->Release(); }
};
template <typename T>
-struct MaybeRefcount<base::true_type, UnretainedWrapper<T> > {
+struct MaybeRefcount<true, UnretainedWrapper<T> > {
static void AddRef(const UnretainedWrapper<T>&) {}
static void Release(const UnretainedWrapper<T>&) {}
};
template <typename T>
-struct MaybeRefcount<base::true_type, OwnedWrapper<T> > {
+struct MaybeRefcount<true, OwnedWrapper<T> > {
static void AddRef(const OwnedWrapper<T>&) {}
static void Release(const OwnedWrapper<T>&) {}
};
@@ -322,19 +368,19 @@ struct MaybeRefcount<base::true_type, OwnedWrapper<T> > {
// No need to additionally AddRef() and Release() since we are storing a
// scoped_refptr<> inside the storage object already.
template <typename T>
-struct MaybeRefcount<base::true_type, scoped_refptr<T> > {
+struct MaybeRefcount<true, scoped_refptr<T> > {
static void AddRef(const scoped_refptr<T>& o) {}
static void Release(const scoped_refptr<T>& o) {}
};
template <typename T>
-struct MaybeRefcount<base::true_type, const T*> {
+struct MaybeRefcount<true, const T*> {
static void AddRef(const T* o) { o->AddRef(); }
static void Release(const T* o) { o->Release(); }
};
template <typename T>
-struct MaybeRefcount<base::true_type, WeakPtr<T> > {
+struct MaybeRefcount<true, WeakPtr<T> > {
static void AddRef(const WeakPtr<T>&) {}
static void Release(const WeakPtr<T>&) {}
};
@@ -344,28 +390,55 @@ void VoidReturnAdapter(Callback<R(void)> callback) {
callback.Run();
}
+// IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a
+// method. It is unsed internally by Bind() to select the correct
+// InvokeHelper that will no-op itself in the event the WeakPtr<> for
+// the target object is invalidated.
+//
+// P1 should be the type of the object that will be received of the method.
+template <bool IsMethod, typename P1>
+struct IsWeakMethod : public false_type {};
+
+template <typename T>
+struct IsWeakMethod<true, WeakPtr<T> > : public true_type {};
+
+template <typename T>
+struct IsWeakMethod<true, ConstRefWrapper<WeakPtr<T> > > : public true_type {};
+
} // namespace internal
template <typename T>
-inline internal::UnretainedWrapper<T> Unretained(T* o) {
+static inline internal::UnretainedWrapper<T> Unretained(T* o) {
return internal::UnretainedWrapper<T>(o);
}
template <typename T>
-inline internal::ConstRefWrapper<T> ConstRef(const T& o) {
+static inline internal::ConstRefWrapper<T> ConstRef(const T& o) {
return internal::ConstRefWrapper<T>(o);
}
template <typename T>
-inline internal::OwnedWrapper<T> Owned(T* o) {
+static inline internal::OwnedWrapper<T> Owned(T* o) {
return internal::OwnedWrapper<T>(o);
}
template <typename R>
-Closure IgnoreReturn(Callback<R(void)> callback) {
+static inline Closure IgnoreReturn(Callback<R(void)> callback) {
return Bind(&internal::VoidReturnAdapter<R>, callback);
}
+template <typename T>
+static inline internal::IgnoreResultHelper<T> IgnoreResult(T data) {
+ return internal::IgnoreResultHelper<T>(data);
+}
+
+template <typename T>
+static inline internal::IgnoreResultHelper<Callback<T> >
+IgnoreResult(const Callback<T>& data) {
+ return internal::IgnoreResultHelper<Callback<T> >(data);
+}
+
+
} // namespace base
#endif // BASE_BIND_HELPERS_H_
diff --git a/base/bind_internal.h b/base/bind_internal.h
index 7beba51..6c76d80 100644
--- a/base/bind_internal.h
+++ b/base/bind_internal.h
@@ -4,6 +4,12 @@
+// TODO(ajwong): If you create an fully unbound method, is there a way to
+// enforce the first argument must be refcounted? Or do we just say
+// "oh well"?
+//
+// Do we want to allow creating a fully unbound method??
+
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -26,2167 +32,2114 @@
namespace base {
namespace internal {
-// The method by which a function is invoked is determined by 3 different
-// dimensions:
-//
-// 1) The type of function (normal or method).
-// 2) The arity of the function.
-// 3) The number of bound parameters.
+// CONCEPTS:
+// Runnable -- A type (really a type class) that has a single Run() method
+// and a RunType typedef that corresponds to the type of Run().
+// A Runnable can declare that it should treated like a method
+// call by including a typedef named IsMethod. The value of
+// this typedef is NOT inspected, only the existence. When a
+// Runnable declares itself a method, Bind() will enforce special
+// refcounting + WeakPtr handling semantics for the first
+// parameter which is expected to be an object.
+// Functor -- A copyable type representing something that should be called.
+// All function pointers, Callback<>, and Runnables are functors
+// even if the invocation syntax differs.
+// RunType -- A function type (as opposed to function _pointer_ type) for
+// a Run() function. Usually just a convenience typedef.
+// (Bound)ArgsType -- A function type that is being (ab)used to store the
+// types of set of arguments. The "return" type is always
+// void here. We use this hack so that we do not need
+// a new type name for each arity of type. (eg.,
+// BindState1, BindState2). This makes forward
+// declarations and friending much much easier.
//
-// The templates below handle the determination of each of these dimensions.
-// In brief:
-//
-// FunctionTraits<> -- Provides a normalied signature, and other traits.
-// InvokerN<> -- Provides a DoInvoke() function that actually executes
-// a calback.
-// InvokerStorageN<> -- Provides storage for the bound parameters, and
-// typedefs to the above.
-// IsWeakMethod<> -- Determines if we are binding a method to a WeakPtr<>.
-//
-// More details about the design of each class is included in a comment closer
-// to their defition.
-
-
-// IsWeakMethod determines if we are binding a method to a WeakPtr<> for an
-// object. It is used to select an InvokerN that will no-op itself in the
-// event the WeakPtr<> for the target object is invalidated.
-template <bool IsMethod, typename T>
-struct IsWeakMethod : public false_type {};
-
-template <typename T>
-struct IsWeakMethod<true, WeakPtr<T> > : public true_type {};
-
-// FunctionTraits<>
+// Types:
+// RunnableAdapter<> -- Wraps the various "function" pointer types into an
+// object that adheres to the Runnable interface.
+// There are |3*ARITY| RunnableAdapter types.
+// FunctionTraits<> -- Type traits that unwrap a function signature into a
+// a set of easier to use typedefs. Used mainly for
+// compile time asserts.
+// There are |ARITY| FunctionTraits types.
+// ForceVoidReturn<> -- Helper class for translating function signatures to
+// equivalent forms with a "void" return type.
+// There are |ARITY| ForceVoidReturn types.
+// FunctorTraits<> -- Type traits used determine the correct RunType and
+// RunnableType for a Functor. This is where function
+// signature adapters are applied.
+// There are |ARITY| ForceVoidReturn types.
+// MakeRunnable<> -- Takes a Functor and returns an object in the Runnable
+// type class that represents the underlying Functor.
+// There are |O(1)| MakeRunnable types.
+// InvokeHelper<> -- Take a Runnable + arguments and actully invokes it.
+// Handle the differing syntaxes needed for WeakPtr<> support,
+// and for ignoring return values. This is separate from
+// Invoker to avoid creating multiple version of Invoker<>
+// which grows at O(n^2) with the arity.
+// There are |k*ARITY| InvokeHelper types.
+// Invoker<> -- Unwraps the curried parameters and executes the Runnable.
+// There are |(ARITY^2 + ARITY)/2| Invoketypes.
+// BindState<> -- Stores the curried parameters, and is the main entry point
+// into the Bind() system, doing most of the type resolution.
+// There are ARITY BindState types.
+
+
+// RunnableAdapter<>
//
-// The FunctionTraits<> template determines the type of function, and also
-// creates a NormalizedType used to select the InvokerN classes. It turns out
-// that syntactically, you only really have 2 variations when invoking a
-// funciton pointer: normal, and method. One is invoked func_ptr(arg1). The
-// other is invoked (*obj_->method_ptr(arg1)).
+// The RunnableAdapter<> templates provide a uniform interface for invoking
+// a function pointer, method pointer, or const method pointer. The adapter
+// exposes a Run() method with an appropriate signature. Using this wrapper
+// allows for writing code that supports all three pointer types without
+// undue repetition. Without it, a lot of code would need to be repeated 3
+// times.
//
-// However, in the type system, there are many more distinctions. In standard
-// C++, there's all variations of const, and volatile on the function pointer.
-// In Windows, there are additional calling conventions (eg., __stdcall,
-// __fastcall, etc.). FunctionTraits<> handles categorizing each of these into
-// a normalized signature.
+// For method pointers and const method pointers the first argument to Run()
+// is considered to be the received of the method. This is similar to STL's
+// mem_fun().
//
-// Having a NormalizedSignature signature, reduces the combinatoric
-// complexity of defintions for the InvokerN<> later. Even though there are
-// only 2 syntactic variations on invoking a function, without normalizing the
-// signature, there would need to be one specialization of InvokerN for each
-// unique (function_type, bound_arg, unbound_args) tuple in order to match all
-// function signatures.
+// This class also exposes a RunType typedef that is the function type of the
+// Run() function.
//
-// By normalizing the function signature, we reduce function_type to exactly 2.
+// If and only if the wrapper contains a method or const method pointer, an
+// IsMethod typedef is exposed. The existence of this typedef (NOT the value)
+// marks that the wrapper should be considered a method wrapper.
-template <typename Sig>
-struct FunctionTraits;
+template <typename Functor>
+class RunnableAdapter;
// Function: Arity 0.
template <typename R>
-struct FunctionTraits<R(*)()> {
- typedef R (*NormalizedSig)();
- typedef false_type IsMethod;
+class RunnableAdapter<R(*)()> {
+ public:
+ typedef R (RunType)();
+
+ explicit RunnableAdapter(R(*function)())
+ : function_(function) {
+ }
- typedef R Return;
+ R Run() {
+ return function_();
+ }
+ private:
+ R (*function_)();
};
// Method: Arity 0.
template <typename R, typename T>
-struct FunctionTraits<R(T::*)()> {
- typedef R (T::*NormalizedSig)();
+class RunnableAdapter<R(T::*)()> {
+ public:
+ typedef R (RunType)(T*);
typedef true_type IsMethod;
- typedef R Return;
+ explicit RunnableAdapter(R(T::*method)())
+ : method_(method) {
+ }
- // Target type for each bound parameter.
- typedef T B1;
+ R Run(T* object) {
+ return (object->*method_)();
+ }
+ private:
+ R (T::*method_)();
};
// Const Method: Arity 0.
template <typename R, typename T>
-struct FunctionTraits<R(T::*)() const> {
- typedef R (T::*NormalizedSig)();
+class RunnableAdapter<R(T::*)() const> {
+ public:
+ typedef R (RunType)(const T*);
typedef true_type IsMethod;
- typedef R Return;
+ explicit RunnableAdapter(R(T::*method)() const)
+ : method_(method) {
+ }
- // Target type for each bound parameter.
- typedef T B1;
+ R Run(const T* object) {
+ return (object->*method_)();
+ }
+ private:
+ R (T::*method_)() const;
};
// Function: Arity 1.
-template <typename R, typename X1>
-struct FunctionTraits<R(*)(X1)> {
- typedef R (*NormalizedSig)(X1);
- typedef false_type IsMethod;
+template <typename R, typename A1>
+class RunnableAdapter<R(*)(A1)> {
+ public:
+ typedef R (RunType)(A1);
- typedef R Return;
+ explicit RunnableAdapter(R(*function)(A1))
+ : function_(function) {
+ }
- // Target type for each bound parameter.
- typedef X1 B1;
+ R Run(typename CallbackParamTraits<A1>::ForwardType a1) {
+ return function_(a1);
+ }
+ private:
+ R (*function_)(A1);
};
// Method: Arity 1.
-template <typename R, typename T, typename X1>
-struct FunctionTraits<R(T::*)(X1)> {
- typedef R (T::*NormalizedSig)(X1);
+template <typename R, typename T, typename A1>
+class RunnableAdapter<R(T::*)(A1)> {
+ public:
+ typedef R (RunType)(T*, A1);
typedef true_type IsMethod;
- typedef R Return;
+ explicit RunnableAdapter(R(T::*method)(A1))
+ : method_(method) {
+ }
- // Target type for each bound parameter.
- typedef T B1;
- typedef X1 B2;
+ R Run(T* object, typename CallbackParamTraits<A1>::ForwardType a1) {
+ return (object->*method_)(a1);
+ }
+ private:
+ R (T::*method_)(A1);
};
// Const Method: Arity 1.
-template <typename R, typename T, typename X1>
-struct FunctionTraits<R(T::*)(X1) const> {
- typedef R (T::*NormalizedSig)(X1);
+template <typename R, typename T, typename A1>
+class RunnableAdapter<R(T::*)(A1) const> {
+ public:
+ typedef R (RunType)(const T*, A1);
typedef true_type IsMethod;
- typedef R Return;
+ explicit RunnableAdapter(R(T::*method)(A1) const)
+ : method_(method) {
+ }
- // Target type for each bound parameter.
- typedef T B1;
- typedef X1 B2;
+ R Run(const T* object, typename CallbackParamTraits<A1>::ForwardType a1) {
+ return (object->*method_)(a1);
+ }
+ private:
+ R (T::*method_)(A1) const;
};
// Function: Arity 2.
-template <typename R, typename X1, typename X2>
-struct FunctionTraits<R(*)(X1, X2)> {
- typedef R (*NormalizedSig)(X1, X2);
- typedef false_type IsMethod;
+template <typename R, typename A1, typename A2>
+class RunnableAdapter<R(*)(A1, A2)> {
+ public:
+ typedef R (RunType)(A1, A2);
- typedef R Return;
+ explicit RunnableAdapter(R(*function)(A1, A2))
+ : function_(function) {
+ }
- // Target type for each bound parameter.
- typedef X1 B1;
- typedef X2 B2;
+ R Run(typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2) {
+ return function_(a1, a2);
+ }
+ private:
+ R (*function_)(A1, A2);
};
// Method: Arity 2.
-template <typename R, typename T, typename X1, typename X2>
-struct FunctionTraits<R(T::*)(X1, X2)> {
- typedef R (T::*NormalizedSig)(X1, X2);
+template <typename R, typename T, typename A1, typename A2>
+class RunnableAdapter<R(T::*)(A1, A2)> {
+ public:
+ typedef R (RunType)(T*, A1, A2);
typedef true_type IsMethod;
- typedef R Return;
+ explicit RunnableAdapter(R(T::*method)(A1, A2))
+ : method_(method) {
+ }
- // Target type for each bound parameter.
- typedef T B1;
- typedef X1 B2;
- typedef X2 B3;
+ R Run(T* object, typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2) {
+ return (object->*method_)(a1, a2);
+ }
+ private:
+ R (T::*method_)(A1, A2);
};
// Const Method: Arity 2.
-template <typename R, typename T, typename X1, typename X2>
-struct FunctionTraits<R(T::*)(X1, X2) const> {
- typedef R (T::*NormalizedSig)(X1, X2);
+template <typename R, typename T, typename A1, typename A2>
+class RunnableAdapter<R(T::*)(A1, A2) const> {
+ public:
+ typedef R (RunType)(const T*, A1, A2);
typedef true_type IsMethod;
- typedef R Return;
+ explicit RunnableAdapter(R(T::*method)(A1, A2) const)
+ : method_(method) {
+ }
- // Target type for each bound parameter.
- typedef T B1;
- typedef X1 B2;
- typedef X2 B3;
+ R Run(const T* object, typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2) {
+ return (object->*method_)(a1, a2);
+ }
+ private:
+ R (T::*method_)(A1, A2) const;
};
// Function: Arity 3.
-template <typename R, typename X1, typename X2, typename X3>
-struct FunctionTraits<R(*)(X1, X2, X3)> {
- typedef R (*NormalizedSig)(X1, X2, X3);
- typedef false_type IsMethod;
+template <typename R, typename A1, typename A2, typename A3>
+class RunnableAdapter<R(*)(A1, A2, A3)> {
+ public:
+ typedef R (RunType)(A1, A2, A3);
- typedef R Return;
+ explicit RunnableAdapter(R(*function)(A1, A2, A3))
+ : function_(function) {
+ }
- // Target type for each bound parameter.
- typedef X1 B1;
- typedef X2 B2;
- typedef X3 B3;
+ R Run(typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2,
+ typename CallbackParamTraits<A3>::ForwardType a3) {
+ return function_(a1, a2, a3);
+ }
+ private:
+ R (*function_)(A1, A2, A3);
};
// Method: Arity 3.
-template <typename R, typename T, typename X1, typename X2, typename X3>
-struct FunctionTraits<R(T::*)(X1, X2, X3)> {
- typedef R (T::*NormalizedSig)(X1, X2, X3);
+template <typename R, typename T, typename A1, typename A2, typename A3>
+class RunnableAdapter<R(T::*)(A1, A2, A3)> {
+ public:
+ typedef R (RunType)(T*, A1, A2, A3);
typedef true_type IsMethod;
- typedef R Return;
+ explicit RunnableAdapter(R(T::*method)(A1, A2, A3))
+ : method_(method) {
+ }
- // Target type for each bound parameter.
- typedef T B1;
- typedef X1 B2;
- typedef X2 B3;
- typedef X3 B4;
+ R Run(T* object, typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2,
+ typename CallbackParamTraits<A3>::ForwardType a3) {
+ return (object->*method_)(a1, a2, a3);
+ }
+ private:
+ R (T::*method_)(A1, A2, A3);
};
// Const Method: Arity 3.
-template <typename R, typename T, typename X1, typename X2, typename X3>
-struct FunctionTraits<R(T::*)(X1, X2, X3) const> {
- typedef R (T::*NormalizedSig)(X1, X2, X3);
+template <typename R, typename T, typename A1, typename A2, typename A3>
+class RunnableAdapter<R(T::*)(A1, A2, A3) const> {
+ public:
+ typedef R (RunType)(const T*, A1, A2, A3);
typedef true_type IsMethod;
- typedef R Return;
+ explicit RunnableAdapter(R(T::*method)(A1, A2, A3) const)
+ : method_(method) {
+ }
- // Target type for each bound parameter.
- typedef T B1;
- typedef X1 B2;
- typedef X2 B3;
- typedef X3 B4;
+ R Run(const T* object, typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2,
+ typename CallbackParamTraits<A3>::ForwardType a3) {
+ return (object->*method_)(a1, a2, a3);
+ }
+ private:
+ R (T::*method_)(A1, A2, A3) const;
};
// Function: Arity 4.
-template <typename R, typename X1, typename X2, typename X3, typename X4>
-struct FunctionTraits<R(*)(X1, X2, X3, X4)> {
- typedef R (*NormalizedSig)(X1, X2, X3, X4);
- typedef false_type IsMethod;
+template <typename R, typename A1, typename A2, typename A3, typename A4>
+class RunnableAdapter<R(*)(A1, A2, A3, A4)> {
+ public:
+ typedef R (RunType)(A1, A2, A3, A4);
- typedef R Return;
+ explicit RunnableAdapter(R(*function)(A1, A2, A3, A4))
+ : function_(function) {
+ }
- // Target type for each bound parameter.
- typedef X1 B1;
- typedef X2 B2;
- typedef X3 B3;
- typedef X4 B4;
+ R Run(typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2,
+ typename CallbackParamTraits<A3>::ForwardType a3,
+ typename CallbackParamTraits<A4>::ForwardType a4) {
+ return function_(a1, a2, a3, a4);
+ }
+ private:
+ R (*function_)(A1, A2, A3, A4);
};
// Method: Arity 4.
-template <typename R, typename T, typename X1, typename X2, typename X3,
- typename X4>
-struct FunctionTraits<R(T::*)(X1, X2, X3, X4)> {
- typedef R (T::*NormalizedSig)(X1, X2, X3, X4);
+template <typename R, typename T, typename A1, typename A2, typename A3,
+ typename A4>
+class RunnableAdapter<R(T::*)(A1, A2, A3, A4)> {
+ public:
+ typedef R (RunType)(T*, A1, A2, A3, A4);
typedef true_type IsMethod;
- typedef R Return;
+ explicit RunnableAdapter(R(T::*method)(A1, A2, A3, A4))
+ : method_(method) {
+ }
- // Target type for each bound parameter.
- typedef T B1;
- typedef X1 B2;
- typedef X2 B3;
- typedef X3 B4;
- typedef X4 B5;
+ R Run(T* object, typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2,
+ typename CallbackParamTraits<A3>::ForwardType a3,
+ typename CallbackParamTraits<A4>::ForwardType a4) {
+ return (object->*method_)(a1, a2, a3, a4);
+ }
+ private:
+ R (T::*method_)(A1, A2, A3, A4);
};
// Const Method: Arity 4.
-template <typename R, typename T, typename X1, typename X2, typename X3,
- typename X4>
-struct FunctionTraits<R(T::*)(X1, X2, X3, X4) const> {
- typedef R (T::*NormalizedSig)(X1, X2, X3, X4);
+template <typename R, typename T, typename A1, typename A2, typename A3,
+ typename A4>
+class RunnableAdapter<R(T::*)(A1, A2, A3, A4) const> {
+ public:
+ typedef R (RunType)(const T*, A1, A2, A3, A4);
typedef true_type IsMethod;
- typedef R Return;
+ explicit RunnableAdapter(R(T::*method)(A1, A2, A3, A4) const)
+ : method_(method) {
+ }
- // Target type for each bound parameter.
- typedef T B1;
- typedef X1 B2;
- typedef X2 B3;
- typedef X3 B4;
- typedef X4 B5;
+ R Run(const T* object, typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2,
+ typename CallbackParamTraits<A3>::ForwardType a3,
+ typename CallbackParamTraits<A4>::ForwardType a4) {
+ return (object->*method_)(a1, a2, a3, a4);
+ }
+ private:
+ R (T::*method_)(A1, A2, A3, A4) const;
};
// Function: Arity 5.
-template <typename R, typename X1, typename X2, typename X3, typename X4,
- typename X5>
-struct FunctionTraits<R(*)(X1, X2, X3, X4, X5)> {
- typedef R (*NormalizedSig)(X1, X2, X3, X4, X5);
- typedef false_type IsMethod;
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5>
+class RunnableAdapter<R(*)(A1, A2, A3, A4, A5)> {
+ public:
+ typedef R (RunType)(A1, A2, A3, A4, A5);
- typedef R Return;
+ explicit RunnableAdapter(R(*function)(A1, A2, A3, A4, A5))
+ : function_(function) {
+ }
- // Target type for each bound parameter.
- typedef X1 B1;
- typedef X2 B2;
- typedef X3 B3;
- typedef X4 B4;
- typedef X5 B5;
+ R Run(typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2,
+ typename CallbackParamTraits<A3>::ForwardType a3,
+ typename CallbackParamTraits<A4>::ForwardType a4,
+ typename CallbackParamTraits<A5>::ForwardType a5) {
+ return function_(a1, a2, a3, a4, a5);
+ }
+ private:
+ R (*function_)(A1, A2, A3, A4, A5);
};
// Method: Arity 5.
-template <typename R, typename T, typename X1, typename X2, typename X3,
- typename X4, typename X5>
-struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5)> {
- typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5);
+template <typename R, typename T, typename A1, typename A2, typename A3,
+ typename A4, typename A5>
+class RunnableAdapter<R(T::*)(A1, A2, A3, A4, A5)> {
+ public:
+ typedef R (RunType)(T*, A1, A2, A3, A4, A5);
typedef true_type IsMethod;
- typedef R Return;
+ explicit RunnableAdapter(R(T::*method)(A1, A2, A3, A4, A5))
+ : method_(method) {
+ }
- // Target type for each bound parameter.
- typedef T B1;
- typedef X1 B2;
- typedef X2 B3;
- typedef X3 B4;
- typedef X4 B5;
- typedef X5 B6;
+ R Run(T* object, typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2,
+ typename CallbackParamTraits<A3>::ForwardType a3,
+ typename CallbackParamTraits<A4>::ForwardType a4,
+ typename CallbackParamTraits<A5>::ForwardType a5) {
+ return (object->*method_)(a1, a2, a3, a4, a5);
+ }
+ private:
+ R (T::*method_)(A1, A2, A3, A4, A5);
};
// Const Method: Arity 5.
-template <typename R, typename T, typename X1, typename X2, typename X3,
- typename X4, typename X5>
-struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5) const> {
- typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5);
+template <typename R, typename T, typename A1, typename A2, typename A3,
+ typename A4, typename A5>
+class RunnableAdapter<R(T::*)(A1, A2, A3, A4, A5) const> {
+ public:
+ typedef R (RunType)(const T*, A1, A2, A3, A4, A5);
typedef true_type IsMethod;
- typedef R Return;
+ explicit RunnableAdapter(R(T::*method)(A1, A2, A3, A4, A5) const)
+ : method_(method) {
+ }
- // Target type for each bound parameter.
- typedef T B1;
- typedef X1 B2;
- typedef X2 B3;
- typedef X3 B4;
- typedef X4 B5;
- typedef X5 B6;
+ R Run(const T* object, typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2,
+ typename CallbackParamTraits<A3>::ForwardType a3,
+ typename CallbackParamTraits<A4>::ForwardType a4,
+ typename CallbackParamTraits<A5>::ForwardType a5) {
+ return (object->*method_)(a1, a2, a3, a4, a5);
+ }
+ private:
+ R (T::*method_)(A1, A2, A3, A4, A5) const;
};
// Function: Arity 6.
-template <typename R, typename X1, typename X2, typename X3, typename X4,
- typename X5, typename X6>
-struct FunctionTraits<R(*)(X1, X2, X3, X4, X5, X6)> {
- typedef R (*NormalizedSig)(X1, X2, X3, X4, X5, X6);
- typedef false_type IsMethod;
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6>
+class RunnableAdapter<R(*)(A1, A2, A3, A4, A5, A6)> {
+ public:
+ typedef R (RunType)(A1, A2, A3, A4, A5, A6);
- typedef R Return;
+ explicit RunnableAdapter(R(*function)(A1, A2, A3, A4, A5, A6))
+ : function_(function) {
+ }
- // Target type for each bound parameter.
- typedef X1 B1;
- typedef X2 B2;
- typedef X3 B3;
- typedef X4 B4;
- typedef X5 B5;
- typedef X6 B6;
+ R Run(typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2,
+ typename CallbackParamTraits<A3>::ForwardType a3,
+ typename CallbackParamTraits<A4>::ForwardType a4,
+ typename CallbackParamTraits<A5>::ForwardType a5,
+ typename CallbackParamTraits<A6>::ForwardType a6) {
+ return function_(a1, a2, a3, a4, a5, a6);
+ }
+ private:
+ R (*function_)(A1, A2, A3, A4, A5, A6);
};
// Method: Arity 6.
-template <typename R, typename T, typename X1, typename X2, typename X3,
- typename X4, typename X5, typename X6>
-struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5, X6)> {
- typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5, X6);
+template <typename R, typename T, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6>
+class RunnableAdapter<R(T::*)(A1, A2, A3, A4, A5, A6)> {
+ public:
+ typedef R (RunType)(T*, A1, A2, A3, A4, A5, A6);
typedef true_type IsMethod;
- typedef R Return;
+ explicit RunnableAdapter(R(T::*method)(A1, A2, A3, A4, A5, A6))
+ : method_(method) {
+ }
- // Target type for each bound parameter.
- typedef T B1;
- typedef X1 B2;
- typedef X2 B3;
- typedef X3 B4;
- typedef X4 B5;
- typedef X5 B6;
- typedef X6 B7;
+ R Run(T* object, typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2,
+ typename CallbackParamTraits<A3>::ForwardType a3,
+ typename CallbackParamTraits<A4>::ForwardType a4,
+ typename CallbackParamTraits<A5>::ForwardType a5,
+ typename CallbackParamTraits<A6>::ForwardType a6) {
+ return (object->*method_)(a1, a2, a3, a4, a5, a6);
+ }
+ private:
+ R (T::*method_)(A1, A2, A3, A4, A5, A6);
};
// Const Method: Arity 6.
-template <typename R, typename T, typename X1, typename X2, typename X3,
- typename X4, typename X5, typename X6>
-struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5, X6) const> {
- typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5, X6);
+template <typename R, typename T, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6>
+class RunnableAdapter<R(T::*)(A1, A2, A3, A4, A5, A6) const> {
+ public:
+ typedef R (RunType)(const T*, A1, A2, A3, A4, A5, A6);
typedef true_type IsMethod;
- typedef R Return;
+ explicit RunnableAdapter(R(T::*method)(A1, A2, A3, A4, A5, A6) const)
+ : method_(method) {
+ }
- // Target type for each bound parameter.
- typedef T B1;
- typedef X1 B2;
- typedef X2 B3;
- typedef X3 B4;
- typedef X4 B5;
- typedef X5 B6;
- typedef X6 B7;
+ R Run(const T* object, typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2,
+ typename CallbackParamTraits<A3>::ForwardType a3,
+ typename CallbackParamTraits<A4>::ForwardType a4,
+ typename CallbackParamTraits<A5>::ForwardType a5,
+ typename CallbackParamTraits<A6>::ForwardType a6) {
+ return (object->*method_)(a1, a2, a3, a4, a5, a6);
+ }
+ private:
+ R (T::*method_)(A1, A2, A3, A4, A5, A6) const;
};
-// InvokerN<>
-//
-// The InvokerN templates contain a static DoInvoke() function that is the key
-// to implementing type erasure in the Callback() classes.
-//
-// DoInvoke() is a static function with a fixed signature that is independent
-// of StorageType; its first argument is a pointer to the non-templated common
-// baseclass of StorageType. This lets us store pointer to DoInvoke() in a
-// function pointer that has knowledge of the specific StorageType, and thus
-// no knowledge of the bound function and bound parameter types.
-//
-// As long as we ensure that DoInvoke() is only used with pointers there were
-// upcasted from the correct StorageType, we can be sure that execution is
-// safe.
+
+// FunctionTraits<>
//
-// The InvokerN templates are the only point that knows the number of bound
-// and unbound arguments. This is intentional because it allows the other
-// templates classes in the system to only have as many specializations as
-// the max arity of function we wish to support.
+// Breaks a function signature apart into typedefs for easier introspection.
+template <typename Sig>
+struct FunctionTraits;
-template <bool IsWeak, typename StorageType, typename NormalizedSig>
-struct Invoker0;
+template <typename R>
+struct FunctionTraits<R()> {
+ typedef R ReturnType;
+};
-// Function: Arity 0 -> 0.
-template <typename StorageType, typename R>
-struct Invoker0<false, StorageType, R(*)()> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*);
+template <typename R, typename A1>
+struct FunctionTraits<R(A1)> {
+ typedef R ReturnType;
+ typedef A1 A1Type;
+};
- static R DoInvoke(InvokerStorageBase* base) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_();
- }
+template <typename R, typename A1, typename A2>
+struct FunctionTraits<R(A1, A2)> {
+ typedef R ReturnType;
+ typedef A1 A1Type;
+ typedef A2 A2Type;
};
-// Function: Arity 1 -> 1.
-template <typename StorageType, typename R,typename X1>
-struct Invoker0<false, StorageType, R(*)(X1)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X1>::ForwardType);
+template <typename R, typename A1, typename A2, typename A3>
+struct FunctionTraits<R(A1, A2, A3)> {
+ typedef R ReturnType;
+ typedef A1 A1Type;
+ typedef A2 A2Type;
+ typedef A3 A3Type;
+};
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X1>::ForwardType x1) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(x1);
- }
+template <typename R, typename A1, typename A2, typename A3, typename A4>
+struct FunctionTraits<R(A1, A2, A3, A4)> {
+ typedef R ReturnType;
+ typedef A1 A1Type;
+ typedef A2 A2Type;
+ typedef A3 A3Type;
+ typedef A4 A4Type;
};
-// Function: Arity 2 -> 2.
-template <typename StorageType, typename R,typename X1, typename X2>
-struct Invoker0<false, StorageType, R(*)(X1, X2)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X1>::ForwardType,
- typename internal::ParamTraits<X2>::ForwardType);
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5>
+struct FunctionTraits<R(A1, A2, A3, A4, A5)> {
+ typedef R ReturnType;
+ typedef A1 A1Type;
+ typedef A2 A2Type;
+ typedef A3 A3Type;
+ typedef A4 A4Type;
+ typedef A5 A5Type;
+};
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X1>::ForwardType x1,
- typename internal::ParamTraits<X2>::ForwardType x2) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(x1, x2);
- }
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6>
+struct FunctionTraits<R(A1, A2, A3, A4, A5, A6)> {
+ typedef R ReturnType;
+ typedef A1 A1Type;
+ typedef A2 A2Type;
+ typedef A3 A3Type;
+ typedef A4 A4Type;
+ typedef A5 A5Type;
+ typedef A6 A6Type;
};
-// Function: Arity 3 -> 3.
-template <typename StorageType, typename R,typename X1, typename X2,
- typename X3>
-struct Invoker0<false, StorageType, R(*)(X1, X2, X3)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X1>::ForwardType,
- typename internal::ParamTraits<X2>::ForwardType,
- typename internal::ParamTraits<X3>::ForwardType);
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X1>::ForwardType x1,
- typename internal::ParamTraits<X2>::ForwardType x2,
- typename internal::ParamTraits<X3>::ForwardType x3) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(x1, x2, x3);
- }
+// ForceVoidReturn<>
+//
+// Set of templates that support forcing the function return type to void.
+template <typename Sig>
+struct ForceVoidReturn;
+
+template <typename R>
+struct ForceVoidReturn<R()> {
+ typedef void(RunType)();
};
-// Function: Arity 4 -> 4.
-template <typename StorageType, typename R,typename X1, typename X2,
- typename X3, typename X4>
-struct Invoker0<false, StorageType, R(*)(X1, X2, X3, X4)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X1>::ForwardType,
- typename internal::ParamTraits<X2>::ForwardType,
- typename internal::ParamTraits<X3>::ForwardType,
- typename internal::ParamTraits<X4>::ForwardType);
+template <typename R, typename A1>
+struct ForceVoidReturn<R(A1)> {
+ typedef void(RunType)(A1);
+};
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X1>::ForwardType x1,
- typename internal::ParamTraits<X2>::ForwardType x2,
- typename internal::ParamTraits<X3>::ForwardType x3,
- typename internal::ParamTraits<X4>::ForwardType x4) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(x1, x2, x3, x4);
- }
+template <typename R, typename A1, typename A2>
+struct ForceVoidReturn<R(A1, A2)> {
+ typedef void(RunType)(A1, A2);
};
-// Function: Arity 5 -> 5.
-template <typename StorageType, typename R,typename X1, typename X2,
- typename X3, typename X4, typename X5>
-struct Invoker0<false, StorageType, R(*)(X1, X2, X3, X4, X5)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X1>::ForwardType,
- typename internal::ParamTraits<X2>::ForwardType,
- typename internal::ParamTraits<X3>::ForwardType,
- typename internal::ParamTraits<X4>::ForwardType,
- typename internal::ParamTraits<X5>::ForwardType);
-
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X1>::ForwardType x1,
- typename internal::ParamTraits<X2>::ForwardType x2,
- typename internal::ParamTraits<X3>::ForwardType x3,
- typename internal::ParamTraits<X4>::ForwardType x4,
- typename internal::ParamTraits<X5>::ForwardType x5) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(x1, x2, x3, x4, x5);
- }
-};
-
-// Function: Arity 6 -> 6.
-template <typename StorageType, typename R,typename X1, typename X2,
- typename X3, typename X4, typename X5, typename X6>
-struct Invoker0<false, StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X1>::ForwardType,
- typename internal::ParamTraits<X2>::ForwardType,
- typename internal::ParamTraits<X3>::ForwardType,
- typename internal::ParamTraits<X4>::ForwardType,
- typename internal::ParamTraits<X5>::ForwardType,
- typename internal::ParamTraits<X6>::ForwardType);
-
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X1>::ForwardType x1,
- typename internal::ParamTraits<X2>::ForwardType x2,
- typename internal::ParamTraits<X3>::ForwardType x3,
- typename internal::ParamTraits<X4>::ForwardType x4,
- typename internal::ParamTraits<X5>::ForwardType x5,
- typename internal::ParamTraits<X6>::ForwardType x6) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(x1, x2, x3, x4, x5, x6);
- }
-};
-
-template <bool IsWeak, typename StorageType, typename NormalizedSig>
-struct Invoker1;
-
-// Function: Arity 1 -> 0.
-template <typename StorageType, typename R,typename X1>
-struct Invoker1<false, StorageType, R(*)(X1)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*);
+template <typename R, typename A1, typename A2, typename A3>
+struct ForceVoidReturn<R(A1, A2, A3)> {
+ typedef void(RunType)(A1, A2, A3);
+};
- static R DoInvoke(InvokerStorageBase* base) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(Unwrap(invoker->p1_));
- }
+template <typename R, typename A1, typename A2, typename A3, typename A4>
+struct ForceVoidReturn<R(A1, A2, A3, A4)> {
+ typedef void(RunType)(A1, A2, A3, A4);
};
-// Method: Arity 0 -> 0.
-template <typename StorageType, typename R, typename T>
-struct Invoker1<false, StorageType, R(T::*)()> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*);
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5>
+struct ForceVoidReturn<R(A1, A2, A3, A4, A5)> {
+ typedef void(RunType)(A1, A2, A3, A4, A5);
+};
- static R DoInvoke(InvokerStorageBase* base) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return (Unwrap(invoker->p1_)->*invoker->f_)();
- }
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6>
+struct ForceVoidReturn<R(A1, A2, A3, A4, A5, A6)> {
+ typedef void(RunType)(A1, A2, A3, A4, A5, A6);
};
-// WeakPtr Method: Arity 0 -> 0.
-template <typename StorageType, typename T>
-struct Invoker1<true, StorageType, void(T::*)()> {
- typedef void(*DoInvokeType)(
- internal::InvokerStorageBase*);
- static void DoInvoke(InvokerStorageBase* base) {
- StorageType* invoker = static_cast<StorageType*>(base);
- typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
- if (!weak_ptr.get()) {
- return;
- }
- (weak_ptr->*invoker->f_)();
- }
+// FunctorTraits<>
+//
+// See description at top of file.
+template <typename T>
+struct FunctorTraits {
+ typedef RunnableAdapter<T> RunnableType;
+ typedef typename RunnableType::RunType RunType;
};
-// Function: Arity 2 -> 1.
-template <typename StorageType, typename R,typename X1, typename X2>
-struct Invoker1<false, StorageType, R(*)(X1, X2)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X2>::ForwardType);
+template <typename T>
+struct FunctorTraits<IgnoreResultHelper<T> > {
+ typedef typename FunctorTraits<T>::RunnableType RunnableType;
+ typedef typename ForceVoidReturn<
+ typename RunnableType::RunType>::RunType RunType;
+};
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X2>::ForwardType x2) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(Unwrap(invoker->p1_), x2);
- }
+template <typename T>
+struct FunctorTraits<Callback<T> > {
+ typedef Callback<T> RunnableType;
+ typedef typename Callback<T>::RunType RunType;
};
-// Method: Arity 1 -> 1.
-template <typename StorageType, typename R, typename T, typename X1>
-struct Invoker1<false, StorageType, R(T::*)(X1)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X1>::ForwardType);
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X1>::ForwardType x1) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return (Unwrap(invoker->p1_)->*invoker->f_)(x1);
- }
-};
+// MakeRunnable<>
+//
+// Converts a passed in functor to a RunnableType using type inference.
-// WeakPtr Method: Arity 1 -> 1.
-template <typename StorageType, typename T, typename X1>
-struct Invoker1<true, StorageType, void(T::*)(X1)> {
- typedef void(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X1>::ForwardType);
+template <typename T>
+typename FunctorTraits<T>::RunnableType MakeRunnable(const T& t) {
+ return RunnableAdapter<T>(t);
+}
- static void DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X1>::ForwardType x1) {
- StorageType* invoker = static_cast<StorageType*>(base);
- typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
- if (!weak_ptr.get()) {
- return;
- }
- (weak_ptr->*invoker->f_)(x1);
+template <typename T>
+typename FunctorTraits<T>::RunnableType
+MakeRunnable(const IgnoreResultHelper<T>& t) {
+ return MakeRunnable(t.functor_);
+}
+
+template <typename T>
+const typename FunctorTraits<Callback<T> >::RunnableType&
+MakeRunnable(const Callback<T>& t) {
+ return t;
+}
+
+
+// InvokeHelper<>
+//
+// There are 3 logical InvokeHelper<> specializations: normal, void-return,
+// WeakCalls.
+//
+// The normal type just calls the underlying runnable.
+//
+// We need a InvokeHelper to handle void return types in order to support
+// IgnoreResult(). Normally, if the Runnable's RunType had a void return,
+// the template system would just accept "return functor.Run()" ignoring
+// the fact that a void function is being used with return. This piece of
+// sugar breaks though when the Runnable's RunType is not void. Thus, we
+// need a partial specialization to change the syntax to drop the "return"
+// from the invocation call.
+//
+// WeakCalls similarly need special syntax that is applied to the first
+// argument to check if they should no-op themselves.
+template <bool IsWeakCall, typename ReturnType, typename Runnable,
+ typename ArgsType>
+struct InvokeHelper;
+
+template <typename ReturnType, typename Runnable>
+struct InvokeHelper<false, ReturnType, Runnable,
+ void()> {
+ static ReturnType MakeItSo(Runnable runnable) {
+ return runnable.Run();
}
};
-// Function: Arity 3 -> 2.
-template <typename StorageType, typename R,typename X1, typename X2,
- typename X3>
-struct Invoker1<false, StorageType, R(*)(X1, X2, X3)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X2>::ForwardType,
- typename internal::ParamTraits<X3>::ForwardType);
-
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X2>::ForwardType x2,
- typename internal::ParamTraits<X3>::ForwardType x3) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(Unwrap(invoker->p1_), x2, x3);
- }
-};
-
-// Method: Arity 2 -> 2.
-template <typename StorageType, typename R, typename T, typename X1,
- typename X2>
-struct Invoker1<false, StorageType, R(T::*)(X1, X2)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X1>::ForwardType,
- typename internal::ParamTraits<X2>::ForwardType);
-
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X1>::ForwardType x1,
- typename internal::ParamTraits<X2>::ForwardType x2) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2);
- }
-};
-
-// WeakPtr Method: Arity 2 -> 2.
-template <typename StorageType, typename T, typename X1, typename X2>
-struct Invoker1<true, StorageType, void(T::*)(X1, X2)> {
- typedef void(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X1>::ForwardType,
- typename internal::ParamTraits<X2>::ForwardType);
-
- static void DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X1>::ForwardType x1,
- typename internal::ParamTraits<X2>::ForwardType x2) {
- StorageType* invoker = static_cast<StorageType*>(base);
- typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
- if (!weak_ptr.get()) {
- return;
- }
- (weak_ptr->*invoker->f_)(x1, x2);
+template <typename Runnable>
+struct InvokeHelper<false, void, Runnable,
+ void()> {
+ static void MakeItSo(Runnable runnable) {
+ runnable.Run();
}
};
-// Function: Arity 4 -> 3.
-template <typename StorageType, typename R,typename X1, typename X2,
- typename X3, typename X4>
-struct Invoker1<false, StorageType, R(*)(X1, X2, X3, X4)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X2>::ForwardType,
- typename internal::ParamTraits<X3>::ForwardType,
- typename internal::ParamTraits<X4>::ForwardType);
-
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X2>::ForwardType x2,
- typename internal::ParamTraits<X3>::ForwardType x3,
- typename internal::ParamTraits<X4>::ForwardType x4) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(Unwrap(invoker->p1_), x2, x3, x4);
- }
-};
-
-// Method: Arity 3 -> 3.
-template <typename StorageType, typename R, typename T, typename X1,
- typename X2, typename X3>
-struct Invoker1<false, StorageType, R(T::*)(X1, X2, X3)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X1>::ForwardType,
- typename internal::ParamTraits<X2>::ForwardType,
- typename internal::ParamTraits<X3>::ForwardType);
-
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X1>::ForwardType x1,
- typename internal::ParamTraits<X2>::ForwardType x2,
- typename internal::ParamTraits<X3>::ForwardType x3) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2, x3);
- }
-};
-
-// WeakPtr Method: Arity 3 -> 3.
-template <typename StorageType, typename T, typename X1, typename X2,
- typename X3>
-struct Invoker1<true, StorageType, void(T::*)(X1, X2, X3)> {
- typedef void(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X1>::ForwardType,
- typename internal::ParamTraits<X2>::ForwardType,
- typename internal::ParamTraits<X3>::ForwardType);
-
- static void DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X1>::ForwardType x1,
- typename internal::ParamTraits<X2>::ForwardType x2,
- typename internal::ParamTraits<X3>::ForwardType x3) {
- StorageType* invoker = static_cast<StorageType*>(base);
- typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
- if (!weak_ptr.get()) {
- return;
- }
- (weak_ptr->*invoker->f_)(x1, x2, x3);
+template <typename ReturnType, typename Runnable,typename A1>
+struct InvokeHelper<false, ReturnType, Runnable,
+ void(A1)> {
+ static ReturnType MakeItSo(Runnable runnable, A1 a1) {
+ return runnable.Run(a1);
}
};
-// Function: Arity 5 -> 4.
-template <typename StorageType, typename R,typename X1, typename X2,
- typename X3, typename X4, typename X5>
-struct Invoker1<false, StorageType, R(*)(X1, X2, X3, X4, X5)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X2>::ForwardType,
- typename internal::ParamTraits<X3>::ForwardType,
- typename internal::ParamTraits<X4>::ForwardType,
- typename internal::ParamTraits<X5>::ForwardType);
-
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X2>::ForwardType x2,
- typename internal::ParamTraits<X3>::ForwardType x3,
- typename internal::ParamTraits<X4>::ForwardType x4,
- typename internal::ParamTraits<X5>::ForwardType x5) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(Unwrap(invoker->p1_), x2, x3, x4, x5);
- }
-};
-
-// Method: Arity 4 -> 4.
-template <typename StorageType, typename R, typename T, typename X1,
- typename X2, typename X3, typename X4>
-struct Invoker1<false, StorageType, R(T::*)(X1, X2, X3, X4)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X1>::ForwardType,
- typename internal::ParamTraits<X2>::ForwardType,
- typename internal::ParamTraits<X3>::ForwardType,
- typename internal::ParamTraits<X4>::ForwardType);
-
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X1>::ForwardType x1,
- typename internal::ParamTraits<X2>::ForwardType x2,
- typename internal::ParamTraits<X3>::ForwardType x3,
- typename internal::ParamTraits<X4>::ForwardType x4) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2, x3, x4);
- }
-};
-
-// WeakPtr Method: Arity 4 -> 4.
-template <typename StorageType, typename T, typename X1, typename X2,
- typename X3, typename X4>
-struct Invoker1<true, StorageType, void(T::*)(X1, X2, X3, X4)> {
- typedef void(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X1>::ForwardType,
- typename internal::ParamTraits<X2>::ForwardType,
- typename internal::ParamTraits<X3>::ForwardType,
- typename internal::ParamTraits<X4>::ForwardType);
-
- static void DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X1>::ForwardType x1,
- typename internal::ParamTraits<X2>::ForwardType x2,
- typename internal::ParamTraits<X3>::ForwardType x3,
- typename internal::ParamTraits<X4>::ForwardType x4) {
- StorageType* invoker = static_cast<StorageType*>(base);
- typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
- if (!weak_ptr.get()) {
- return;
- }
- (weak_ptr->*invoker->f_)(x1, x2, x3, x4);
+template <typename Runnable,typename A1>
+struct InvokeHelper<false, void, Runnable,
+ void(A1)> {
+ static void MakeItSo(Runnable runnable, A1 a1) {
+ runnable.Run(a1);
}
};
-// Function: Arity 6 -> 5.
-template <typename StorageType, typename R,typename X1, typename X2,
- typename X3, typename X4, typename X5, typename X6>
-struct Invoker1<false, StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X2>::ForwardType,
- typename internal::ParamTraits<X3>::ForwardType,
- typename internal::ParamTraits<X4>::ForwardType,
- typename internal::ParamTraits<X5>::ForwardType,
- typename internal::ParamTraits<X6>::ForwardType);
-
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X2>::ForwardType x2,
- typename internal::ParamTraits<X3>::ForwardType x3,
- typename internal::ParamTraits<X4>::ForwardType x4,
- typename internal::ParamTraits<X5>::ForwardType x5,
- typename internal::ParamTraits<X6>::ForwardType x6) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(Unwrap(invoker->p1_), x2, x3, x4, x5, x6);
- }
-};
-
-// Method: Arity 5 -> 5.
-template <typename StorageType, typename R, typename T, typename X1,
- typename X2, typename X3, typename X4, typename X5>
-struct Invoker1<false, StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X1>::ForwardType,
- typename internal::ParamTraits<X2>::ForwardType,
- typename internal::ParamTraits<X3>::ForwardType,
- typename internal::ParamTraits<X4>::ForwardType,
- typename internal::ParamTraits<X5>::ForwardType);
-
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X1>::ForwardType x1,
- typename internal::ParamTraits<X2>::ForwardType x2,
- typename internal::ParamTraits<X3>::ForwardType x3,
- typename internal::ParamTraits<X4>::ForwardType x4,
- typename internal::ParamTraits<X5>::ForwardType x5) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2, x3, x4, x5);
- }
-};
-
-// WeakPtr Method: Arity 5 -> 5.
-template <typename StorageType, typename T, typename X1, typename X2,
- typename X3, typename X4, typename X5>
-struct Invoker1<true, StorageType, void(T::*)(X1, X2, X3, X4, X5)> {
- typedef void(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X1>::ForwardType,
- typename internal::ParamTraits<X2>::ForwardType,
- typename internal::ParamTraits<X3>::ForwardType,
- typename internal::ParamTraits<X4>::ForwardType,
- typename internal::ParamTraits<X5>::ForwardType);
-
- static void DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X1>::ForwardType x1,
- typename internal::ParamTraits<X2>::ForwardType x2,
- typename internal::ParamTraits<X3>::ForwardType x3,
- typename internal::ParamTraits<X4>::ForwardType x4,
- typename internal::ParamTraits<X5>::ForwardType x5) {
- StorageType* invoker = static_cast<StorageType*>(base);
- typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
- if (!weak_ptr.get()) {
+template <typename Runnable, typename A1>
+struct InvokeHelper<true, void, Runnable,
+ void(A1)> {
+ static void MakeItSo(Runnable runnable, A1 a1) {
+ if (!a1.get()) {
return;
}
- (weak_ptr->*invoker->f_)(x1, x2, x3, x4, x5);
+
+ runnable.Run(a1);
}
};
-template <bool IsWeak, typename StorageType, typename NormalizedSig>
-struct Invoker2;
-
-// Function: Arity 2 -> 0.
-template <typename StorageType, typename R,typename X1, typename X2>
-struct Invoker2<false, StorageType, R(*)(X1, X2)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*);
-
- static R DoInvoke(InvokerStorageBase* base) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_));
+template <typename ReturnType, typename Runnable,typename A1, typename A2>
+struct InvokeHelper<false, ReturnType, Runnable,
+ void(A1, A2)> {
+ static ReturnType MakeItSo(Runnable runnable, A1 a1, A2 a2) {
+ return runnable.Run(a1, a2);
}
};
-// Method: Arity 1 -> 0.
-template <typename StorageType, typename R, typename T, typename X1>
-struct Invoker2<false, StorageType, R(T::*)(X1)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*);
-
- static R DoInvoke(InvokerStorageBase* base) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_));
+template <typename Runnable,typename A1, typename A2>
+struct InvokeHelper<false, void, Runnable,
+ void(A1, A2)> {
+ static void MakeItSo(Runnable runnable, A1 a1, A2 a2) {
+ runnable.Run(a1, a2);
}
};
-// WeakPtr Method: Arity 1 -> 0.
-template <typename StorageType, typename T, typename X1>
-struct Invoker2<true, StorageType, void(T::*)(X1)> {
- typedef void(*DoInvokeType)(
- internal::InvokerStorageBase*);
-
- static void DoInvoke(InvokerStorageBase* base) {
- StorageType* invoker = static_cast<StorageType*>(base);
- typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
- if (!weak_ptr.get()) {
+template <typename Runnable, typename A1, typename A2>
+struct InvokeHelper<true, void, Runnable,
+ void(A1, A2)> {
+ static void MakeItSo(Runnable runnable, A1 a1, A2 a2) {
+ if (!a1.get()) {
return;
}
- (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_));
+
+ runnable.Run(a1, a2);
}
};
-// Function: Arity 3 -> 1.
-template <typename StorageType, typename R,typename X1, typename X2,
- typename X3>
-struct Invoker2<false, StorageType, R(*)(X1, X2, X3)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X3>::ForwardType);
-
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X3>::ForwardType x3) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3);
+template <typename ReturnType, typename Runnable,typename A1, typename A2,
+ typename A3>
+struct InvokeHelper<false, ReturnType, Runnable,
+ void(A1, A2, A3)> {
+ static ReturnType MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3) {
+ return runnable.Run(a1, a2, a3);
}
};
-// Method: Arity 2 -> 1.
-template <typename StorageType, typename R, typename T, typename X1,
- typename X2>
-struct Invoker2<false, StorageType, R(T::*)(X1, X2)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X2>::ForwardType);
-
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X2>::ForwardType x2) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2);
+template <typename Runnable,typename A1, typename A2, typename A3>
+struct InvokeHelper<false, void, Runnable,
+ void(A1, A2, A3)> {
+ static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3) {
+ runnable.Run(a1, a2, a3);
}
};
-// WeakPtr Method: Arity 2 -> 1.
-template <typename StorageType, typename T, typename X1, typename X2>
-struct Invoker2<true, StorageType, void(T::*)(X1, X2)> {
- typedef void(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X2>::ForwardType);
-
- static void DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X2>::ForwardType x2) {
- StorageType* invoker = static_cast<StorageType*>(base);
- typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
- if (!weak_ptr.get()) {
+template <typename Runnable, typename A1, typename A2, typename A3>
+struct InvokeHelper<true, void, Runnable,
+ void(A1, A2, A3)> {
+ static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3) {
+ if (!a1.get()) {
return;
}
- (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), x2);
- }
-};
-// Function: Arity 4 -> 2.
-template <typename StorageType, typename R,typename X1, typename X2,
- typename X3, typename X4>
-struct Invoker2<false, StorageType, R(*)(X1, X2, X3, X4)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X3>::ForwardType,
- typename internal::ParamTraits<X4>::ForwardType);
-
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X3>::ForwardType x3,
- typename internal::ParamTraits<X4>::ForwardType x4) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3, x4);
+ runnable.Run(a1, a2, a3);
}
};
-// Method: Arity 3 -> 2.
-template <typename StorageType, typename R, typename T, typename X1,
- typename X2, typename X3>
-struct Invoker2<false, StorageType, R(T::*)(X1, X2, X3)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X2>::ForwardType,
- typename internal::ParamTraits<X3>::ForwardType);
-
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X2>::ForwardType x2,
- typename internal::ParamTraits<X3>::ForwardType x3) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2, x3);
+template <typename ReturnType, typename Runnable,typename A1, typename A2,
+ typename A3, typename A4>
+struct InvokeHelper<false, ReturnType, Runnable,
+ void(A1, A2, A3, A4)> {
+ static ReturnType MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4) {
+ return runnable.Run(a1, a2, a3, a4);
}
};
-// WeakPtr Method: Arity 3 -> 2.
-template <typename StorageType, typename T, typename X1, typename X2,
- typename X3>
-struct Invoker2<true, StorageType, void(T::*)(X1, X2, X3)> {
- typedef void(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X2>::ForwardType,
- typename internal::ParamTraits<X3>::ForwardType);
-
- static void DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X2>::ForwardType x2,
- typename internal::ParamTraits<X3>::ForwardType x3) {
- StorageType* invoker = static_cast<StorageType*>(base);
- typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
- if (!weak_ptr.get()) {
- return;
- }
- (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), x2, x3);
+template <typename Runnable,typename A1, typename A2, typename A3, typename A4>
+struct InvokeHelper<false, void, Runnable,
+ void(A1, A2, A3, A4)> {
+ static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4) {
+ runnable.Run(a1, a2, a3, a4);
}
};
-// Function: Arity 5 -> 3.
-template <typename StorageType, typename R,typename X1, typename X2,
- typename X3, typename X4, typename X5>
-struct Invoker2<false, StorageType, R(*)(X1, X2, X3, X4, X5)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X3>::ForwardType,
- typename internal::ParamTraits<X4>::ForwardType,
- typename internal::ParamTraits<X5>::ForwardType);
-
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X3>::ForwardType x3,
- typename internal::ParamTraits<X4>::ForwardType x4,
- typename internal::ParamTraits<X5>::ForwardType x5) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3, x4, x5);
- }
-};
-
-// Method: Arity 4 -> 3.
-template <typename StorageType, typename R, typename T, typename X1,
- typename X2, typename X3, typename X4>
-struct Invoker2<false, StorageType, R(T::*)(X1, X2, X3, X4)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X2>::ForwardType,
- typename internal::ParamTraits<X3>::ForwardType,
- typename internal::ParamTraits<X4>::ForwardType);
-
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X2>::ForwardType x2,
- typename internal::ParamTraits<X3>::ForwardType x3,
- typename internal::ParamTraits<X4>::ForwardType x4) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2, x3,
- x4);
- }
-};
-
-// WeakPtr Method: Arity 4 -> 3.
-template <typename StorageType, typename T, typename X1, typename X2,
- typename X3, typename X4>
-struct Invoker2<true, StorageType, void(T::*)(X1, X2, X3, X4)> {
- typedef void(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X2>::ForwardType,
- typename internal::ParamTraits<X3>::ForwardType,
- typename internal::ParamTraits<X4>::ForwardType);
-
- static void DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X2>::ForwardType x2,
- typename internal::ParamTraits<X3>::ForwardType x3,
- typename internal::ParamTraits<X4>::ForwardType x4) {
- StorageType* invoker = static_cast<StorageType*>(base);
- typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
- if (!weak_ptr.get()) {
+template <typename Runnable, typename A1, typename A2, typename A3, typename A4>
+struct InvokeHelper<true, void, Runnable,
+ void(A1, A2, A3, A4)> {
+ static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4) {
+ if (!a1.get()) {
return;
}
- (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), x2, x3, x4);
- }
-};
-// Function: Arity 6 -> 4.
-template <typename StorageType, typename R,typename X1, typename X2,
- typename X3, typename X4, typename X5, typename X6>
-struct Invoker2<false, StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X3>::ForwardType,
- typename internal::ParamTraits<X4>::ForwardType,
- typename internal::ParamTraits<X5>::ForwardType,
- typename internal::ParamTraits<X6>::ForwardType);
-
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X3>::ForwardType x3,
- typename internal::ParamTraits<X4>::ForwardType x4,
- typename internal::ParamTraits<X5>::ForwardType x5,
- typename internal::ParamTraits<X6>::ForwardType x6) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3, x4, x5,
- x6);
- }
-};
-
-// Method: Arity 5 -> 4.
-template <typename StorageType, typename R, typename T, typename X1,
- typename X2, typename X3, typename X4, typename X5>
-struct Invoker2<false, StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X2>::ForwardType,
- typename internal::ParamTraits<X3>::ForwardType,
- typename internal::ParamTraits<X4>::ForwardType,
- typename internal::ParamTraits<X5>::ForwardType);
-
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X2>::ForwardType x2,
- typename internal::ParamTraits<X3>::ForwardType x3,
- typename internal::ParamTraits<X4>::ForwardType x4,
- typename internal::ParamTraits<X5>::ForwardType x5) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2, x3,
- x4, x5);
- }
-};
-
-// WeakPtr Method: Arity 5 -> 4.
-template <typename StorageType, typename T, typename X1, typename X2,
- typename X3, typename X4, typename X5>
-struct Invoker2<true, StorageType, void(T::*)(X1, X2, X3, X4, X5)> {
- typedef void(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X2>::ForwardType,
- typename internal::ParamTraits<X3>::ForwardType,
- typename internal::ParamTraits<X4>::ForwardType,
- typename internal::ParamTraits<X5>::ForwardType);
-
- static void DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X2>::ForwardType x2,
- typename internal::ParamTraits<X3>::ForwardType x3,
- typename internal::ParamTraits<X4>::ForwardType x4,
- typename internal::ParamTraits<X5>::ForwardType x5) {
- StorageType* invoker = static_cast<StorageType*>(base);
- typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
- if (!weak_ptr.get()) {
- return;
- }
- (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), x2, x3, x4, x5);
+ runnable.Run(a1, a2, a3, a4);
}
};
-template <bool IsWeak, typename StorageType, typename NormalizedSig>
-struct Invoker3;
-
-// Function: Arity 3 -> 0.
-template <typename StorageType, typename R,typename X1, typename X2,
- typename X3>
-struct Invoker3<false, StorageType, R(*)(X1, X2, X3)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*);
-
- static R DoInvoke(InvokerStorageBase* base) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
- Unwrap(invoker->p3_));
+template <typename ReturnType, typename Runnable,typename A1, typename A2,
+ typename A3, typename A4, typename A5>
+struct InvokeHelper<false, ReturnType, Runnable,
+ void(A1, A2, A3, A4, A5)> {
+ static ReturnType MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4,
+ A5 a5) {
+ return runnable.Run(a1, a2, a3, a4, a5);
}
};
-// Method: Arity 2 -> 0.
-template <typename StorageType, typename R, typename T, typename X1,
- typename X2>
-struct Invoker3<false, StorageType, R(T::*)(X1, X2)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*);
-
- static R DoInvoke(InvokerStorageBase* base) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
- Unwrap(invoker->p3_));
+template <typename Runnable,typename A1, typename A2, typename A3, typename A4,
+ typename A5>
+struct InvokeHelper<false, void, Runnable,
+ void(A1, A2, A3, A4, A5)> {
+ static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
+ runnable.Run(a1, a2, a3, a4, a5);
}
};
-// WeakPtr Method: Arity 2 -> 0.
-template <typename StorageType, typename T, typename X1, typename X2>
-struct Invoker3<true, StorageType, void(T::*)(X1, X2)> {
- typedef void(*DoInvokeType)(
- internal::InvokerStorageBase*);
-
- static void DoInvoke(InvokerStorageBase* base) {
- StorageType* invoker = static_cast<StorageType*>(base);
- typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
- if (!weak_ptr.get()) {
+template <typename Runnable, typename A1, typename A2, typename A3,
+ typename A4, typename A5>
+struct InvokeHelper<true, void, Runnable,
+ void(A1, A2, A3, A4, A5)> {
+ static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
+ if (!a1.get()) {
return;
}
- (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_));
+
+ runnable.Run(a1, a2, a3, a4, a5);
}
};
-// Function: Arity 4 -> 1.
-template <typename StorageType, typename R,typename X1, typename X2,
- typename X3, typename X4>
-struct Invoker3<false, StorageType, R(*)(X1, X2, X3, X4)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X4>::ForwardType);
-
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X4>::ForwardType x4) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
- Unwrap(invoker->p3_), x4);
+template <typename ReturnType, typename Runnable,typename A1, typename A2,
+ typename A3, typename A4, typename A5, typename A6>
+struct InvokeHelper<false, ReturnType, Runnable,
+ void(A1, A2, A3, A4, A5, A6)> {
+ static ReturnType MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4,
+ A5 a5, A6 a6) {
+ return runnable.Run(a1, a2, a3, a4, a5, a6);
}
};
-// Method: Arity 3 -> 1.
-template <typename StorageType, typename R, typename T, typename X1,
- typename X2, typename X3>
-struct Invoker3<false, StorageType, R(T::*)(X1, X2, X3)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X3>::ForwardType);
-
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X3>::ForwardType x3) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
- Unwrap(invoker->p3_), x3);
+template <typename Runnable,typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6>
+struct InvokeHelper<false, void, Runnable,
+ void(A1, A2, A3, A4, A5, A6)> {
+ static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5,
+ A6 a6) {
+ runnable.Run(a1, a2, a3, a4, a5, a6);
}
};
-// WeakPtr Method: Arity 3 -> 1.
-template <typename StorageType, typename T, typename X1, typename X2,
- typename X3>
-struct Invoker3<true, StorageType, void(T::*)(X1, X2, X3)> {
- typedef void(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X3>::ForwardType);
-
- static void DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X3>::ForwardType x3) {
- StorageType* invoker = static_cast<StorageType*>(base);
- typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
- if (!weak_ptr.get()) {
+template <typename Runnable, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6>
+struct InvokeHelper<true, void, Runnable,
+ void(A1, A2, A3, A4, A5, A6)> {
+ static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5,
+ A6 a6) {
+ if (!a1.get()) {
return;
}
- (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_), x3);
- }
-};
-
-// Function: Arity 5 -> 2.
-template <typename StorageType, typename R,typename X1, typename X2,
- typename X3, typename X4, typename X5>
-struct Invoker3<false, StorageType, R(*)(X1, X2, X3, X4, X5)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X4>::ForwardType,
- typename internal::ParamTraits<X5>::ForwardType);
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X4>::ForwardType x4,
- typename internal::ParamTraits<X5>::ForwardType x5) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
- Unwrap(invoker->p3_), x4, x5);
+ runnable.Run(a1, a2, a3, a4, a5, a6);
}
};
-// Method: Arity 4 -> 2.
-template <typename StorageType, typename R, typename T, typename X1,
- typename X2, typename X3, typename X4>
-struct Invoker3<false, StorageType, R(T::*)(X1, X2, X3, X4)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X3>::ForwardType,
- typename internal::ParamTraits<X4>::ForwardType);
+#if !defined(_MSC_VER)
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X3>::ForwardType x3,
- typename internal::ParamTraits<X4>::ForwardType x4) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
- Unwrap(invoker->p3_), x3, x4);
- }
+template <typename ReturnType, typename Runnable, typename ArgsType>
+struct InvokeHelper<true, ReturnType, Runnable, ArgsType> {
+ // WeakCalls are only supported for functions with a void return type.
+ // Otherwise, the function result would be undefined if the the WeakPtr<>
+ // is invalidated.
+ COMPILE_ASSERT(is_void<ReturnType>::value,
+ weak_ptrs_can_only_bind_to_methods_without_return_values);
};
-// WeakPtr Method: Arity 4 -> 2.
-template <typename StorageType, typename T, typename X1, typename X2,
- typename X3, typename X4>
-struct Invoker3<true, StorageType, void(T::*)(X1, X2, X3, X4)> {
- typedef void(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X3>::ForwardType,
- typename internal::ParamTraits<X4>::ForwardType);
-
- static void DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X3>::ForwardType x3,
- typename internal::ParamTraits<X4>::ForwardType x4) {
- StorageType* invoker = static_cast<StorageType*>(base);
- typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
- if (!weak_ptr.get()) {
- return;
- }
- (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_), x3,
- x4);
- }
-};
+#endif
-// Function: Arity 6 -> 3.
-template <typename StorageType, typename R,typename X1, typename X2,
- typename X3, typename X4, typename X5, typename X6>
-struct Invoker3<false, StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X4>::ForwardType,
- typename internal::ParamTraits<X5>::ForwardType,
- typename internal::ParamTraits<X6>::ForwardType);
-
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X4>::ForwardType x4,
- typename internal::ParamTraits<X5>::ForwardType x5,
- typename internal::ParamTraits<X6>::ForwardType x6) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
- Unwrap(invoker->p3_), x4, x5, x6);
- }
-};
-
-// Method: Arity 5 -> 3.
-template <typename StorageType, typename R, typename T, typename X1,
- typename X2, typename X3, typename X4, typename X5>
-struct Invoker3<false, StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X3>::ForwardType,
- typename internal::ParamTraits<X4>::ForwardType,
- typename internal::ParamTraits<X5>::ForwardType);
-
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X3>::ForwardType x3,
- typename internal::ParamTraits<X4>::ForwardType x4,
- typename internal::ParamTraits<X5>::ForwardType x5) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
- Unwrap(invoker->p3_), x3, x4, x5);
- }
-};
-
-// WeakPtr Method: Arity 5 -> 3.
-template <typename StorageType, typename T, typename X1, typename X2,
- typename X3, typename X4, typename X5>
-struct Invoker3<true, StorageType, void(T::*)(X1, X2, X3, X4, X5)> {
- typedef void(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X3>::ForwardType,
- typename internal::ParamTraits<X4>::ForwardType,
- typename internal::ParamTraits<X5>::ForwardType);
-
- static void DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X3>::ForwardType x3,
- typename internal::ParamTraits<X4>::ForwardType x4,
- typename internal::ParamTraits<X5>::ForwardType x5) {
- StorageType* invoker = static_cast<StorageType*>(base);
- typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
- if (!weak_ptr.get()) {
- return;
- }
- (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_), x3,
- x4, x5);
- }
-};
+// Invoker<>
+//
+// See description at the top of the file.
+template <int NumBound, typename Storage, typename RunType>
+struct Invoker;
-template <bool IsWeak, typename StorageType, typename NormalizedSig>
-struct Invoker4;
+// Arity 0 -> 0.
+template <typename StorageType, typename R>
+struct Invoker<0, StorageType, R()> {
+ typedef R(RunType)(BindStateBase*);
-// Function: Arity 4 -> 0.
-template <typename StorageType, typename R,typename X1, typename X2,
- typename X3, typename X4>
-struct Invoker4<false, StorageType, R(*)(X1, X2, X3, X4)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*);
+ typedef R(UnboundRunType)();
- static R DoInvoke(InvokerStorageBase* base) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
- Unwrap(invoker->p3_), Unwrap(invoker->p4_));
- }
-};
+ static R Run(BindStateBase* base) {
+ StorageType* storage = static_cast<StorageType*>(base);
-// Method: Arity 3 -> 0.
-template <typename StorageType, typename R, typename T, typename X1,
- typename X2, typename X3>
-struct Invoker4<false, StorageType, R(T::*)(X1, X2, X3)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*);
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
- static R DoInvoke(InvokerStorageBase* base) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
- Unwrap(invoker->p3_), Unwrap(invoker->p4_));
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void()>
+ ::MakeItSo(storage->runnable_);
}
};
-// WeakPtr Method: Arity 3 -> 0.
-template <typename StorageType, typename T, typename X1, typename X2,
- typename X3>
-struct Invoker4<true, StorageType, void(T::*)(X1, X2, X3)> {
- typedef void(*DoInvokeType)(
- internal::InvokerStorageBase*);
-
- static void DoInvoke(InvokerStorageBase* base) {
- StorageType* invoker = static_cast<StorageType*>(base);
- typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
- if (!weak_ptr.get()) {
- return;
- }
- (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_),
- Unwrap(invoker->p4_));
- }
-};
+// Arity 1 -> 1.
+template <typename StorageType, typename R,typename X1>
+struct Invoker<0, StorageType, R(X1)> {
+ typedef R(RunType)(BindStateBase*,
+ typename CallbackParamTraits<X1>::ForwardType);
-// Function: Arity 5 -> 1.
-template <typename StorageType, typename R,typename X1, typename X2,
- typename X3, typename X4, typename X5>
-struct Invoker4<false, StorageType, R(*)(X1, X2, X3, X4, X5)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X5>::ForwardType);
+ typedef R(UnboundRunType)(X1);
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X5>::ForwardType x5) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
- Unwrap(invoker->p3_), Unwrap(invoker->p4_), x5);
- }
-};
+ static R Run(BindStateBase* base,
+ typename CallbackParamTraits<X1>::ForwardType x1) {
+ StorageType* storage = static_cast<StorageType*>(base);
-// Method: Arity 4 -> 1.
-template <typename StorageType, typename R, typename T, typename X1,
- typename X2, typename X3, typename X4>
-struct Invoker4<false, StorageType, R(T::*)(X1, X2, X3, X4)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X4>::ForwardType);
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X4>::ForwardType x4) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
- Unwrap(invoker->p3_), Unwrap(invoker->p4_), x4);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename CallbackParamTraits<X1>::ForwardType x1)>
+ ::MakeItSo(storage->runnable_, x1);
}
};
-// WeakPtr Method: Arity 4 -> 1.
-template <typename StorageType, typename T, typename X1, typename X2,
- typename X3, typename X4>
-struct Invoker4<true, StorageType, void(T::*)(X1, X2, X3, X4)> {
- typedef void(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X4>::ForwardType);
-
- static void DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X4>::ForwardType x4) {
- StorageType* invoker = static_cast<StorageType*>(base);
- typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
- if (!weak_ptr.get()) {
- return;
- }
- (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_),
- Unwrap(invoker->p4_), x4);
- }
-};
+// Arity 1 -> 0.
+template <typename StorageType, typename R,typename X1>
+struct Invoker<1, StorageType, R(X1)> {
+ typedef R(RunType)(BindStateBase*);
-// Function: Arity 6 -> 2.
-template <typename StorageType, typename R,typename X1, typename X2,
- typename X3, typename X4, typename X5, typename X6>
-struct Invoker4<false, StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X5>::ForwardType,
- typename internal::ParamTraits<X6>::ForwardType);
+ typedef R(UnboundRunType)();
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X5>::ForwardType x5,
- typename internal::ParamTraits<X6>::ForwardType x6) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
- Unwrap(invoker->p3_), Unwrap(invoker->p4_), x5, x6);
- }
-};
+ static R Run(BindStateBase* base) {
+ StorageType* storage = static_cast<StorageType*>(base);
-// Method: Arity 5 -> 2.
-template <typename StorageType, typename R, typename T, typename X1,
- typename X2, typename X3, typename X4, typename X5>
-struct Invoker4<false, StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X4>::ForwardType,
- typename internal::ParamTraits<X5>::ForwardType);
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+ typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X4>::ForwardType x4,
- typename internal::ParamTraits<X5>::ForwardType x5) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
- Unwrap(invoker->p3_), Unwrap(invoker->p4_), x4, x5);
+ typename Bound1UnwrapTraits::ForwardType x1 =
+ Bound1UnwrapTraits::Unwrap(storage->p1_);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename Bound1UnwrapTraits::ForwardType)>
+ ::MakeItSo(storage->runnable_, x1);
}
};
-// WeakPtr Method: Arity 5 -> 2.
-template <typename StorageType, typename T, typename X1, typename X2,
- typename X3, typename X4, typename X5>
-struct Invoker4<true, StorageType, void(T::*)(X1, X2, X3, X4, X5)> {
- typedef void(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X4>::ForwardType,
- typename internal::ParamTraits<X5>::ForwardType);
-
- static void DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X4>::ForwardType x4,
- typename internal::ParamTraits<X5>::ForwardType x5) {
- StorageType* invoker = static_cast<StorageType*>(base);
- typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
- if (!weak_ptr.get()) {
- return;
- }
- (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_),
- Unwrap(invoker->p4_), x4, x5);
- }
-};
+// Arity 2 -> 2.
+template <typename StorageType, typename R,typename X1, typename X2>
+struct Invoker<0, StorageType, R(X1, X2)> {
+ typedef R(RunType)(BindStateBase*,
+ typename CallbackParamTraits<X1>::ForwardType,
+ typename CallbackParamTraits<X2>::ForwardType);
-template <bool IsWeak, typename StorageType, typename NormalizedSig>
-struct Invoker5;
+ typedef R(UnboundRunType)(X1, X2);
-// Function: Arity 5 -> 0.
-template <typename StorageType, typename R,typename X1, typename X2,
- typename X3, typename X4, typename X5>
-struct Invoker5<false, StorageType, R(*)(X1, X2, X3, X4, X5)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*);
+ static R Run(BindStateBase* base,
+ typename CallbackParamTraits<X1>::ForwardType x1,
+ typename CallbackParamTraits<X2>::ForwardType x2) {
+ StorageType* storage = static_cast<StorageType*>(base);
+
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
- static R DoInvoke(InvokerStorageBase* base) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
- Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_));
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename CallbackParamTraits<X1>::ForwardType x1,
+ typename CallbackParamTraits<X2>::ForwardType x2)>
+ ::MakeItSo(storage->runnable_, x1, x2);
}
};
-// Method: Arity 4 -> 0.
-template <typename StorageType, typename R, typename T, typename X1,
- typename X2, typename X3, typename X4>
-struct Invoker5<false, StorageType, R(T::*)(X1, X2, X3, X4)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*);
+// Arity 2 -> 1.
+template <typename StorageType, typename R,typename X1, typename X2>
+struct Invoker<1, StorageType, R(X1, X2)> {
+ typedef R(RunType)(BindStateBase*,
+ typename CallbackParamTraits<X2>::ForwardType);
- static R DoInvoke(InvokerStorageBase* base) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
- Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_));
- }
-};
+ typedef R(UnboundRunType)(X2);
-// WeakPtr Method: Arity 4 -> 0.
-template <typename StorageType, typename T, typename X1, typename X2,
- typename X3, typename X4>
-struct Invoker5<true, StorageType, void(T::*)(X1, X2, X3, X4)> {
- typedef void(*DoInvokeType)(
- internal::InvokerStorageBase*);
-
- static void DoInvoke(InvokerStorageBase* base) {
- StorageType* invoker = static_cast<StorageType*>(base);
- typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
- if (!weak_ptr.get()) {
- return;
- }
- (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_),
- Unwrap(invoker->p4_), Unwrap(invoker->p5_));
- }
-};
+ static R Run(BindStateBase* base,
+ typename CallbackParamTraits<X2>::ForwardType x2) {
+ StorageType* storage = static_cast<StorageType*>(base);
-// Function: Arity 6 -> 1.
-template <typename StorageType, typename R,typename X1, typename X2,
- typename X3, typename X4, typename X5, typename X6>
-struct Invoker5<false, StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X6>::ForwardType);
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+ typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X6>::ForwardType x6) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
- Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_), x6);
+ typename Bound1UnwrapTraits::ForwardType x1 =
+ Bound1UnwrapTraits::Unwrap(storage->p1_);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename Bound1UnwrapTraits::ForwardType,
+ typename CallbackParamTraits<X2>::ForwardType x2)>
+ ::MakeItSo(storage->runnable_, x1, x2);
}
};
-// Method: Arity 5 -> 1.
-template <typename StorageType, typename R, typename T, typename X1,
- typename X2, typename X3, typename X4, typename X5>
-struct Invoker5<false, StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X5>::ForwardType);
+// Arity 2 -> 0.
+template <typename StorageType, typename R,typename X1, typename X2>
+struct Invoker<2, StorageType, R(X1, X2)> {
+ typedef R(RunType)(BindStateBase*);
- static R DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X5>::ForwardType x5) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
- Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_), x5);
- }
-};
+ typedef R(UnboundRunType)();
-// WeakPtr Method: Arity 5 -> 1.
-template <typename StorageType, typename T, typename X1, typename X2,
- typename X3, typename X4, typename X5>
-struct Invoker5<true, StorageType, void(T::*)(X1, X2, X3, X4, X5)> {
- typedef void(*DoInvokeType)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<X5>::ForwardType);
-
- static void DoInvoke(InvokerStorageBase* base,
- typename internal::ParamTraits<X5>::ForwardType x5) {
- StorageType* invoker = static_cast<StorageType*>(base);
- typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
- if (!weak_ptr.get()) {
- return;
- }
- (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_),
- Unwrap(invoker->p4_), Unwrap(invoker->p5_), x5);
+ static R Run(BindStateBase* base) {
+ StorageType* storage = static_cast<StorageType*>(base);
+
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+ typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+ typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+
+ typename Bound1UnwrapTraits::ForwardType x1 =
+ Bound1UnwrapTraits::Unwrap(storage->p1_);
+ typename Bound2UnwrapTraits::ForwardType x2 =
+ Bound2UnwrapTraits::Unwrap(storage->p2_);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename Bound1UnwrapTraits::ForwardType,
+ typename Bound2UnwrapTraits::ForwardType)>
+ ::MakeItSo(storage->runnable_, x1, x2);
}
};
-template <bool IsWeak, typename StorageType, typename NormalizedSig>
-struct Invoker6;
-
-// Function: Arity 6 -> 0.
+// Arity 3 -> 3.
template <typename StorageType, typename R,typename X1, typename X2,
- typename X3, typename X4, typename X5, typename X6>
-struct Invoker6<false, StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*);
+ typename X3>
+struct Invoker<0, StorageType, R(X1, X2, X3)> {
+ typedef R(RunType)(BindStateBase*,
+ typename CallbackParamTraits<X1>::ForwardType,
+ typename CallbackParamTraits<X2>::ForwardType,
+ typename CallbackParamTraits<X3>::ForwardType);
- static R DoInvoke(InvokerStorageBase* base) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
- Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_),
- Unwrap(invoker->p6_));
- }
-};
+ typedef R(UnboundRunType)(X1, X2, X3);
-// Method: Arity 5 -> 0.
-template <typename StorageType, typename R, typename T, typename X1,
- typename X2, typename X3, typename X4, typename X5>
-struct Invoker6<false, StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*);
+ static R Run(BindStateBase* base,
+ typename CallbackParamTraits<X1>::ForwardType x1,
+ typename CallbackParamTraits<X2>::ForwardType x2,
+ typename CallbackParamTraits<X3>::ForwardType x3) {
+ StorageType* storage = static_cast<StorageType*>(base);
- static R DoInvoke(InvokerStorageBase* base) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
- Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_),
- Unwrap(invoker->p6_));
- }
-};
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
-// WeakPtr Method: Arity 5 -> 0.
-template <typename StorageType, typename T, typename X1, typename X2,
- typename X3, typename X4, typename X5>
-struct Invoker6<true, StorageType, void(T::*)(X1, X2, X3, X4, X5)> {
- typedef void(*DoInvokeType)(
- internal::InvokerStorageBase*);
-
- static void DoInvoke(InvokerStorageBase* base) {
- StorageType* invoker = static_cast<StorageType*>(base);
- typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
- if (!weak_ptr.get()) {
- return;
- }
- (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_),
- Unwrap(invoker->p4_), Unwrap(invoker->p5_), Unwrap(invoker->p6_));
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename CallbackParamTraits<X1>::ForwardType x1,
+ typename CallbackParamTraits<X2>::ForwardType x2,
+ typename CallbackParamTraits<X3>::ForwardType x3)>
+ ::MakeItSo(storage->runnable_, x1, x2, x3);
}
};
-// BindMoreFuncN<>
-//
-// This set of functions help in fully binding the free parameters in a
-// Callback<>.
-template <typename Sig, typename P1>
-void BindMoreFunc1(const base::Callback<Sig>& callback, const P1& p1) {
- callback.Run(p1);
-}
+// Arity 3 -> 2.
+template <typename StorageType, typename R,typename X1, typename X2,
+ typename X3>
+struct Invoker<1, StorageType, R(X1, X2, X3)> {
+ typedef R(RunType)(BindStateBase*,
+ typename CallbackParamTraits<X2>::ForwardType,
+ typename CallbackParamTraits<X3>::ForwardType);
-template <typename Sig, typename P1, typename P2>
-void BindMoreFunc2(const base::Callback<Sig>& callback, const P1& p1,
- const P2& p2) {
- callback.Run(p1, p2);
-}
+ typedef R(UnboundRunType)(X2, X3);
-template <typename Sig, typename P1, typename P2, typename P3>
-void BindMoreFunc3(const base::Callback<Sig>& callback, const P1& p1,
- const P2& p2, const P3& p3) {
- callback.Run(p1, p2, p3);
-}
+ static R Run(BindStateBase* base,
+ typename CallbackParamTraits<X2>::ForwardType x2,
+ typename CallbackParamTraits<X3>::ForwardType x3) {
+ StorageType* storage = static_cast<StorageType*>(base);
-template <typename Sig, typename P1, typename P2, typename P3, typename P4>
-void BindMoreFunc4(const base::Callback<Sig>& callback, const P1& p1,
- const P2& p2, const P3& p3, const P4& p4) {
- callback.Run(p1, p2, p3, p4);
-}
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+ typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
-template <typename Sig, typename P1, typename P2, typename P3, typename P4,
- typename P5>
-void BindMoreFunc5(const base::Callback<Sig>& callback, const P1& p1,
- const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
- callback.Run(p1, p2, p3, p4, p5);
-}
+ typename Bound1UnwrapTraits::ForwardType x1 =
+ Bound1UnwrapTraits::Unwrap(storage->p1_);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename Bound1UnwrapTraits::ForwardType,
+ typename CallbackParamTraits<X2>::ForwardType x2,
+ typename CallbackParamTraits<X3>::ForwardType x3)>
+ ::MakeItSo(storage->runnable_, x1, x2, x3);
+ }
+};
-template <typename Sig, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6>
-void BindMoreFunc6(const base::Callback<Sig>& callback, const P1& p1,
- const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6) {
- callback.Run(p1, p2, p3, p4, p5, p6);
-}
+// Arity 3 -> 1.
+template <typename StorageType, typename R,typename X1, typename X2,
+ typename X3>
+struct Invoker<2, StorageType, R(X1, X2, X3)> {
+ typedef R(RunType)(BindStateBase*,
+ typename CallbackParamTraits<X3>::ForwardType);
-// InvokerStorageN<>
-//
-// These are the actual storage classes for the Invokers.
-//
-// Though these types are "classes", they are being used as structs with
-// all member variable public. We cannot make it a struct because it inherits
-// from a class which causes a compiler warning. We cannot add a "Run()" method
-// that forwards the unbound arguments because that would require we unwrap the
-// Sig type like in InvokerN above to know the return type, and the arity
-// of Run().
-//
-// An alternate solution would be to merge InvokerN and InvokerStorageN,
-// but the generated code seemed harder to read.
-
-template <typename Sig>
-class InvokerStorage0 : public InvokerStorageBase {
- public:
- typedef InvokerStorage0 StorageType;
- typedef FunctionTraits<Sig> TargetTraits;
- typedef typename TargetTraits::IsMethod IsMethod;
- typedef Sig Signature;
- typedef Invoker0<false, StorageType,
- typename TargetTraits::NormalizedSig> Invoker;
+ typedef R(UnboundRunType)(X3);
+ static R Run(BindStateBase* base,
+ typename CallbackParamTraits<X3>::ForwardType x3) {
+ StorageType* storage = static_cast<StorageType*>(base);
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+ typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+ typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
- InvokerStorage0(Sig f)
- : f_(f) {
+ typename Bound1UnwrapTraits::ForwardType x1 =
+ Bound1UnwrapTraits::Unwrap(storage->p1_);
+ typename Bound2UnwrapTraits::ForwardType x2 =
+ Bound2UnwrapTraits::Unwrap(storage->p2_);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename Bound1UnwrapTraits::ForwardType,
+ typename Bound2UnwrapTraits::ForwardType,
+ typename CallbackParamTraits<X3>::ForwardType x3)>
+ ::MakeItSo(storage->runnable_, x1, x2, x3);
}
-
- virtual ~InvokerStorage0() { }
-
- Sig f_;
};
-template <typename Sig, typename P1>
-class InvokerStorage1 : public InvokerStorageBase {
- public:
- typedef InvokerStorage1 StorageType;
- typedef FunctionTraits<Sig> TargetTraits;
- typedef typename TargetTraits::IsMethod IsMethod;
- typedef Sig Signature;
- typedef ParamTraits<P1> P1Traits;
- typedef Invoker1<IsWeakMethod<IsMethod::value, P1>::value, StorageType,
- typename TargetTraits::NormalizedSig> Invoker;
- COMPILE_ASSERT(!(IsWeakMethod<IsMethod::value, P1>::value) ||
- is_void<typename TargetTraits::Return>::value,
- weak_ptrs_can_only_bind_to_methods_without_return_values);
-
- // For methods, we need to be careful for parameter 1. We skip the
- // scoped_refptr check because the binder itself takes care of this. We also
- // disallow binding of an array as the method's target object.
- COMPILE_ASSERT(IsMethod::value ||
- internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P1>::StorageType>::value == 0,
- p1_is_refcounted_type_and_needs_scoped_refptr);
- COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
- first_bound_argument_to_method_cannot_be_array);
+// Arity 3 -> 0.
+template <typename StorageType, typename R,typename X1, typename X2,
+ typename X3>
+struct Invoker<3, StorageType, R(X1, X2, X3)> {
+ typedef R(RunType)(BindStateBase*);
- // Do not allow binding a non-const reference parameter. Non-const reference
- // parameters are disallowed by the Google style guide. Also, binding a
- // non-const reference parameter can make for subtle bugs because the
- // invoked function will receive a reference to the stored copy of the
- // argument and not the original.
- COMPILE_ASSERT(
- !( is_non_const_reference<typename TargetTraits::B1>::value ),
- do_not_bind_functions_with_nonconst_ref);
+ typedef R(UnboundRunType)();
+ static R Run(BindStateBase* base) {
+ StorageType* storage = static_cast<StorageType*>(base);
- InvokerStorage1(Sig f, const P1& p1)
- : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)) {
- MaybeRefcount<IsMethod, P1>::AddRef(p1_);
- }
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+ typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+ typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+ typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits;
- virtual ~InvokerStorage1() {
- MaybeRefcount<IsMethod, P1>::Release(p1_);
+ typename Bound1UnwrapTraits::ForwardType x1 =
+ Bound1UnwrapTraits::Unwrap(storage->p1_);
+ typename Bound2UnwrapTraits::ForwardType x2 =
+ Bound2UnwrapTraits::Unwrap(storage->p2_);
+ typename Bound3UnwrapTraits::ForwardType x3 =
+ Bound3UnwrapTraits::Unwrap(storage->p3_);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename Bound1UnwrapTraits::ForwardType,
+ typename Bound2UnwrapTraits::ForwardType,
+ typename Bound3UnwrapTraits::ForwardType)>
+ ::MakeItSo(storage->runnable_, x1, x2, x3);
}
-
- Sig f_;
- typename ParamTraits<P1>::StorageType p1_;
};
-template <typename Sig, typename P1, typename P2>
-class InvokerStorage2 : public InvokerStorageBase {
- public:
- typedef InvokerStorage2 StorageType;
- typedef FunctionTraits<Sig> TargetTraits;
- typedef typename TargetTraits::IsMethod IsMethod;
- typedef Sig Signature;
- typedef ParamTraits<P1> P1Traits;
- typedef ParamTraits<P2> P2Traits;
- typedef Invoker2<IsWeakMethod<IsMethod::value, P1>::value, StorageType,
- typename TargetTraits::NormalizedSig> Invoker;
- COMPILE_ASSERT(!(IsWeakMethod<IsMethod::value, P1>::value) ||
- is_void<typename TargetTraits::Return>::value,
- weak_ptrs_can_only_bind_to_methods_without_return_values);
+// Arity 4 -> 4.
+template <typename StorageType, typename R,typename X1, typename X2,
+ typename X3, typename X4>
+struct Invoker<0, StorageType, R(X1, X2, X3, X4)> {
+ typedef R(RunType)(BindStateBase*,
+ typename CallbackParamTraits<X1>::ForwardType,
+ typename CallbackParamTraits<X2>::ForwardType,
+ typename CallbackParamTraits<X3>::ForwardType,
+ typename CallbackParamTraits<X4>::ForwardType);
- // For methods, we need to be careful for parameter 1. We skip the
- // scoped_refptr check because the binder itself takes care of this. We also
- // disallow binding of an array as the method's target object.
- COMPILE_ASSERT(IsMethod::value ||
- internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P1>::StorageType>::value == 0,
- p1_is_refcounted_type_and_needs_scoped_refptr);
- COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
- first_bound_argument_to_method_cannot_be_array);
- COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P2>::StorageType>::value == 0,
- p2_is_refcounted_type_and_needs_scoped_refptr);
+ typedef R(UnboundRunType)(X1, X2, X3, X4);
- // Do not allow binding a non-const reference parameter. Non-const reference
- // parameters are disallowed by the Google style guide. Also, binding a
- // non-const reference parameter can make for subtle bugs because the
- // invoked function will receive a reference to the stored copy of the
- // argument and not the original.
- COMPILE_ASSERT(
- !( is_non_const_reference<typename TargetTraits::B1>::value ||
- is_non_const_reference<typename TargetTraits::B2>::value ),
- do_not_bind_functions_with_nonconst_ref);
+ static R Run(BindStateBase* base,
+ typename CallbackParamTraits<X1>::ForwardType x1,
+ typename CallbackParamTraits<X2>::ForwardType x2,
+ typename CallbackParamTraits<X3>::ForwardType x3,
+ typename CallbackParamTraits<X4>::ForwardType x4) {
+ StorageType* storage = static_cast<StorageType*>(base);
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
- InvokerStorage2(Sig f, const P1& p1, const P2& p2)
- : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)),
- p2_(static_cast<typename ParamTraits<P2>::StorageType>(p2)) {
- MaybeRefcount<IsMethod, P1>::AddRef(p1_);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename CallbackParamTraits<X1>::ForwardType x1,
+ typename CallbackParamTraits<X2>::ForwardType x2,
+ typename CallbackParamTraits<X3>::ForwardType x3,
+ typename CallbackParamTraits<X4>::ForwardType x4)>
+ ::MakeItSo(storage->runnable_, x1, x2, x3, x4);
}
+};
- virtual ~InvokerStorage2() {
- MaybeRefcount<IsMethod, P1>::Release(p1_);
- }
+// Arity 4 -> 3.
+template <typename StorageType, typename R,typename X1, typename X2,
+ typename X3, typename X4>
+struct Invoker<1, StorageType, R(X1, X2, X3, X4)> {
+ typedef R(RunType)(BindStateBase*,
+ typename CallbackParamTraits<X2>::ForwardType,
+ typename CallbackParamTraits<X3>::ForwardType,
+ typename CallbackParamTraits<X4>::ForwardType);
+
+ typedef R(UnboundRunType)(X2, X3, X4);
+
+ static R Run(BindStateBase* base,
+ typename CallbackParamTraits<X2>::ForwardType x2,
+ typename CallbackParamTraits<X3>::ForwardType x3,
+ typename CallbackParamTraits<X4>::ForwardType x4) {
+ StorageType* storage = static_cast<StorageType*>(base);
+
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+ typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+
+ typename Bound1UnwrapTraits::ForwardType x1 =
+ Bound1UnwrapTraits::Unwrap(storage->p1_);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename Bound1UnwrapTraits::ForwardType,
+ typename CallbackParamTraits<X2>::ForwardType x2,
+ typename CallbackParamTraits<X3>::ForwardType x3,
+ typename CallbackParamTraits<X4>::ForwardType x4)>
+ ::MakeItSo(storage->runnable_, x1, x2, x3, x4);
+ }
+};
+
+// Arity 4 -> 2.
+template <typename StorageType, typename R,typename X1, typename X2,
+ typename X3, typename X4>
+struct Invoker<2, StorageType, R(X1, X2, X3, X4)> {
+ typedef R(RunType)(BindStateBase*,
+ typename CallbackParamTraits<X3>::ForwardType,
+ typename CallbackParamTraits<X4>::ForwardType);
+
+ typedef R(UnboundRunType)(X3, X4);
+
+ static R Run(BindStateBase* base,
+ typename CallbackParamTraits<X3>::ForwardType x3,
+ typename CallbackParamTraits<X4>::ForwardType x4) {
+ StorageType* storage = static_cast<StorageType*>(base);
+
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+ typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+ typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+
+ typename Bound1UnwrapTraits::ForwardType x1 =
+ Bound1UnwrapTraits::Unwrap(storage->p1_);
+ typename Bound2UnwrapTraits::ForwardType x2 =
+ Bound2UnwrapTraits::Unwrap(storage->p2_);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename Bound1UnwrapTraits::ForwardType,
+ typename Bound2UnwrapTraits::ForwardType,
+ typename CallbackParamTraits<X3>::ForwardType x3,
+ typename CallbackParamTraits<X4>::ForwardType x4)>
+ ::MakeItSo(storage->runnable_, x1, x2, x3, x4);
+ }
+};
+
+// Arity 4 -> 1.
+template <typename StorageType, typename R,typename X1, typename X2,
+ typename X3, typename X4>
+struct Invoker<3, StorageType, R(X1, X2, X3, X4)> {
+ typedef R(RunType)(BindStateBase*,
+ typename CallbackParamTraits<X4>::ForwardType);
+
+ typedef R(UnboundRunType)(X4);
+
+ static R Run(BindStateBase* base,
+ typename CallbackParamTraits<X4>::ForwardType x4) {
+ StorageType* storage = static_cast<StorageType*>(base);
+
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+ typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+ typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+ typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits;
+
+ typename Bound1UnwrapTraits::ForwardType x1 =
+ Bound1UnwrapTraits::Unwrap(storage->p1_);
+ typename Bound2UnwrapTraits::ForwardType x2 =
+ Bound2UnwrapTraits::Unwrap(storage->p2_);
+ typename Bound3UnwrapTraits::ForwardType x3 =
+ Bound3UnwrapTraits::Unwrap(storage->p3_);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename Bound1UnwrapTraits::ForwardType,
+ typename Bound2UnwrapTraits::ForwardType,
+ typename Bound3UnwrapTraits::ForwardType,
+ typename CallbackParamTraits<X4>::ForwardType x4)>
+ ::MakeItSo(storage->runnable_, x1, x2, x3, x4);
+ }
+};
+
+// Arity 4 -> 0.
+template <typename StorageType, typename R,typename X1, typename X2,
+ typename X3, typename X4>
+struct Invoker<4, StorageType, R(X1, X2, X3, X4)> {
+ typedef R(RunType)(BindStateBase*);
+
+ typedef R(UnboundRunType)();
+
+ static R Run(BindStateBase* base) {
+ StorageType* storage = static_cast<StorageType*>(base);
+
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+ typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+ typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+ typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits;
+ typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits;
+
+ typename Bound1UnwrapTraits::ForwardType x1 =
+ Bound1UnwrapTraits::Unwrap(storage->p1_);
+ typename Bound2UnwrapTraits::ForwardType x2 =
+ Bound2UnwrapTraits::Unwrap(storage->p2_);
+ typename Bound3UnwrapTraits::ForwardType x3 =
+ Bound3UnwrapTraits::Unwrap(storage->p3_);
+ typename Bound4UnwrapTraits::ForwardType x4 =
+ Bound4UnwrapTraits::Unwrap(storage->p4_);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename Bound1UnwrapTraits::ForwardType,
+ typename Bound2UnwrapTraits::ForwardType,
+ typename Bound3UnwrapTraits::ForwardType,
+ typename Bound4UnwrapTraits::ForwardType)>
+ ::MakeItSo(storage->runnable_, x1, x2, x3, x4);
+ }
+};
+
+// Arity 5 -> 5.
+template <typename StorageType, typename R,typename X1, typename X2,
+ typename X3, typename X4, typename X5>
+struct Invoker<0, StorageType, R(X1, X2, X3, X4, X5)> {
+ typedef R(RunType)(BindStateBase*,
+ typename CallbackParamTraits<X1>::ForwardType,
+ typename CallbackParamTraits<X2>::ForwardType,
+ typename CallbackParamTraits<X3>::ForwardType,
+ typename CallbackParamTraits<X4>::ForwardType,
+ typename CallbackParamTraits<X5>::ForwardType);
+
+ typedef R(UnboundRunType)(X1, X2, X3, X4, X5);
+
+ static R Run(BindStateBase* base,
+ typename CallbackParamTraits<X1>::ForwardType x1,
+ typename CallbackParamTraits<X2>::ForwardType x2,
+ typename CallbackParamTraits<X3>::ForwardType x3,
+ typename CallbackParamTraits<X4>::ForwardType x4,
+ typename CallbackParamTraits<X5>::ForwardType x5) {
+ StorageType* storage = static_cast<StorageType*>(base);
+
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename CallbackParamTraits<X1>::ForwardType x1,
+ typename CallbackParamTraits<X2>::ForwardType x2,
+ typename CallbackParamTraits<X3>::ForwardType x3,
+ typename CallbackParamTraits<X4>::ForwardType x4,
+ typename CallbackParamTraits<X5>::ForwardType x5)>
+ ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5);
+ }
+};
+
+// Arity 5 -> 4.
+template <typename StorageType, typename R,typename X1, typename X2,
+ typename X3, typename X4, typename X5>
+struct Invoker<1, StorageType, R(X1, X2, X3, X4, X5)> {
+ typedef R(RunType)(BindStateBase*,
+ typename CallbackParamTraits<X2>::ForwardType,
+ typename CallbackParamTraits<X3>::ForwardType,
+ typename CallbackParamTraits<X4>::ForwardType,
+ typename CallbackParamTraits<X5>::ForwardType);
+
+ typedef R(UnboundRunType)(X2, X3, X4, X5);
+
+ static R Run(BindStateBase* base,
+ typename CallbackParamTraits<X2>::ForwardType x2,
+ typename CallbackParamTraits<X3>::ForwardType x3,
+ typename CallbackParamTraits<X4>::ForwardType x4,
+ typename CallbackParamTraits<X5>::ForwardType x5) {
+ StorageType* storage = static_cast<StorageType*>(base);
+
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+ typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+
+ typename Bound1UnwrapTraits::ForwardType x1 =
+ Bound1UnwrapTraits::Unwrap(storage->p1_);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename Bound1UnwrapTraits::ForwardType,
+ typename CallbackParamTraits<X2>::ForwardType x2,
+ typename CallbackParamTraits<X3>::ForwardType x3,
+ typename CallbackParamTraits<X4>::ForwardType x4,
+ typename CallbackParamTraits<X5>::ForwardType x5)>
+ ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5);
+ }
+};
+
+// Arity 5 -> 3.
+template <typename StorageType, typename R,typename X1, typename X2,
+ typename X3, typename X4, typename X5>
+struct Invoker<2, StorageType, R(X1, X2, X3, X4, X5)> {
+ typedef R(RunType)(BindStateBase*,
+ typename CallbackParamTraits<X3>::ForwardType,
+ typename CallbackParamTraits<X4>::ForwardType,
+ typename CallbackParamTraits<X5>::ForwardType);
+
+ typedef R(UnboundRunType)(X3, X4, X5);
+
+ static R Run(BindStateBase* base,
+ typename CallbackParamTraits<X3>::ForwardType x3,
+ typename CallbackParamTraits<X4>::ForwardType x4,
+ typename CallbackParamTraits<X5>::ForwardType x5) {
+ StorageType* storage = static_cast<StorageType*>(base);
+
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+ typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+ typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+
+ typename Bound1UnwrapTraits::ForwardType x1 =
+ Bound1UnwrapTraits::Unwrap(storage->p1_);
+ typename Bound2UnwrapTraits::ForwardType x2 =
+ Bound2UnwrapTraits::Unwrap(storage->p2_);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename Bound1UnwrapTraits::ForwardType,
+ typename Bound2UnwrapTraits::ForwardType,
+ typename CallbackParamTraits<X3>::ForwardType x3,
+ typename CallbackParamTraits<X4>::ForwardType x4,
+ typename CallbackParamTraits<X5>::ForwardType x5)>
+ ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5);
+ }
+};
+
+// Arity 5 -> 2.
+template <typename StorageType, typename R,typename X1, typename X2,
+ typename X3, typename X4, typename X5>
+struct Invoker<3, StorageType, R(X1, X2, X3, X4, X5)> {
+ typedef R(RunType)(BindStateBase*,
+ typename CallbackParamTraits<X4>::ForwardType,
+ typename CallbackParamTraits<X5>::ForwardType);
+
+ typedef R(UnboundRunType)(X4, X5);
+
+ static R Run(BindStateBase* base,
+ typename CallbackParamTraits<X4>::ForwardType x4,
+ typename CallbackParamTraits<X5>::ForwardType x5) {
+ StorageType* storage = static_cast<StorageType*>(base);
+
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+ typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+ typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+ typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits;
+
+ typename Bound1UnwrapTraits::ForwardType x1 =
+ Bound1UnwrapTraits::Unwrap(storage->p1_);
+ typename Bound2UnwrapTraits::ForwardType x2 =
+ Bound2UnwrapTraits::Unwrap(storage->p2_);
+ typename Bound3UnwrapTraits::ForwardType x3 =
+ Bound3UnwrapTraits::Unwrap(storage->p3_);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename Bound1UnwrapTraits::ForwardType,
+ typename Bound2UnwrapTraits::ForwardType,
+ typename Bound3UnwrapTraits::ForwardType,
+ typename CallbackParamTraits<X4>::ForwardType x4,
+ typename CallbackParamTraits<X5>::ForwardType x5)>
+ ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5);
+ }
+};
+
+// Arity 5 -> 1.
+template <typename StorageType, typename R,typename X1, typename X2,
+ typename X3, typename X4, typename X5>
+struct Invoker<4, StorageType, R(X1, X2, X3, X4, X5)> {
+ typedef R(RunType)(BindStateBase*,
+ typename CallbackParamTraits<X5>::ForwardType);
+
+ typedef R(UnboundRunType)(X5);
+
+ static R Run(BindStateBase* base,
+ typename CallbackParamTraits<X5>::ForwardType x5) {
+ StorageType* storage = static_cast<StorageType*>(base);
+
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+ typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+ typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+ typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits;
+ typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits;
+
+ typename Bound1UnwrapTraits::ForwardType x1 =
+ Bound1UnwrapTraits::Unwrap(storage->p1_);
+ typename Bound2UnwrapTraits::ForwardType x2 =
+ Bound2UnwrapTraits::Unwrap(storage->p2_);
+ typename Bound3UnwrapTraits::ForwardType x3 =
+ Bound3UnwrapTraits::Unwrap(storage->p3_);
+ typename Bound4UnwrapTraits::ForwardType x4 =
+ Bound4UnwrapTraits::Unwrap(storage->p4_);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename Bound1UnwrapTraits::ForwardType,
+ typename Bound2UnwrapTraits::ForwardType,
+ typename Bound3UnwrapTraits::ForwardType,
+ typename Bound4UnwrapTraits::ForwardType,
+ typename CallbackParamTraits<X5>::ForwardType x5)>
+ ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5);
+ }
+};
+
+// Arity 5 -> 0.
+template <typename StorageType, typename R,typename X1, typename X2,
+ typename X3, typename X4, typename X5>
+struct Invoker<5, StorageType, R(X1, X2, X3, X4, X5)> {
+ typedef R(RunType)(BindStateBase*);
+
+ typedef R(UnboundRunType)();
+
+ static R Run(BindStateBase* base) {
+ StorageType* storage = static_cast<StorageType*>(base);
+
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+ typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+ typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+ typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits;
+ typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits;
+ typedef typename StorageType::Bound5UnwrapTraits Bound5UnwrapTraits;
+
+ typename Bound1UnwrapTraits::ForwardType x1 =
+ Bound1UnwrapTraits::Unwrap(storage->p1_);
+ typename Bound2UnwrapTraits::ForwardType x2 =
+ Bound2UnwrapTraits::Unwrap(storage->p2_);
+ typename Bound3UnwrapTraits::ForwardType x3 =
+ Bound3UnwrapTraits::Unwrap(storage->p3_);
+ typename Bound4UnwrapTraits::ForwardType x4 =
+ Bound4UnwrapTraits::Unwrap(storage->p4_);
+ typename Bound5UnwrapTraits::ForwardType x5 =
+ Bound5UnwrapTraits::Unwrap(storage->p5_);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename Bound1UnwrapTraits::ForwardType,
+ typename Bound2UnwrapTraits::ForwardType,
+ typename Bound3UnwrapTraits::ForwardType,
+ typename Bound4UnwrapTraits::ForwardType,
+ typename Bound5UnwrapTraits::ForwardType)>
+ ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5);
+ }
+};
+
+// Arity 6 -> 6.
+template <typename StorageType, typename R,typename X1, typename X2,
+ typename X3, typename X4, typename X5, typename X6>
+struct Invoker<0, StorageType, R(X1, X2, X3, X4, X5, X6)> {
+ typedef R(RunType)(BindStateBase*,
+ typename CallbackParamTraits<X1>::ForwardType,
+ typename CallbackParamTraits<X2>::ForwardType,
+ typename CallbackParamTraits<X3>::ForwardType,
+ typename CallbackParamTraits<X4>::ForwardType,
+ typename CallbackParamTraits<X5>::ForwardType,
+ typename CallbackParamTraits<X6>::ForwardType);
+
+ typedef R(UnboundRunType)(X1, X2, X3, X4, X5, X6);
+
+ static R Run(BindStateBase* base,
+ typename CallbackParamTraits<X1>::ForwardType x1,
+ typename CallbackParamTraits<X2>::ForwardType x2,
+ typename CallbackParamTraits<X3>::ForwardType x3,
+ typename CallbackParamTraits<X4>::ForwardType x4,
+ typename CallbackParamTraits<X5>::ForwardType x5,
+ typename CallbackParamTraits<X6>::ForwardType x6) {
+ StorageType* storage = static_cast<StorageType*>(base);
+
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename CallbackParamTraits<X1>::ForwardType x1,
+ typename CallbackParamTraits<X2>::ForwardType x2,
+ typename CallbackParamTraits<X3>::ForwardType x3,
+ typename CallbackParamTraits<X4>::ForwardType x4,
+ typename CallbackParamTraits<X5>::ForwardType x5,
+ typename CallbackParamTraits<X6>::ForwardType x6)>
+ ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6);
+ }
+};
+
+// Arity 6 -> 5.
+template <typename StorageType, typename R,typename X1, typename X2,
+ typename X3, typename X4, typename X5, typename X6>
+struct Invoker<1, StorageType, R(X1, X2, X3, X4, X5, X6)> {
+ typedef R(RunType)(BindStateBase*,
+ typename CallbackParamTraits<X2>::ForwardType,
+ typename CallbackParamTraits<X3>::ForwardType,
+ typename CallbackParamTraits<X4>::ForwardType,
+ typename CallbackParamTraits<X5>::ForwardType,
+ typename CallbackParamTraits<X6>::ForwardType);
+
+ typedef R(UnboundRunType)(X2, X3, X4, X5, X6);
+
+ static R Run(BindStateBase* base,
+ typename CallbackParamTraits<X2>::ForwardType x2,
+ typename CallbackParamTraits<X3>::ForwardType x3,
+ typename CallbackParamTraits<X4>::ForwardType x4,
+ typename CallbackParamTraits<X5>::ForwardType x5,
+ typename CallbackParamTraits<X6>::ForwardType x6) {
+ StorageType* storage = static_cast<StorageType*>(base);
+
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+ typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+
+ typename Bound1UnwrapTraits::ForwardType x1 =
+ Bound1UnwrapTraits::Unwrap(storage->p1_);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename Bound1UnwrapTraits::ForwardType,
+ typename CallbackParamTraits<X2>::ForwardType x2,
+ typename CallbackParamTraits<X3>::ForwardType x3,
+ typename CallbackParamTraits<X4>::ForwardType x4,
+ typename CallbackParamTraits<X5>::ForwardType x5,
+ typename CallbackParamTraits<X6>::ForwardType x6)>
+ ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6);
+ }
+};
+
+// Arity 6 -> 4.
+template <typename StorageType, typename R,typename X1, typename X2,
+ typename X3, typename X4, typename X5, typename X6>
+struct Invoker<2, StorageType, R(X1, X2, X3, X4, X5, X6)> {
+ typedef R(RunType)(BindStateBase*,
+ typename CallbackParamTraits<X3>::ForwardType,
+ typename CallbackParamTraits<X4>::ForwardType,
+ typename CallbackParamTraits<X5>::ForwardType,
+ typename CallbackParamTraits<X6>::ForwardType);
+
+ typedef R(UnboundRunType)(X3, X4, X5, X6);
+
+ static R Run(BindStateBase* base,
+ typename CallbackParamTraits<X3>::ForwardType x3,
+ typename CallbackParamTraits<X4>::ForwardType x4,
+ typename CallbackParamTraits<X5>::ForwardType x5,
+ typename CallbackParamTraits<X6>::ForwardType x6) {
+ StorageType* storage = static_cast<StorageType*>(base);
+
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+ typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+ typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+
+ typename Bound1UnwrapTraits::ForwardType x1 =
+ Bound1UnwrapTraits::Unwrap(storage->p1_);
+ typename Bound2UnwrapTraits::ForwardType x2 =
+ Bound2UnwrapTraits::Unwrap(storage->p2_);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename Bound1UnwrapTraits::ForwardType,
+ typename Bound2UnwrapTraits::ForwardType,
+ typename CallbackParamTraits<X3>::ForwardType x3,
+ typename CallbackParamTraits<X4>::ForwardType x4,
+ typename CallbackParamTraits<X5>::ForwardType x5,
+ typename CallbackParamTraits<X6>::ForwardType x6)>
+ ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6);
+ }
+};
+
+// Arity 6 -> 3.
+template <typename StorageType, typename R,typename X1, typename X2,
+ typename X3, typename X4, typename X5, typename X6>
+struct Invoker<3, StorageType, R(X1, X2, X3, X4, X5, X6)> {
+ typedef R(RunType)(BindStateBase*,
+ typename CallbackParamTraits<X4>::ForwardType,
+ typename CallbackParamTraits<X5>::ForwardType,
+ typename CallbackParamTraits<X6>::ForwardType);
+
+ typedef R(UnboundRunType)(X4, X5, X6);
+
+ static R Run(BindStateBase* base,
+ typename CallbackParamTraits<X4>::ForwardType x4,
+ typename CallbackParamTraits<X5>::ForwardType x5,
+ typename CallbackParamTraits<X6>::ForwardType x6) {
+ StorageType* storage = static_cast<StorageType*>(base);
+
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+ typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+ typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+ typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits;
+
+ typename Bound1UnwrapTraits::ForwardType x1 =
+ Bound1UnwrapTraits::Unwrap(storage->p1_);
+ typename Bound2UnwrapTraits::ForwardType x2 =
+ Bound2UnwrapTraits::Unwrap(storage->p2_);
+ typename Bound3UnwrapTraits::ForwardType x3 =
+ Bound3UnwrapTraits::Unwrap(storage->p3_);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename Bound1UnwrapTraits::ForwardType,
+ typename Bound2UnwrapTraits::ForwardType,
+ typename Bound3UnwrapTraits::ForwardType,
+ typename CallbackParamTraits<X4>::ForwardType x4,
+ typename CallbackParamTraits<X5>::ForwardType x5,
+ typename CallbackParamTraits<X6>::ForwardType x6)>
+ ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6);
+ }
+};
+
+// Arity 6 -> 2.
+template <typename StorageType, typename R,typename X1, typename X2,
+ typename X3, typename X4, typename X5, typename X6>
+struct Invoker<4, StorageType, R(X1, X2, X3, X4, X5, X6)> {
+ typedef R(RunType)(BindStateBase*,
+ typename CallbackParamTraits<X5>::ForwardType,
+ typename CallbackParamTraits<X6>::ForwardType);
+
+ typedef R(UnboundRunType)(X5, X6);
+
+ static R Run(BindStateBase* base,
+ typename CallbackParamTraits<X5>::ForwardType x5,
+ typename CallbackParamTraits<X6>::ForwardType x6) {
+ StorageType* storage = static_cast<StorageType*>(base);
+
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+ typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+ typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+ typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits;
+ typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits;
+
+ typename Bound1UnwrapTraits::ForwardType x1 =
+ Bound1UnwrapTraits::Unwrap(storage->p1_);
+ typename Bound2UnwrapTraits::ForwardType x2 =
+ Bound2UnwrapTraits::Unwrap(storage->p2_);
+ typename Bound3UnwrapTraits::ForwardType x3 =
+ Bound3UnwrapTraits::Unwrap(storage->p3_);
+ typename Bound4UnwrapTraits::ForwardType x4 =
+ Bound4UnwrapTraits::Unwrap(storage->p4_);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename Bound1UnwrapTraits::ForwardType,
+ typename Bound2UnwrapTraits::ForwardType,
+ typename Bound3UnwrapTraits::ForwardType,
+ typename Bound4UnwrapTraits::ForwardType,
+ typename CallbackParamTraits<X5>::ForwardType x5,
+ typename CallbackParamTraits<X6>::ForwardType x6)>
+ ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6);
+ }
+};
+
+// Arity 6 -> 1.
+template <typename StorageType, typename R,typename X1, typename X2,
+ typename X3, typename X4, typename X5, typename X6>
+struct Invoker<5, StorageType, R(X1, X2, X3, X4, X5, X6)> {
+ typedef R(RunType)(BindStateBase*,
+ typename CallbackParamTraits<X6>::ForwardType);
+
+ typedef R(UnboundRunType)(X6);
+
+ static R Run(BindStateBase* base,
+ typename CallbackParamTraits<X6>::ForwardType x6) {
+ StorageType* storage = static_cast<StorageType*>(base);
+
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+ typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+ typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+ typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits;
+ typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits;
+ typedef typename StorageType::Bound5UnwrapTraits Bound5UnwrapTraits;
+
+ typename Bound1UnwrapTraits::ForwardType x1 =
+ Bound1UnwrapTraits::Unwrap(storage->p1_);
+ typename Bound2UnwrapTraits::ForwardType x2 =
+ Bound2UnwrapTraits::Unwrap(storage->p2_);
+ typename Bound3UnwrapTraits::ForwardType x3 =
+ Bound3UnwrapTraits::Unwrap(storage->p3_);
+ typename Bound4UnwrapTraits::ForwardType x4 =
+ Bound4UnwrapTraits::Unwrap(storage->p4_);
+ typename Bound5UnwrapTraits::ForwardType x5 =
+ Bound5UnwrapTraits::Unwrap(storage->p5_);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename Bound1UnwrapTraits::ForwardType,
+ typename Bound2UnwrapTraits::ForwardType,
+ typename Bound3UnwrapTraits::ForwardType,
+ typename Bound4UnwrapTraits::ForwardType,
+ typename Bound5UnwrapTraits::ForwardType,
+ typename CallbackParamTraits<X6>::ForwardType x6)>
+ ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6);
+ }
+};
+
+// Arity 6 -> 0.
+template <typename StorageType, typename R,typename X1, typename X2,
+ typename X3, typename X4, typename X5, typename X6>
+struct Invoker<6, StorageType, R(X1, X2, X3, X4, X5, X6)> {
+ typedef R(RunType)(BindStateBase*);
+
+ typedef R(UnboundRunType)();
+
+ static R Run(BindStateBase* base) {
+ StorageType* storage = static_cast<StorageType*>(base);
+
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+ typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+ typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+ typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits;
+ typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits;
+ typedef typename StorageType::Bound5UnwrapTraits Bound5UnwrapTraits;
+ typedef typename StorageType::Bound6UnwrapTraits Bound6UnwrapTraits;
+
+ typename Bound1UnwrapTraits::ForwardType x1 =
+ Bound1UnwrapTraits::Unwrap(storage->p1_);
+ typename Bound2UnwrapTraits::ForwardType x2 =
+ Bound2UnwrapTraits::Unwrap(storage->p2_);
+ typename Bound3UnwrapTraits::ForwardType x3 =
+ Bound3UnwrapTraits::Unwrap(storage->p3_);
+ typename Bound4UnwrapTraits::ForwardType x4 =
+ Bound4UnwrapTraits::Unwrap(storage->p4_);
+ typename Bound5UnwrapTraits::ForwardType x5 =
+ Bound5UnwrapTraits::Unwrap(storage->p5_);
+ typename Bound6UnwrapTraits::ForwardType x6 =
+ Bound6UnwrapTraits::Unwrap(storage->p6_);
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(typename Bound1UnwrapTraits::ForwardType,
+ typename Bound2UnwrapTraits::ForwardType,
+ typename Bound3UnwrapTraits::ForwardType,
+ typename Bound4UnwrapTraits::ForwardType,
+ typename Bound5UnwrapTraits::ForwardType,
+ typename Bound6UnwrapTraits::ForwardType)>
+ ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6);
+ }
+};
+
+
+// BindState<>
+//
+// This stores all the state passed into Bind() and is also where most
+// of the template resolution magic occurs.
+//
+// Runnable is the functor we are binding arguments to.
+// RunType is type of the Run() function that the Invoker<> should use.
+// Normally, this is the same as the RunType of the Runnable, but it can
+// be different if an adapter like IgnoreResult() has been used.
+//
+// BoundArgsType contains the storage type for all the bound arguments by
+// (ab)using a function type.
+template <typename Runnable, typename RunType, typename BoundArgsType>
+struct BindState;
- Sig f_;
- typename ParamTraits<P1>::StorageType p1_;
- typename ParamTraits<P2>::StorageType p2_;
-};
+template <typename Runnable, typename RunType>
+struct BindState<Runnable, RunType, void()> : public BindStateBase {
+ typedef Runnable RunnableType;
+ typedef false_type IsWeakCall;
+ typedef Invoker<0, BindState, RunType> InvokerType;
+ typedef typename InvokerType::UnboundRunType UnboundRunType;
+ explicit BindState(const Runnable& runnable)
+ : runnable_(runnable) {
+ }
-template <typename Sig, typename P1, typename P2, typename P3>
-class InvokerStorage3 : public InvokerStorageBase {
- public:
- typedef InvokerStorage3 StorageType;
- typedef FunctionTraits<Sig> TargetTraits;
- typedef typename TargetTraits::IsMethod IsMethod;
- typedef Sig Signature;
- typedef ParamTraits<P1> P1Traits;
- typedef ParamTraits<P2> P2Traits;
- typedef ParamTraits<P3> P3Traits;
- typedef Invoker3<IsWeakMethod<IsMethod::value, P1>::value, StorageType,
- typename TargetTraits::NormalizedSig> Invoker;
- COMPILE_ASSERT(!(IsWeakMethod<IsMethod::value, P1>::value) ||
- is_void<typename TargetTraits::Return>::value,
- weak_ptrs_can_only_bind_to_methods_without_return_values);
+ virtual ~BindState() { }
- // For methods, we need to be careful for parameter 1. We skip the
- // scoped_refptr check because the binder itself takes care of this. We also
- // disallow binding of an array as the method's target object.
- COMPILE_ASSERT(IsMethod::value ||
- internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P1>::StorageType>::value == 0,
- p1_is_refcounted_type_and_needs_scoped_refptr);
- COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
- first_bound_argument_to_method_cannot_be_array);
- COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P2>::StorageType>::value == 0,
- p2_is_refcounted_type_and_needs_scoped_refptr);
- COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P3>::StorageType>::value == 0,
- p3_is_refcounted_type_and_needs_scoped_refptr);
-
- // Do not allow binding a non-const reference parameter. Non-const reference
- // parameters are disallowed by the Google style guide. Also, binding a
- // non-const reference parameter can make for subtle bugs because the
- // invoked function will receive a reference to the stored copy of the
- // argument and not the original.
- COMPILE_ASSERT(
- !( is_non_const_reference<typename TargetTraits::B1>::value ||
- is_non_const_reference<typename TargetTraits::B2>::value ||
- is_non_const_reference<typename TargetTraits::B3>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
-
- InvokerStorage3(Sig f, const P1& p1, const P2& p2, const P3& p3)
- : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)),
- p2_(static_cast<typename ParamTraits<P2>::StorageType>(p2)),
- p3_(static_cast<typename ParamTraits<P3>::StorageType>(p3)) {
- MaybeRefcount<IsMethod, P1>::AddRef(p1_);
- }
-
- virtual ~InvokerStorage3() {
- MaybeRefcount<IsMethod, P1>::Release(p1_);
- }
-
- Sig f_;
- typename ParamTraits<P1>::StorageType p1_;
- typename ParamTraits<P2>::StorageType p2_;
- typename ParamTraits<P3>::StorageType p3_;
-};
-
-template <typename Sig, typename P1, typename P2, typename P3, typename P4>
-class InvokerStorage4 : public InvokerStorageBase {
- public:
- typedef InvokerStorage4 StorageType;
- typedef FunctionTraits<Sig> TargetTraits;
- typedef typename TargetTraits::IsMethod IsMethod;
- typedef Sig Signature;
- typedef ParamTraits<P1> P1Traits;
- typedef ParamTraits<P2> P2Traits;
- typedef ParamTraits<P3> P3Traits;
- typedef ParamTraits<P4> P4Traits;
- typedef Invoker4<IsWeakMethod<IsMethod::value, P1>::value, StorageType,
- typename TargetTraits::NormalizedSig> Invoker;
- COMPILE_ASSERT(!(IsWeakMethod<IsMethod::value, P1>::value) ||
- is_void<typename TargetTraits::Return>::value,
- weak_ptrs_can_only_bind_to_methods_without_return_values);
+ RunnableType runnable_;
+};
+
+template <typename Runnable, typename RunType, typename P1>
+struct BindState<Runnable, RunType, void(P1)> : public BindStateBase {
+ typedef Runnable RunnableType;
+ typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall;
+ typedef Invoker<1, BindState, RunType> InvokerType;
+ typedef typename InvokerType::UnboundRunType UnboundRunType;
- // For methods, we need to be careful for parameter 1. We skip the
- // scoped_refptr check because the binder itself takes care of this. We also
- // disallow binding of an array as the method's target object.
- COMPILE_ASSERT(IsMethod::value ||
- internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P1>::StorageType>::value == 0,
- p1_is_refcounted_type_and_needs_scoped_refptr);
- COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
- first_bound_argument_to_method_cannot_be_array);
- COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P2>::StorageType>::value == 0,
- p2_is_refcounted_type_and_needs_scoped_refptr);
- COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P3>::StorageType>::value == 0,
- p3_is_refcounted_type_and_needs_scoped_refptr);
- COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P4>::StorageType>::value == 0,
- p4_is_refcounted_type_and_needs_scoped_refptr);
-
- // Do not allow binding a non-const reference parameter. Non-const reference
- // parameters are disallowed by the Google style guide. Also, binding a
- // non-const reference parameter can make for subtle bugs because the
- // invoked function will receive a reference to the stored copy of the
- // argument and not the original.
- COMPILE_ASSERT(
- !( is_non_const_reference<typename TargetTraits::B1>::value ||
- is_non_const_reference<typename TargetTraits::B2>::value ||
- is_non_const_reference<typename TargetTraits::B3>::value ||
- is_non_const_reference<typename TargetTraits::B4>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
-
- InvokerStorage4(Sig f, const P1& p1, const P2& p2, const P3& p3, const P4& p4)
- : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)),
- p2_(static_cast<typename ParamTraits<P2>::StorageType>(p2)),
- p3_(static_cast<typename ParamTraits<P3>::StorageType>(p3)),
- p4_(static_cast<typename ParamTraits<P4>::StorageType>(p4)) {
- MaybeRefcount<IsMethod, P1>::AddRef(p1_);
- }
-
- virtual ~InvokerStorage4() {
- MaybeRefcount<IsMethod, P1>::Release(p1_);
- }
-
- Sig f_;
- typename ParamTraits<P1>::StorageType p1_;
- typename ParamTraits<P2>::StorageType p2_;
- typename ParamTraits<P3>::StorageType p3_;
- typename ParamTraits<P4>::StorageType p4_;
-};
-
-template <typename Sig, typename P1, typename P2, typename P3, typename P4,
- typename P5>
-class InvokerStorage5 : public InvokerStorageBase {
- public:
- typedef InvokerStorage5 StorageType;
- typedef FunctionTraits<Sig> TargetTraits;
- typedef typename TargetTraits::IsMethod IsMethod;
- typedef Sig Signature;
- typedef ParamTraits<P1> P1Traits;
- typedef ParamTraits<P2> P2Traits;
- typedef ParamTraits<P3> P3Traits;
- typedef ParamTraits<P4> P4Traits;
- typedef ParamTraits<P5> P5Traits;
- typedef Invoker5<IsWeakMethod<IsMethod::value, P1>::value, StorageType,
- typename TargetTraits::NormalizedSig> Invoker;
- COMPILE_ASSERT(!(IsWeakMethod<IsMethod::value, P1>::value) ||
- is_void<typename TargetTraits::Return>::value,
- weak_ptrs_can_only_bind_to_methods_without_return_values);
+ // Convenience typedefs for bound argument types.
+ typedef UnwrapTraits<P1> Bound1UnwrapTraits;
- // For methods, we need to be careful for parameter 1. We skip the
- // scoped_refptr check because the binder itself takes care of this. We also
- // disallow binding of an array as the method's target object.
- COMPILE_ASSERT(IsMethod::value ||
- internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P1>::StorageType>::value == 0,
- p1_is_refcounted_type_and_needs_scoped_refptr);
- COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
- first_bound_argument_to_method_cannot_be_array);
- COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P2>::StorageType>::value == 0,
- p2_is_refcounted_type_and_needs_scoped_refptr);
- COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P3>::StorageType>::value == 0,
- p3_is_refcounted_type_and_needs_scoped_refptr);
- COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P4>::StorageType>::value == 0,
- p4_is_refcounted_type_and_needs_scoped_refptr);
- COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P5>::StorageType>::value == 0,
- p5_is_refcounted_type_and_needs_scoped_refptr);
-
- // Do not allow binding a non-const reference parameter. Non-const reference
- // parameters are disallowed by the Google style guide. Also, binding a
- // non-const reference parameter can make for subtle bugs because the
- // invoked function will receive a reference to the stored copy of the
- // argument and not the original.
- COMPILE_ASSERT(
- !( is_non_const_reference<typename TargetTraits::B1>::value ||
- is_non_const_reference<typename TargetTraits::B2>::value ||
- is_non_const_reference<typename TargetTraits::B3>::value ||
- is_non_const_reference<typename TargetTraits::B4>::value ||
- is_non_const_reference<typename TargetTraits::B5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
-
- InvokerStorage5(Sig f, const P1& p1, const P2& p2, const P3& p3,
- const P4& p4, const P5& p5)
- : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)),
- p2_(static_cast<typename ParamTraits<P2>::StorageType>(p2)),
- p3_(static_cast<typename ParamTraits<P3>::StorageType>(p3)),
- p4_(static_cast<typename ParamTraits<P4>::StorageType>(p4)),
- p5_(static_cast<typename ParamTraits<P5>::StorageType>(p5)) {
- MaybeRefcount<IsMethod, P1>::AddRef(p1_);
+ BindState(const Runnable& runnable, const P1& p1)
+ : runnable_(runnable),
+ p1_(p1) {
+ MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_);
}
- virtual ~InvokerStorage5() {
- MaybeRefcount<IsMethod, P1>::Release(p1_);
- }
+ virtual ~BindState() { MaybeRefcount<HasIsMethodTag<Runnable>::value,
+ P1>::Release(p1_); }
- Sig f_;
- typename ParamTraits<P1>::StorageType p1_;
- typename ParamTraits<P2>::StorageType p2_;
- typename ParamTraits<P3>::StorageType p3_;
- typename ParamTraits<P4>::StorageType p4_;
- typename ParamTraits<P5>::StorageType p5_;
-};
+ RunnableType runnable_;
+ P1 p1_;
+};
-template <typename Sig, typename P1, typename P2, typename P3, typename P4,
- typename P5, typename P6>
-class InvokerStorage6 : public InvokerStorageBase {
- public:
- typedef InvokerStorage6 StorageType;
- typedef FunctionTraits<Sig> TargetTraits;
- typedef typename TargetTraits::IsMethod IsMethod;
- typedef Sig Signature;
- typedef ParamTraits<P1> P1Traits;
- typedef ParamTraits<P2> P2Traits;
- typedef ParamTraits<P3> P3Traits;
- typedef ParamTraits<P4> P4Traits;
- typedef ParamTraits<P5> P5Traits;
- typedef ParamTraits<P6> P6Traits;
- typedef Invoker6<IsWeakMethod<IsMethod::value, P1>::value, StorageType,
- typename TargetTraits::NormalizedSig> Invoker;
- COMPILE_ASSERT(!(IsWeakMethod<IsMethod::value, P1>::value) ||
- is_void<typename TargetTraits::Return>::value,
- weak_ptrs_can_only_bind_to_methods_without_return_values);
+template <typename Runnable, typename RunType, typename P1, typename P2>
+struct BindState<Runnable, RunType, void(P1, P2)> : public BindStateBase {
+ typedef Runnable RunnableType;
+ typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall;
+ typedef Invoker<2, BindState, RunType> InvokerType;
+ typedef typename InvokerType::UnboundRunType UnboundRunType;
+
+ // Convenience typedefs for bound argument types.
+ typedef UnwrapTraits<P1> Bound1UnwrapTraits;
+ typedef UnwrapTraits<P2> Bound2UnwrapTraits;
+
+ BindState(const Runnable& runnable, const P1& p1, const P2& p2)
+ : runnable_(runnable),
+ p1_(p1),
+ p2_(p2) {
+ MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_);
+ }
+
+ virtual ~BindState() { MaybeRefcount<HasIsMethodTag<Runnable>::value,
+ P1>::Release(p1_); }
+
+ RunnableType runnable_;
+ P1 p1_;
+ P2 p2_;
+};
+
+template <typename Runnable, typename RunType, typename P1, typename P2,
+ typename P3>
+struct BindState<Runnable, RunType, void(P1, P2, P3)> : public BindStateBase {
+ typedef Runnable RunnableType;
+ typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall;
+ typedef Invoker<3, BindState, RunType> InvokerType;
+ typedef typename InvokerType::UnboundRunType UnboundRunType;
+
+ // Convenience typedefs for bound argument types.
+ typedef UnwrapTraits<P1> Bound1UnwrapTraits;
+ typedef UnwrapTraits<P2> Bound2UnwrapTraits;
+ typedef UnwrapTraits<P3> Bound3UnwrapTraits;
+
+ BindState(const Runnable& runnable, const P1& p1, const P2& p2, const P3& p3)
+ : runnable_(runnable),
+ p1_(p1),
+ p2_(p2),
+ p3_(p3) {
+ MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_);
+ }
+
+ virtual ~BindState() { MaybeRefcount<HasIsMethodTag<Runnable>::value,
+ P1>::Release(p1_); }
+
+ RunnableType runnable_;
+ P1 p1_;
+ P2 p2_;
+ P3 p3_;
+};
+
+template <typename Runnable, typename RunType, typename P1, typename P2,
+ typename P3, typename P4>
+struct BindState<Runnable, RunType, void(P1, P2, P3,
+ P4)> : public BindStateBase {
+ typedef Runnable RunnableType;
+ typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall;
+ typedef Invoker<4, BindState, RunType> InvokerType;
+ typedef typename InvokerType::UnboundRunType UnboundRunType;
+
+ // Convenience typedefs for bound argument types.
+ typedef UnwrapTraits<P1> Bound1UnwrapTraits;
+ typedef UnwrapTraits<P2> Bound2UnwrapTraits;
+ typedef UnwrapTraits<P3> Bound3UnwrapTraits;
+ typedef UnwrapTraits<P4> Bound4UnwrapTraits;
- // For methods, we need to be careful for parameter 1. We skip the
- // scoped_refptr check because the binder itself takes care of this. We also
- // disallow binding of an array as the method's target object.
- COMPILE_ASSERT(IsMethod::value ||
- internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P1>::StorageType>::value == 0,
- p1_is_refcounted_type_and_needs_scoped_refptr);
- COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
- first_bound_argument_to_method_cannot_be_array);
- COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P2>::StorageType>::value == 0,
- p2_is_refcounted_type_and_needs_scoped_refptr);
- COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P3>::StorageType>::value == 0,
- p3_is_refcounted_type_and_needs_scoped_refptr);
- COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P4>::StorageType>::value == 0,
- p4_is_refcounted_type_and_needs_scoped_refptr);
- COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P5>::StorageType>::value == 0,
- p5_is_refcounted_type_and_needs_scoped_refptr);
- COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P6>::StorageType>::value == 0,
- p6_is_refcounted_type_and_needs_scoped_refptr);
-
- // Do not allow binding a non-const reference parameter. Non-const reference
- // parameters are disallowed by the Google style guide. Also, binding a
- // non-const reference parameter can make for subtle bugs because the
- // invoked function will receive a reference to the stored copy of the
- // argument and not the original.
- COMPILE_ASSERT(
- !( is_non_const_reference<typename TargetTraits::B1>::value ||
- is_non_const_reference<typename TargetTraits::B2>::value ||
- is_non_const_reference<typename TargetTraits::B3>::value ||
- is_non_const_reference<typename TargetTraits::B4>::value ||
- is_non_const_reference<typename TargetTraits::B5>::value ||
- is_non_const_reference<typename TargetTraits::B6>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
-
- InvokerStorage6(Sig f, const P1& p1, const P2& p2, const P3& p3,
+ BindState(const Runnable& runnable, const P1& p1, const P2& p2, const P3& p3,
+ const P4& p4)
+ : runnable_(runnable),
+ p1_(p1),
+ p2_(p2),
+ p3_(p3),
+ p4_(p4) {
+ MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_);
+ }
+
+ virtual ~BindState() { MaybeRefcount<HasIsMethodTag<Runnable>::value,
+ P1>::Release(p1_); }
+
+ RunnableType runnable_;
+ P1 p1_;
+ P2 p2_;
+ P3 p3_;
+ P4 p4_;
+};
+
+template <typename Runnable, typename RunType, typename P1, typename P2,
+ typename P3, typename P4, typename P5>
+struct BindState<Runnable, RunType, void(P1, P2, P3, P4,
+ P5)> : public BindStateBase {
+ typedef Runnable RunnableType;
+ typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall;
+ typedef Invoker<5, BindState, RunType> InvokerType;
+ typedef typename InvokerType::UnboundRunType UnboundRunType;
+
+ // Convenience typedefs for bound argument types.
+ typedef UnwrapTraits<P1> Bound1UnwrapTraits;
+ typedef UnwrapTraits<P2> Bound2UnwrapTraits;
+ typedef UnwrapTraits<P3> Bound3UnwrapTraits;
+ typedef UnwrapTraits<P4> Bound4UnwrapTraits;
+ typedef UnwrapTraits<P5> Bound5UnwrapTraits;
+
+ BindState(const Runnable& runnable, const P1& p1, const P2& p2, const P3& p3,
+ const P4& p4, const P5& p5)
+ : runnable_(runnable),
+ p1_(p1),
+ p2_(p2),
+ p3_(p3),
+ p4_(p4),
+ p5_(p5) {
+ MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_);
+ }
+
+ virtual ~BindState() { MaybeRefcount<HasIsMethodTag<Runnable>::value,
+ P1>::Release(p1_); }
+
+ RunnableType runnable_;
+ P1 p1_;
+ P2 p2_;
+ P3 p3_;
+ P4 p4_;
+ P5 p5_;
+};
+
+template <typename Runnable, typename RunType, typename P1, typename P2,
+ typename P3, typename P4, typename P5, typename P6>
+struct BindState<Runnable, RunType, void(P1, P2, P3, P4, P5,
+ P6)> : public BindStateBase {
+ typedef Runnable RunnableType;
+ typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall;
+ typedef Invoker<6, BindState, RunType> InvokerType;
+ typedef typename InvokerType::UnboundRunType UnboundRunType;
+
+ // Convenience typedefs for bound argument types.
+ typedef UnwrapTraits<P1> Bound1UnwrapTraits;
+ typedef UnwrapTraits<P2> Bound2UnwrapTraits;
+ typedef UnwrapTraits<P3> Bound3UnwrapTraits;
+ typedef UnwrapTraits<P4> Bound4UnwrapTraits;
+ typedef UnwrapTraits<P5> Bound5UnwrapTraits;
+ typedef UnwrapTraits<P6> Bound6UnwrapTraits;
+
+ BindState(const Runnable& runnable, const P1& p1, const P2& p2, const P3& p3,
const P4& p4, const P5& p5, const P6& p6)
- : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)),
- p2_(static_cast<typename ParamTraits<P2>::StorageType>(p2)),
- p3_(static_cast<typename ParamTraits<P3>::StorageType>(p3)),
- p4_(static_cast<typename ParamTraits<P4>::StorageType>(p4)),
- p5_(static_cast<typename ParamTraits<P5>::StorageType>(p5)),
- p6_(static_cast<typename ParamTraits<P6>::StorageType>(p6)) {
- MaybeRefcount<IsMethod, P1>::AddRef(p1_);
- }
-
- virtual ~InvokerStorage6() {
- MaybeRefcount<IsMethod, P1>::Release(p1_);
- }
-
- Sig f_;
- typename ParamTraits<P1>::StorageType p1_;
- typename ParamTraits<P2>::StorageType p2_;
- typename ParamTraits<P3>::StorageType p3_;
- typename ParamTraits<P4>::StorageType p4_;
- typename ParamTraits<P5>::StorageType p5_;
- typename ParamTraits<P6>::StorageType p6_;
+ : runnable_(runnable),
+ p1_(p1),
+ p2_(p2),
+ p3_(p3),
+ p4_(p4),
+ p5_(p5),
+ p6_(p6) {
+ MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_);
+ }
+
+ virtual ~BindState() { MaybeRefcount<HasIsMethodTag<Runnable>::value,
+ P1>::Release(p1_); }
+
+ RunnableType runnable_;
+ P1 p1_;
+ P2 p2_;
+ P3 p3_;
+ P4 p4_;
+ P5 p5_;
+ P6 p6_;
};
} // namespace internal
diff --git a/base/bind_internal.h.pump b/base/bind_internal.h.pump
index 429e13f..1192974 100644
--- a/base/bind_internal.h.pump
+++ b/base/bind_internal.h.pump
@@ -5,7 +5,14 @@ $$
$$ http://code.google.com/p/googletest/wiki/PumpManual
$$
+// TODO(ajwong): If you create an fully unbound method, is there a way to
+// enforce the first argument must be refcounted? Or do we just say
+// "oh well"?
+//
+// Do we want to allow creating a fully unbound method??
+
$var MAX_ARITY = 6
+$range ARITY 0..MAX_ARITY
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -29,371 +36,463 @@ $var MAX_ARITY = 6
namespace base {
namespace internal {
-// The method by which a function is invoked is determined by 3 different
-// dimensions:
+// CONCEPTS:
+// Runnable -- A type (really a type class) that has a single Run() method
+// and a RunType typedef that corresponds to the type of Run().
+// A Runnable can declare that it should treated like a method
+// call by including a typedef named IsMethod. The value of
+// this typedef is NOT inspected, only the existence. When a
+// Runnable declares itself a method, Bind() will enforce special
+// refcounting + WeakPtr handling semantics for the first
+// parameter which is expected to be an object.
+// Functor -- A copyable type representing something that should be called.
+// All function pointers, Callback<>, and Runnables are functors
+// even if the invocation syntax differs.
+// RunType -- A function type (as opposed to function _pointer_ type) for
+// a Run() function. Usually just a convenience typedef.
+// (Bound)ArgsType -- A function type that is being (ab)used to store the
+// types of set of arguments. The "return" type is always
+// void here. We use this hack so that we do not need
+// a new type name for each arity of type. (eg.,
+// BindState1, BindState2). This makes forward
+// declarations and friending much much easier.
//
-// 1) The type of function (normal or method).
-// 2) The arity of the function.
-// 3) The number of bound parameters.
+// Types:
+// RunnableAdapter<> -- Wraps the various "function" pointer types into an
+// object that adheres to the Runnable interface.
+// There are |3*ARITY| RunnableAdapter types.
+// FunctionTraits<> -- Type traits that unwrap a function signature into a
+// a set of easier to use typedefs. Used mainly for
+// compile time asserts.
+// There are |ARITY| FunctionTraits types.
+// ForceVoidReturn<> -- Helper class for translating function signatures to
+// equivalent forms with a "void" return type.
+// There are |ARITY| ForceVoidReturn types.
+// FunctorTraits<> -- Type traits used determine the correct RunType and
+// RunnableType for a Functor. This is where function
+// signature adapters are applied.
+// There are |ARITY| ForceVoidReturn types.
+// MakeRunnable<> -- Takes a Functor and returns an object in the Runnable
+// type class that represents the underlying Functor.
+// There are |O(1)| MakeRunnable types.
+// InvokeHelper<> -- Take a Runnable + arguments and actully invokes it.
+// Handle the differing syntaxes needed for WeakPtr<> support,
+// and for ignoring return values. This is separate from
+// Invoker to avoid creating multiple version of Invoker<>
+// which grows at O(n^2) with the arity.
+// There are |k*ARITY| InvokeHelper types.
+// Invoker<> -- Unwraps the curried parameters and executes the Runnable.
+// There are |(ARITY^2 + ARITY)/2| Invoketypes.
+// BindState<> -- Stores the curried parameters, and is the main entry point
+// into the Bind() system, doing most of the type resolution.
+// There are ARITY BindState types.
+
+
+// RunnableAdapter<>
//
-// The templates below handle the determination of each of these dimensions.
-// In brief:
-//
-// FunctionTraits<> -- Provides a normalied signature, and other traits.
-// InvokerN<> -- Provides a DoInvoke() function that actually executes
-// a calback.
-// InvokerStorageN<> -- Provides storage for the bound parameters, and
-// typedefs to the above.
-// IsWeakMethod<> -- Determines if we are binding a method to a WeakPtr<>.
-//
-// More details about the design of each class is included in a comment closer
-// to their defition.
-
-
-// IsWeakMethod determines if we are binding a method to a WeakPtr<> for an
-// object. It is used to select an InvokerN that will no-op itself in the
-// event the WeakPtr<> for the target object is invalidated.
-template <bool IsMethod, typename T>
-struct IsWeakMethod : public false_type {};
-
-template <typename T>
-struct IsWeakMethod<true, WeakPtr<T> > : public true_type {};
-
-// FunctionTraits<>
+// The RunnableAdapter<> templates provide a uniform interface for invoking
+// a function pointer, method pointer, or const method pointer. The adapter
+// exposes a Run() method with an appropriate signature. Using this wrapper
+// allows for writing code that supports all three pointer types without
+// undue repetition. Without it, a lot of code would need to be repeated 3
+// times.
//
-// The FunctionTraits<> template determines the type of function, and also
-// creates a NormalizedType used to select the InvokerN classes. It turns out
-// that syntactically, you only really have 2 variations when invoking a
-// funciton pointer: normal, and method. One is invoked func_ptr(arg1). The
-// other is invoked (*obj_->method_ptr(arg1)).
+// For method pointers and const method pointers the first argument to Run()
+// is considered to be the received of the method. This is similar to STL's
+// mem_fun().
//
-// However, in the type system, there are many more distinctions. In standard
-// C++, there's all variations of const, and volatile on the function pointer.
-// In Windows, there are additional calling conventions (eg., __stdcall,
-// __fastcall, etc.). FunctionTraits<> handles categorizing each of these into
-// a normalized signature.
+// This class also exposes a RunType typedef that is the function type of the
+// Run() function.
//
-// Having a NormalizedSignature signature, reduces the combinatoric
-// complexity of defintions for the InvokerN<> later. Even though there are
-// only 2 syntactic variations on invoking a function, without normalizing the
-// signature, there would need to be one specialization of InvokerN for each
-// unique (function_type, bound_arg, unbound_args) tuple in order to match all
-// function signatures.
-//
-// By normalizing the function signature, we reduce function_type to exactly 2.
+// If and only if the wrapper contains a method or const method pointer, an
+// IsMethod typedef is exposed. The existence of this typedef (NOT the value)
+// marks that the wrapper should be considered a method wrapper.
-template <typename Sig>
-struct FunctionTraits;
+template <typename Functor>
+class RunnableAdapter;
-$range ARITY 0..MAX_ARITY
$for ARITY [[
$range ARG 1..ARITY
// Function: Arity $(ARITY).
template <typename R[[]]
-$if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]>
-struct FunctionTraits<R(*)($for ARG , [[X$(ARG)]])> {
- typedef R (*NormalizedSig)($for ARG , [[X$(ARG)]]);
- typedef false_type IsMethod;
-
- typedef R Return;
-
-$if ARITY > 0 [[
-
- // Target type for each bound parameter.
+$if ARITY > 0[[, ]] $for ARG , [[typename A$(ARG)]]>
+class RunnableAdapter<R(*)($for ARG , [[A$(ARG)]])> {
+ public:
+ typedef R (RunType)($for ARG , [[A$(ARG)]]);
-$for ARG [[
- typedef X$(ARG) B$(ARG);
+ explicit RunnableAdapter(R(*function)($for ARG , [[A$(ARG)]]))
+ : function_(function) {
+ }
-]] $$ for ARG
-]] $$ if ARITY > 0
+ R Run($for ARG , [[typename CallbackParamTraits<A$(ARG)>::ForwardType a$(ARG)]]) {
+ return function_($for ARG , [[a$(ARG)]]);
+ }
+ private:
+ R (*function_)($for ARG , [[A$(ARG)]]);
};
// Method: Arity $(ARITY).
template <typename R, typename T[[]]
-$if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]>
-struct FunctionTraits<R(T::*)($for ARG , [[X$(ARG)]])> {
- typedef R (T::*NormalizedSig)($for ARG , [[X$(ARG)]]);
+$if ARITY > 0[[, ]] $for ARG , [[typename A$(ARG)]]>
+class RunnableAdapter<R(T::*)($for ARG , [[A$(ARG)]])> {
+ public:
+ typedef R (RunType)(T*[[]]
+$if ARITY > 0[[, ]] $for ARG , [[A$(ARG)]]);
typedef true_type IsMethod;
- typedef R Return;
-
- // Target type for each bound parameter.
- typedef T B1;
-
-$for ARG [[
- typedef X$(ARG) B$(ARG + 1);
+ explicit RunnableAdapter(R(T::*method)($for ARG , [[A$(ARG)]]))
+ : method_(method) {
+ }
-]] $$ for ARG
+ R Run(T* object[[]]
+$if ARITY > 0[[, ]] $for ARG, [[typename CallbackParamTraits<A$(ARG)>::ForwardType a$(ARG)]]) {
+ return (object->*method_)($for ARG , [[a$(ARG)]]);
+ }
+ private:
+ R (T::*method_)($for ARG , [[A$(ARG)]]);
};
// Const Method: Arity $(ARITY).
template <typename R, typename T[[]]
-$if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]>
-struct FunctionTraits<R(T::*)($for ARG , [[X$(ARG)]]) const> {
- typedef R (T::*NormalizedSig)($for ARG , [[X$(ARG)]]);
+$if ARITY > 0[[, ]] $for ARG , [[typename A$(ARG)]]>
+class RunnableAdapter<R(T::*)($for ARG , [[A$(ARG)]]) const> {
+ public:
+ typedef R (RunType)(const T*[[]]
+$if ARITY > 0[[, ]] $for ARG , [[A$(ARG)]]);
typedef true_type IsMethod;
- typedef R Return;
+ explicit RunnableAdapter(R(T::*method)($for ARG , [[A$(ARG)]]) const)
+ : method_(method) {
+ }
+
+ R Run(const T* object[[]]
+$if ARITY > 0[[, ]] $for ARG, [[typename CallbackParamTraits<A$(ARG)>::ForwardType a$(ARG)]]) {
+ return (object->*method_)($for ARG , [[a$(ARG)]]);
+ }
+
+ private:
+ R (T::*method_)($for ARG , [[A$(ARG)]]) const;
+};
+
+]] $$ for ARITY
+
- // Target type for each bound parameter.
- typedef T B1;
+// FunctionTraits<>
+//
+// Breaks a function signature apart into typedefs for easier introspection.
+template <typename Sig>
+struct FunctionTraits;
+$for ARITY [[
+$range ARG 1..ARITY
+
+template <typename R[[]]
+$if ARITY > 0[[, ]] $for ARG , [[typename A$(ARG)]]>
+struct FunctionTraits<R($for ARG , [[A$(ARG)]])> {
+ typedef R ReturnType;
$for ARG [[
- typedef X$(ARG) B$(ARG + 1);
-]] $$ for ARG
+ typedef A$(ARG) A$(ARG)Type;
+]]
};
-]] $$for ARITY
+]]
-// InvokerN<>
-//
-// The InvokerN templates contain a static DoInvoke() function that is the key
-// to implementing type erasure in the Callback() classes.
-//
-// DoInvoke() is a static function with a fixed signature that is independent
-// of StorageType; its first argument is a pointer to the non-templated common
-// baseclass of StorageType. This lets us store pointer to DoInvoke() in a
-// function pointer that has knowledge of the specific StorageType, and thus
-// no knowledge of the bound function and bound parameter types.
+
+// ForceVoidReturn<>
//
-// As long as we ensure that DoInvoke() is only used with pointers there were
-// upcasted from the correct StorageType, we can be sure that execution is
-// safe.
+// Set of templates that support forcing the function return type to void.
+template <typename Sig>
+struct ForceVoidReturn;
+
+$for ARITY [[
+$range ARG 1..ARITY
+
+template <typename R[[]]
+$if ARITY > 0[[, ]] $for ARG , [[typename A$(ARG)]]>
+struct ForceVoidReturn<R($for ARG , [[A$(ARG)]])> {
+ typedef void(RunType)($for ARG , [[A$(ARG)]]);
+};
+
+]] $$ for ARITY
+
+
+// FunctorTraits<>
//
-// The InvokerN templates are the only point that knows the number of bound
-// and unbound arguments. This is intentional because it allows the other
-// templates classes in the system to only have as many specializations as
-// the max arity of function we wish to support.
+// See description at top of file.
+template <typename T>
+struct FunctorTraits {
+ typedef RunnableAdapter<T> RunnableType;
+ typedef typename RunnableType::RunType RunType;
+};
-$range BOUND 0..MAX_ARITY
-$for BOUND [[
+template <typename T>
+struct FunctorTraits<IgnoreResultHelper<T> > {
+ typedef typename FunctorTraits<T>::RunnableType RunnableType;
+ typedef typename ForceVoidReturn<
+ typename RunnableType::RunType>::RunType RunType;
+};
-template <bool IsWeak, typename StorageType, typename NormalizedSig>
-struct Invoker$(BOUND);
+template <typename T>
+struct FunctorTraits<Callback<T> > {
+ typedef Callback<T> RunnableType;
+ typedef typename Callback<T>::RunType RunType;
+};
-$range ARITY 0..MAX_ARITY
-$for ARITY [[
-$var UNBOUND = ARITY - BOUND
-$if UNBOUND >= 0 [[
+// MakeRunnable<>
+//
+// Converts a passed in functor to a RunnableType using type inference.
-$$ Variables for function traits generation.
-$range ARG 1..ARITY
-$range BOUND_ARG 1..BOUND
-$range UNBOUND_ARG (ARITY - UNBOUND + 1)..ARITY
+template <typename T>
+typename FunctorTraits<T>::RunnableType MakeRunnable(const T& t) {
+ return RunnableAdapter<T>(t);
+}
-$$ Variables for method traits generation. We are always short one arity since
-$$ the first bound parameter is the object.
-$var M_ARITY = ARITY - 1
-$range M_ARG 1..M_ARITY
-$range M_BOUND_ARG 2..BOUND
-$range M_UNBOUND_ARG (M_ARITY - UNBOUND + 1)..M_ARITY
+template <typename T>
+typename FunctorTraits<T>::RunnableType
+MakeRunnable(const IgnoreResultHelper<T>& t) {
+ return MakeRunnable(t.functor_);
+}
-// Function: Arity $(ARITY) -> $(UNBOUND).
-template <typename StorageType, typename R[[]]
-$if ARITY > 0 [[,]][[]]
-$for ARG , [[typename X$(ARG)]]>
-struct Invoker$(BOUND)<false, StorageType, R(*)($for ARG , [[X$(ARG)]])> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*[[]]
-$if UNBOUND != 0 [[, ]]
-$for UNBOUND_ARG , [[typename internal::ParamTraits<X$(UNBOUND_ARG)>::ForwardType]]);
+template <typename T>
+const typename FunctorTraits<Callback<T> >::RunnableType&
+MakeRunnable(const Callback<T>& t) {
+ return t;
+}
- static R DoInvoke(InvokerStorageBase* base[[]]
-$if UNBOUND != 0 [[, ]][[]]
-$for UNBOUND_ARG , [[typename internal::ParamTraits<X$(UNBOUND_ARG)>::ForwardType x$(UNBOUND_ARG)]]) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return invoker->f_($for BOUND_ARG , [[Unwrap(invoker->p$(BOUND_ARG)_)]][[]]
-$$ Add comma if there are both boudn and unbound args.
-$if UNBOUND > 0 [[$if BOUND > 0 [[, ]]]][[]]
-$for UNBOUND_ARG , [[x$(UNBOUND_ARG)]]);
+
+// InvokeHelper<>
+//
+// There are 3 logical InvokeHelper<> specializations: normal, void-return,
+// WeakCalls.
+//
+// The normal type just calls the underlying runnable.
+//
+// We need a InvokeHelper to handle void return types in order to support
+// IgnoreResult(). Normally, if the Runnable's RunType had a void return,
+// the template system would just accept "return functor.Run()" ignoring
+// the fact that a void function is being used with return. This piece of
+// sugar breaks though when the Runnable's RunType is not void. Thus, we
+// need a partial specialization to change the syntax to drop the "return"
+// from the invocation call.
+//
+// WeakCalls similarly need special syntax that is applied to the first
+// argument to check if they should no-op themselves.
+template <bool IsWeakCall, typename ReturnType, typename Runnable,
+ typename ArgsType>
+struct InvokeHelper;
+
+$for ARITY [[
+$range ARG 1..ARITY
+
+template <typename ReturnType, typename Runnable[[]]
+$if ARITY > 0 [[,]] $for ARG , [[typename A$(ARG)]]>
+struct InvokeHelper<false, ReturnType, Runnable,
+ void($for ARG , [[A$(ARG)]])> {
+ static ReturnType MakeItSo(Runnable runnable[[]]
+$if ARITY > 0[[, ]] $for ARG , [[A$(ARG) a$(ARG)]]) {
+ return runnable.Run($for ARG , [[a$(ARG)]]);
}
};
-$if BOUND > 0 [[
-
-// Method: Arity $(M_ARITY) -> $(UNBOUND).
-template <typename StorageType, typename R, typename T[[]]
-$if M_ARITY > 0[[, ]] $for M_ARG , [[typename X$(M_ARG)]]>
-struct Invoker$(BOUND)<false, StorageType, R(T::*)($for M_ARG , [[X$(M_ARG)]])> {
- typedef R(*DoInvokeType)(
- internal::InvokerStorageBase*[[]]
-$if UNBOUND != 0 [[, ]]
-$for M_UNBOUND_ARG , [[typename internal::ParamTraits<X$(M_UNBOUND_ARG)>::ForwardType]]);
-
- static R DoInvoke(InvokerStorageBase* base[[]]
-$if UNBOUND > 0 [[, ]][[]]
-$for M_UNBOUND_ARG , [[typename internal::ParamTraits<X$(M_UNBOUND_ARG)>::ForwardType x$(M_UNBOUND_ARG)]]) {
- StorageType* invoker = static_cast<StorageType*>(base);
- return (Unwrap(invoker->p1_)->*invoker->f_)([[]]
-$for M_BOUND_ARG , [[Unwrap(invoker->p$(M_BOUND_ARG)_)]][[]]
-$if UNBOUND > 0 [[$if BOUND > 1 [[, ]]]][[]]
-$for M_UNBOUND_ARG , [[x$(M_UNBOUND_ARG)]]);
+template <typename Runnable[[]]
+$if ARITY > 0 [[,]] $for ARG , [[typename A$(ARG)]]>
+struct InvokeHelper<false, void, Runnable,
+ void($for ARG , [[A$(ARG)]])> {
+ static void MakeItSo(Runnable runnable[[]]
+$if ARITY > 0[[, ]] $for ARG , [[A$(ARG) a$(ARG)]]) {
+ runnable.Run($for ARG , [[a$(ARG)]]);
}
};
-// WeakPtr Method: Arity $(M_ARITY) -> $(UNBOUND).
-template <typename StorageType, typename T[[]]
-$if M_ARITY > 0[[, ]] $for M_ARG , [[typename X$(M_ARG)]]>
-struct Invoker$(BOUND)<true, StorageType, void(T::*)($for M_ARG , [[X$(M_ARG)]])> {
- typedef void(*DoInvokeType)(
- internal::InvokerStorageBase*[[]]
-$if UNBOUND != 0 [[, ]]
-$for M_UNBOUND_ARG , [[typename internal::ParamTraits<X$(M_UNBOUND_ARG)>::ForwardType]]);
-
- static void DoInvoke(InvokerStorageBase* base[[]]
-$if UNBOUND > 0 [[, ]][[]]
-$for M_UNBOUND_ARG , [[typename internal::ParamTraits<X$(M_UNBOUND_ARG)>::ForwardType x$(M_UNBOUND_ARG)]]) {
- StorageType* invoker = static_cast<StorageType*>(base);
- typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
- if (!weak_ptr.get()) {
+$if ARITY > 0 [[
+
+template <typename Runnable[[]], $for ARG , [[typename A$(ARG)]]>
+struct InvokeHelper<true, void, Runnable,
+ void($for ARG , [[A$(ARG)]])> {
+ static void MakeItSo(Runnable runnable[[]]
+$if ARITY > 0[[, ]] $for ARG , [[A$(ARG) a$(ARG)]]) {
+ if (!a1.get()) {
return;
}
- (weak_ptr->*invoker->f_)([[]]
-$for M_BOUND_ARG , [[Unwrap(invoker->p$(M_BOUND_ARG)_)]][[]]
-$if UNBOUND > 0 [[$if BOUND > 1 [[, ]]]][[]]
-$for M_UNBOUND_ARG , [[x$(M_UNBOUND_ARG)]]);
+
+ runnable.Run($for ARG , [[a$(ARG)]]);
}
};
-]] $$ if BOUND
+]]
-]] $$ if UNBOUND
-]] $$ for ARITY
-]] $$ for BOUND
+]] $$ for ARITY
-// BindMoreFuncN<>
-//
-// This set of functions help in fully binding the free parameters in a
-// Callback<>.
-$for BOUND [[
-$range BOUND_ARG 1..BOUND
-$if BOUND != 0 [[
+#if !defined(_MSC_VER)
-template <typename Sig, $for BOUND_ARG , [[typename P$(BOUND_ARG)]]>
-void BindMoreFunc$(BOUND)(const base::Callback<Sig>& callback, [[]]
-$for BOUND_ARG , [[const P$(BOUND_ARG)& p$(BOUND_ARG)]]) {
- callback.Run($for BOUND_ARG , [[p$(BOUND_ARG)]]);
-}
+template <typename ReturnType, typename Runnable, typename ArgsType>
+struct InvokeHelper<true, ReturnType, Runnable, ArgsType> {
+ // WeakCalls are only supported for functions with a void return type.
+ // Otherwise, the function result would be undefined if the the WeakPtr<>
+ // is invalidated.
+ COMPILE_ASSERT(is_void<ReturnType>::value,
+ weak_ptrs_can_only_bind_to_methods_without_return_values);
+};
-]] $$ if BOUND
-]] $$ for BOUND
+#endif
-// InvokerStorageN<>
-//
-// These are the actual storage classes for the Invokers.
-//
-// Though these types are "classes", they are being used as structs with
-// all member variable public. We cannot make it a struct because it inherits
-// from a class which causes a compiler warning. We cannot add a "Run()" method
-// that forwards the unbound arguments because that would require we unwrap the
-// Sig type like in InvokerN above to know the return type, and the arity
-// of Run().
+// Invoker<>
//
-// An alternate solution would be to merge InvokerN and InvokerStorageN,
-// but the generated code seemed harder to read.
+// See description at the top of the file.
+template <int NumBound, typename Storage, typename RunType>
+struct Invoker;
+$for ARITY [[
+
+$$ Number of bound arguments.
+$range BOUND 0..ARITY
$for BOUND [[
+
+$var UNBOUND = ARITY - BOUND
+$range ARG 1..ARITY
$range BOUND_ARG 1..BOUND
+$range UNBOUND_ARG (ARITY - UNBOUND + 1)..ARITY
-template <typename Sig[[]]
-$if BOUND > 0 [[, ]]
-$for BOUND_ARG , [[typename P$(BOUND_ARG)]]>
-class InvokerStorage$(BOUND) : public InvokerStorageBase {
- public:
- typedef InvokerStorage$(BOUND) StorageType;
- typedef FunctionTraits<Sig> TargetTraits;
- typedef typename TargetTraits::IsMethod IsMethod;
- typedef Sig Signature;
+// Arity $(ARITY) -> $(UNBOUND).
+template <typename StorageType, typename R[[]]
+$if ARITY > 0 [[,]][[]]
+$for ARG , [[typename X$(ARG)]]>
+struct Invoker<$(BOUND), StorageType, R($for ARG , [[X$(ARG)]])> {
+ typedef R(RunType)(BindStateBase*[[]]
+$if UNBOUND != 0 [[, ]]
+$for UNBOUND_ARG , [[typename CallbackParamTraits<X$(UNBOUND_ARG)>::ForwardType]]);
-$for BOUND_ARG [[
- typedef ParamTraits<P$(BOUND_ARG)> P$(BOUND_ARG)Traits;
+ typedef R(UnboundRunType)($for UNBOUND_ARG , [[X$(UNBOUND_ARG)]]);
+ static R Run(BindStateBase* base[[]]
+$if UNBOUND != 0 [[, ]][[]]
+$for UNBOUND_ARG , [[
+typename CallbackParamTraits<X$(UNBOUND_ARG)>::ForwardType x$(UNBOUND_ARG)
+]][[]]
+) {
+ StorageType* storage = static_cast<StorageType*>(base);
+
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+$for BOUND_ARG
+[[
+
+ typedef typename StorageType::Bound$(BOUND_ARG)UnwrapTraits Bound$(BOUND_ARG)UnwrapTraits;
]]
-$if BOUND == 0 [[
- typedef Invoker$(BOUND)<false, StorageType,
- typename TargetTraits::NormalizedSig> Invoker;
-]] $else [[
- typedef Invoker$(BOUND)<IsWeakMethod<IsMethod::value, P1>::value, StorageType,
- typename TargetTraits::NormalizedSig> Invoker;
- COMPILE_ASSERT(!(IsWeakMethod<IsMethod::value, P1>::value) ||
- is_void<typename TargetTraits::Return>::value,
- weak_ptrs_can_only_bind_to_methods_without_return_values);
+
+$for BOUND_ARG
+[[
+
+ typename Bound$(BOUND_ARG)UnwrapTraits::ForwardType x$(BOUND_ARG) =
+ Bound$(BOUND_ARG)UnwrapTraits::Unwrap(storage->p$(BOUND_ARG)_);
]]
+ return InvokeHelper<StorageType::IsWeakCall::value, R,
+ typename StorageType::RunnableType,
+ void(
+$for BOUND_ARG , [[
+typename Bound$(BOUND_ARG)UnwrapTraits::ForwardType
+]]
-$for BOUND_ARG [[
-$if BOUND_ARG == 1 [[
+$if UNBOUND > 0 [[$if BOUND > 0 [[, ]]]][[]]
- // For methods, we need to be careful for parameter 1. We skip the
- // scoped_refptr check because the binder itself takes care of this. We also
- // disallow binding of an array as the method's target object.
- COMPILE_ASSERT(IsMethod::value ||
- internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P$(BOUND_ARG)>::StorageType>::value == 0,
- p$(BOUND_ARG)_is_refcounted_type_and_needs_scoped_refptr);
- COMPILE_ASSERT(!IsMethod::value || !is_array<P$(BOUND_ARG)>::value,
- first_bound_argument_to_method_cannot_be_array);
-]] $else [[
+$for UNBOUND_ARG , [[
+typename CallbackParamTraits<X$(UNBOUND_ARG)>::ForwardType x$(UNBOUND_ARG)
+]]
+)>
+ ::MakeItSo(storage->runnable_
+$if ARITY > 0[[, ]] $for ARG , [[x$(ARG)]]);
+ }
+};
+
+]] $$ for BOUND
+]] $$ for ARITY
- COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
- typename ParamTraits<P$(BOUND_ARG)>::StorageType>::value == 0,
- p$(BOUND_ARG)_is_refcounted_type_and_needs_scoped_refptr);
-]] $$ $if BOUND_ARG
-]] $$ $for BOUND_ARG
+// BindState<>
+//
+// This stores all the state passed into Bind() and is also where most
+// of the template resolution magic occurs.
+//
+// Runnable is the functor we are binding arguments to.
+// RunType is type of the Run() function that the Invoker<> should use.
+// Normally, this is the same as the RunType of the Runnable, but it can
+// be different if an adapter like IgnoreResult() has been used.
+//
+// BoundArgsType contains the storage type for all the bound arguments by
+// (ab)using a function type.
+template <typename Runnable, typename RunType, typename BoundArgsType>
+struct BindState;
-$if BOUND > 0 [[
+$for ARITY [[
+$range ARG 1..ARITY
- // Do not allow binding a non-const reference parameter. Non-const reference
- // parameters are disallowed by the Google style guide. Also, binding a
- // non-const reference parameter can make for subtle bugs because the
- // invoked function will receive a reference to the stored copy of the
- // argument and not the original.
- COMPILE_ASSERT(
- !($for BOUND_ARG || [[ is_non_const_reference<typename TargetTraits::B$(BOUND_ARG)>::value ]]),
- do_not_bind_functions_with_nonconst_ref);
+template <typename Runnable, typename RunType[[]]
+$if ARITY > 0[[, ]] $for ARG , [[typename P$(ARG)]]>
+struct BindState<Runnable, RunType, void($for ARG , [[P$(ARG)]])> : public BindStateBase {
+ typedef Runnable RunnableType;
+$if ARITY > 0 [[
+ typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall;
+]] $else [[
+ typedef false_type IsWeakCall;
]]
+ typedef Invoker<$(ARITY), BindState, RunType> InvokerType;
+ typedef typename InvokerType::UnboundRunType UnboundRunType;
+
+$if ARITY > 0 [[
+
+ // Convenience typedefs for bound argument types.
+
+$for ARG [[
+ typedef UnwrapTraits<P$(ARG)> Bound$(ARG)UnwrapTraits;
+
+]] $$ for ARG
+
+
+]] $$ if ARITY > 0
- InvokerStorage$(BOUND)(Sig f
-$if BOUND > 0 [[, ]]
-$for BOUND_ARG , [[const P$(BOUND_ARG)& p$(BOUND_ARG)]])
- : f_(f)[[]]
-$if BOUND == 0 [[
+$$ The extra [[ ]] is needed to massage spacing. Silly pump.py.
+[[ ]]$if ARITY == 0 [[explicit ]]BindState(const Runnable& runnable
+$if ARITY > 0 [[, ]] $for ARG , [[const P$(ARG)& p$(ARG)]])
+ : runnable_(runnable)[[]]
+$if ARITY == 0 [[
{
]] $else [[
-, $for BOUND_ARG , [[p$(BOUND_ARG)_(static_cast<typename ParamTraits<P$(BOUND_ARG)>::StorageType>(p$(BOUND_ARG)))]] {
- MaybeRefcount<IsMethod, P1>::AddRef(p1_);
+, $for ARG , [[
+
+ p$(ARG)_(p$(ARG))
+]] {
+ MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_);
]]
}
- virtual ~InvokerStorage$(BOUND)() {
-$if BOUND > 0 [[
-
- MaybeRefcount<IsMethod, P1>::Release(p1_);
-
+ virtual ~BindState() {
+$if ARITY > 0 [[
+ MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::Release(p1_);
]]
}
- Sig f_;
+ RunnableType runnable_;
-$for BOUND_ARG [[
- typename ParamTraits<P$(BOUND_ARG)>::StorageType p$(BOUND_ARG)_;
+$for ARG [[
+ P$(ARG) p$(ARG)_;
]]
};
-]] $$ for BOUND
+]] $$ for ARITY
} // namespace internal
} // namespace base
diff --git a/base/bind_internal_win.h b/base/bind_internal_win.h
index 250f472..17d3aa3 100644
--- a/base/bind_internal_win.h
+++ b/base/bind_internal_win.h
@@ -8,7 +8,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Specializations of FunctionTraits<> for Windows specific calling
+// Specializations of RunnableAdapter<> for Windows specific calling
// conventions. Please see base/bind_internal.h for more info.
#ifndef BASE_BIND_INTERNAL_WIN_H_
@@ -23,203 +23,293 @@
namespace base {
namespace internal {
-template <typename Sig>
-struct FunctionTraits;
+template <typename Functor>
+class RunnableAdapter;
// __stdcall Function: Arity 0.
template <typename R>
-struct FunctionTraits<R(__stdcall *)()> {
- typedef R (*NormalizedSig)();
- typedef false_type IsMethod;
+class RunnableAdapter<R(__stdcall *)()> {
+ public:
+ typedef R (RunType)();
- typedef R Return;
+ explicit RunnableAdapter(R(__stdcall *function)())
+ : function_(function) {
+ }
+
+ R Run() {
+ return function_();
+ }
+
+ private:
+ R (__stdcall *function_)();
};
// __fastcall Function: Arity 0.
template <typename R>
-struct FunctionTraits<R(__fastcall *)()> {
- typedef R (*NormalizedSig)();
- typedef false_type IsMethod;
+class RunnableAdapter<R(__fastcall *)()> {
+ public:
+ typedef R (RunType)();
+
+ explicit RunnableAdapter(R(__fastcall *function)())
+ : function_(function) {
+ }
+
+ R Run() {
+ return function_();
+ }
- typedef R Return;
+ private:
+ R (__fastcall *function_)();
};
// __stdcall Function: Arity 1.
-template <typename R, typename X1>
-struct FunctionTraits<R(__stdcall *)(X1)> {
- typedef R (*NormalizedSig)(X1);
- typedef false_type IsMethod;
+template <typename R, typename A1>
+class RunnableAdapter<R(__stdcall *)(A1)> {
+ public:
+ typedef R (RunType)(A1);
- typedef R Return;
+ explicit RunnableAdapter(R(__stdcall *function)(A1))
+ : function_(function) {
+ }
- // Target type for each bound parameter.
- typedef X1 B1;
+ R Run(typename CallbackParamTraits<A1>::ForwardType a1) {
+ return function_(a1);
+ }
+
+ private:
+ R (__stdcall *function_)(A1);
};
// __fastcall Function: Arity 1.
-template <typename R, typename X1>
-struct FunctionTraits<R(__fastcall *)(X1)> {
- typedef R (*NormalizedSig)(X1);
- typedef false_type IsMethod;
+template <typename R, typename A1>
+class RunnableAdapter<R(__fastcall *)(A1)> {
+ public:
+ typedef R (RunType)(A1);
+
+ explicit RunnableAdapter(R(__fastcall *function)(A1))
+ : function_(function) {
+ }
- typedef R Return;
+ R Run(typename CallbackParamTraits<A1>::ForwardType a1) {
+ return function_(a1);
+ }
- // Target type for each bound parameter.
- typedef X1 B1;
+ private:
+ R (__fastcall *function_)(A1);
};
// __stdcall Function: Arity 2.
-template <typename R, typename X1, typename X2>
-struct FunctionTraits<R(__stdcall *)(X1, X2)> {
- typedef R (*NormalizedSig)(X1, X2);
- typedef false_type IsMethod;
-
- typedef R Return;
-
- // Target type for each bound parameter.
- typedef X1 B1;
- typedef X2 B2;
+template <typename R, typename A1, typename A2>
+class RunnableAdapter<R(__stdcall *)(A1, A2)> {
+ public:
+ typedef R (RunType)(A1, A2);
+
+ explicit RunnableAdapter(R(__stdcall *function)(A1, A2))
+ : function_(function) {
+ }
+
+ R Run(typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2) {
+ return function_(a1, a2);
+ }
+
+ private:
+ R (__stdcall *function_)(A1, A2);
};
// __fastcall Function: Arity 2.
-template <typename R, typename X1, typename X2>
-struct FunctionTraits<R(__fastcall *)(X1, X2)> {
- typedef R (*NormalizedSig)(X1, X2);
- typedef false_type IsMethod;
-
- typedef R Return;
-
- // Target type for each bound parameter.
- typedef X1 B1;
- typedef X2 B2;
+template <typename R, typename A1, typename A2>
+class RunnableAdapter<R(__fastcall *)(A1, A2)> {
+ public:
+ typedef R (RunType)(A1, A2);
+
+ explicit RunnableAdapter(R(__fastcall *function)(A1, A2))
+ : function_(function) {
+ }
+
+ R Run(typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2) {
+ return function_(a1, a2);
+ }
+
+ private:
+ R (__fastcall *function_)(A1, A2);
};
// __stdcall Function: Arity 3.
-template <typename R, typename X1, typename X2, typename X3>
-struct FunctionTraits<R(__stdcall *)(X1, X2, X3)> {
- typedef R (*NormalizedSig)(X1, X2, X3);
- typedef false_type IsMethod;
-
- typedef R Return;
-
- // Target type for each bound parameter.
- typedef X1 B1;
- typedef X2 B2;
- typedef X3 B3;
+template <typename R, typename A1, typename A2, typename A3>
+class RunnableAdapter<R(__stdcall *)(A1, A2, A3)> {
+ public:
+ typedef R (RunType)(A1, A2, A3);
+
+ explicit RunnableAdapter(R(__stdcall *function)(A1, A2, A3))
+ : function_(function) {
+ }
+
+ R Run(typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2,
+ typename CallbackParamTraits<A3>::ForwardType a3) {
+ return function_(a1, a2, a3);
+ }
+
+ private:
+ R (__stdcall *function_)(A1, A2, A3);
};
// __fastcall Function: Arity 3.
-template <typename R, typename X1, typename X2, typename X3>
-struct FunctionTraits<R(__fastcall *)(X1, X2, X3)> {
- typedef R (*NormalizedSig)(X1, X2, X3);
- typedef false_type IsMethod;
-
- typedef R Return;
-
- // Target type for each bound parameter.
- typedef X1 B1;
- typedef X2 B2;
- typedef X3 B3;
+template <typename R, typename A1, typename A2, typename A3>
+class RunnableAdapter<R(__fastcall *)(A1, A2, A3)> {
+ public:
+ typedef R (RunType)(A1, A2, A3);
+
+ explicit RunnableAdapter(R(__fastcall *function)(A1, A2, A3))
+ : function_(function) {
+ }
+
+ R Run(typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2,
+ typename CallbackParamTraits<A3>::ForwardType a3) {
+ return function_(a1, a2, a3);
+ }
+
+ private:
+ R (__fastcall *function_)(A1, A2, A3);
};
// __stdcall Function: Arity 4.
-template <typename R, typename X1, typename X2, typename X3, typename X4>
-struct FunctionTraits<R(__stdcall *)(X1, X2, X3, X4)> {
- typedef R (*NormalizedSig)(X1, X2, X3, X4);
- typedef false_type IsMethod;
-
- typedef R Return;
-
- // Target type for each bound parameter.
- typedef X1 B1;
- typedef X2 B2;
- typedef X3 B3;
- typedef X4 B4;
+template <typename R, typename A1, typename A2, typename A3, typename A4>
+class RunnableAdapter<R(__stdcall *)(A1, A2, A3, A4)> {
+ public:
+ typedef R (RunType)(A1, A2, A3, A4);
+
+ explicit RunnableAdapter(R(__stdcall *function)(A1, A2, A3, A4))
+ : function_(function) {
+ }
+
+ R Run(typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2,
+ typename CallbackParamTraits<A3>::ForwardType a3,
+ typename CallbackParamTraits<A4>::ForwardType a4) {
+ return function_(a1, a2, a3, a4);
+ }
+
+ private:
+ R (__stdcall *function_)(A1, A2, A3, A4);
};
// __fastcall Function: Arity 4.
-template <typename R, typename X1, typename X2, typename X3, typename X4>
-struct FunctionTraits<R(__fastcall *)(X1, X2, X3, X4)> {
- typedef R (*NormalizedSig)(X1, X2, X3, X4);
- typedef false_type IsMethod;
-
- typedef R Return;
-
- // Target type for each bound parameter.
- typedef X1 B1;
- typedef X2 B2;
- typedef X3 B3;
- typedef X4 B4;
+template <typename R, typename A1, typename A2, typename A3, typename A4>
+class RunnableAdapter<R(__fastcall *)(A1, A2, A3, A4)> {
+ public:
+ typedef R (RunType)(A1, A2, A3, A4);
+
+ explicit RunnableAdapter(R(__fastcall *function)(A1, A2, A3, A4))
+ : function_(function) {
+ }
+
+ R Run(typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2,
+ typename CallbackParamTraits<A3>::ForwardType a3,
+ typename CallbackParamTraits<A4>::ForwardType a4) {
+ return function_(a1, a2, a3, a4);
+ }
+
+ private:
+ R (__fastcall *function_)(A1, A2, A3, A4);
};
// __stdcall Function: Arity 5.
-template <typename R, typename X1, typename X2, typename X3, typename X4,
- typename X5>
-struct FunctionTraits<R(__stdcall *)(X1, X2, X3, X4, X5)> {
- typedef R (*NormalizedSig)(X1, X2, X3, X4, X5);
- typedef false_type IsMethod;
-
- typedef R Return;
-
- // Target type for each bound parameter.
- typedef X1 B1;
- typedef X2 B2;
- typedef X3 B3;
- typedef X4 B4;
- typedef X5 B5;
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5>
+class RunnableAdapter<R(__stdcall *)(A1, A2, A3, A4, A5)> {
+ public:
+ typedef R (RunType)(A1, A2, A3, A4, A5);
+
+ explicit RunnableAdapter(R(__stdcall *function)(A1, A2, A3, A4, A5))
+ : function_(function) {
+ }
+
+ R Run(typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2,
+ typename CallbackParamTraits<A3>::ForwardType a3,
+ typename CallbackParamTraits<A4>::ForwardType a4,
+ typename CallbackParamTraits<A5>::ForwardType a5) {
+ return function_(a1, a2, a3, a4, a5);
+ }
+
+ private:
+ R (__stdcall *function_)(A1, A2, A3, A4, A5);
};
// __fastcall Function: Arity 5.
-template <typename R, typename X1, typename X2, typename X3, typename X4,
- typename X5>
-struct FunctionTraits<R(__fastcall *)(X1, X2, X3, X4, X5)> {
- typedef R (*NormalizedSig)(X1, X2, X3, X4, X5);
- typedef false_type IsMethod;
-
- typedef R Return;
-
- // Target type for each bound parameter.
- typedef X1 B1;
- typedef X2 B2;
- typedef X3 B3;
- typedef X4 B4;
- typedef X5 B5;
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5>
+class RunnableAdapter<R(__fastcall *)(A1, A2, A3, A4, A5)> {
+ public:
+ typedef R (RunType)(A1, A2, A3, A4, A5);
+
+ explicit RunnableAdapter(R(__fastcall *function)(A1, A2, A3, A4, A5))
+ : function_(function) {
+ }
+
+ R Run(typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2,
+ typename CallbackParamTraits<A3>::ForwardType a3,
+ typename CallbackParamTraits<A4>::ForwardType a4,
+ typename CallbackParamTraits<A5>::ForwardType a5) {
+ return function_(a1, a2, a3, a4, a5);
+ }
+
+ private:
+ R (__fastcall *function_)(A1, A2, A3, A4, A5);
};
// __stdcall Function: Arity 6.
-template <typename R, typename X1, typename X2, typename X3, typename X4,
- typename X5, typename X6>
-struct FunctionTraits<R(__stdcall *)(X1, X2, X3, X4, X5, X6)> {
- typedef R (*NormalizedSig)(X1, X2, X3, X4, X5, X6);
- typedef false_type IsMethod;
-
- typedef R Return;
-
- // Target type for each bound parameter.
- typedef X1 B1;
- typedef X2 B2;
- typedef X3 B3;
- typedef X4 B4;
- typedef X5 B5;
- typedef X6 B6;
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6>
+class RunnableAdapter<R(__stdcall *)(A1, A2, A3, A4, A5, A6)> {
+ public:
+ typedef R (RunType)(A1, A2, A3, A4, A5, A6);
+
+ explicit RunnableAdapter(R(__stdcall *function)(A1, A2, A3, A4, A5, A6))
+ : function_(function) {
+ }
+
+ R Run(typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2,
+ typename CallbackParamTraits<A3>::ForwardType a3,
+ typename CallbackParamTraits<A4>::ForwardType a4,
+ typename CallbackParamTraits<A5>::ForwardType a5,
+ typename CallbackParamTraits<A6>::ForwardType a6) {
+ return function_(a1, a2, a3, a4, a5, a6);
+ }
+
+ private:
+ R (__stdcall *function_)(A1, A2, A3, A4, A5, A6);
};
// __fastcall Function: Arity 6.
-template <typename R, typename X1, typename X2, typename X3, typename X4,
- typename X5, typename X6>
-struct FunctionTraits<R(__fastcall *)(X1, X2, X3, X4, X5, X6)> {
- typedef R (*NormalizedSig)(X1, X2, X3, X4, X5, X6);
- typedef false_type IsMethod;
-
- typedef R Return;
-
- // Target type for each bound parameter.
- typedef X1 B1;
- typedef X2 B2;
- typedef X3 B3;
- typedef X4 B4;
- typedef X5 B5;
- typedef X6 B6;
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, typename A6>
+class RunnableAdapter<R(__fastcall *)(A1, A2, A3, A4, A5, A6)> {
+ public:
+ typedef R (RunType)(A1, A2, A3, A4, A5, A6);
+
+ explicit RunnableAdapter(R(__fastcall *function)(A1, A2, A3, A4, A5, A6))
+ : function_(function) {
+ }
+
+ R Run(typename CallbackParamTraits<A1>::ForwardType a1,
+ typename CallbackParamTraits<A2>::ForwardType a2,
+ typename CallbackParamTraits<A3>::ForwardType a3,
+ typename CallbackParamTraits<A4>::ForwardType a4,
+ typename CallbackParamTraits<A5>::ForwardType a5,
+ typename CallbackParamTraits<A6>::ForwardType a6) {
+ return function_(a1, a2, a3, a4, a5, a6);
+ }
+
+ private:
+ R (__fastcall *function_)(A1, A2, A3, A4, A5, A6);
};
} // namespace internal
diff --git a/base/bind_internal_win.h.pump b/base/bind_internal_win.h.pump
index 80ee37d..1d3b6b4 100644
--- a/base/bind_internal_win.h.pump
+++ b/base/bind_internal_win.h.pump
@@ -11,7 +11,7 @@ $var MAX_ARITY = 6
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Specializations of FunctionTraits<> for Windows specific calling
+// Specializations of RunnableAdapter<> for Windows specific calling
// conventions. Please see base/bind_internal.h for more info.
#ifndef BASE_BIND_INTERNAL_WIN_H_
@@ -26,8 +26,8 @@ $var MAX_ARITY = 6
namespace base {
namespace internal {
-template <typename Sig>
-struct FunctionTraits;
+template <typename Functor>
+class RunnableAdapter;
$range ARITY 0..MAX_ARITY
$for ARITY [[
@@ -35,42 +35,40 @@ $range ARG 1..ARITY
// __stdcall Function: Arity $(ARITY).
template <typename R[[]]
-$if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]>
-struct FunctionTraits<R(__stdcall *)($for ARG , [[X$(ARG)]])> {
- typedef R (*NormalizedSig)($for ARG , [[X$(ARG)]]);
- typedef false_type IsMethod;
+$if ARITY > 0[[, ]] $for ARG , [[typename A$(ARG)]]>
+class RunnableAdapter<R(__stdcall *)($for ARG , [[A$(ARG)]])> {
+ public:
+ typedef R (RunType)($for ARG , [[A$(ARG)]]);
- typedef R Return;
+ explicit RunnableAdapter(R(__stdcall *function)($for ARG , [[A$(ARG)]]))
+ : function_(function) {
+ }
-$if ARITY > 0 [[
+ R Run($for ARG , [[typename CallbackParamTraits<A$(ARG)>::ForwardType a$(ARG)]]) {
+ return function_($for ARG , [[a$(ARG)]]);
+ }
- // Target type for each bound parameter.
-
-$for ARG [[
- typedef X$(ARG) B$(ARG);
-
-]] $$ for ARG
-]] $$ if ARITY > 0
+ private:
+ R (__stdcall *function_)($for ARG , [[A$(ARG)]]);
};
// __fastcall Function: Arity $(ARITY).
template <typename R[[]]
-$if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]>
-struct FunctionTraits<R(__fastcall *)($for ARG , [[X$(ARG)]])> {
- typedef R (*NormalizedSig)($for ARG , [[X$(ARG)]]);
- typedef false_type IsMethod;
-
- typedef R Return;
-
-$if ARITY > 0 [[
+$if ARITY > 0[[, ]] $for ARG , [[typename A$(ARG)]]>
+class RunnableAdapter<R(__fastcall *)($for ARG , [[A$(ARG)]])> {
+ public:
+ typedef R (RunType)($for ARG , [[A$(ARG)]]);
- // Target type for each bound parameter.
+ explicit RunnableAdapter(R(__fastcall *function)($for ARG , [[A$(ARG)]]))
+ : function_(function) {
+ }
-$for ARG [[
- typedef X$(ARG) B$(ARG);
+ R Run($for ARG , [[typename CallbackParamTraits<A$(ARG)>::ForwardType a$(ARG)]]) {
+ return function_($for ARG , [[a$(ARG)]]);
+ }
-]] $$ for ARG
-]] $$ if ARITY > 0
+ private:
+ R (__fastcall *function_)($for ARG , [[A$(ARG)]]);
};
]] $$for ARITY
diff --git a/base/bind_unittest.cc b/base/bind_unittest.cc
index 0fdd241..654a277 100644
--- a/base/bind_unittest.cc
+++ b/base/bind_unittest.cc
@@ -260,35 +260,28 @@ TEST_F(BindTest, ArityTest) {
EXPECT_EQ(69, c6.Run(13, 12, 11, 10, 9, 14));
}
-// Bind should be able to take existing Callbacks and convert to a Closure.
-TEST_F(BindTest, CallbackBindMore) {
- int output = 0;
- Closure c;
+// Test the Currying ability of the Callback system.
+TEST_F(BindTest, CurryingTest) {
+ Callback<int(int,int,int,int,int,int)> c6 = Bind(&Sum);
+ EXPECT_EQ(69, c6.Run(13, 12, 11, 10, 9, 14));
- Callback<void(int)> c1 = Bind(&OutputSum, &output, 16, 8, 4, 2);
- c = Bind(c1, 10);
- c.Run();
- EXPECT_EQ(40, output);
+ Callback<int(int,int,int,int,int)> c5 = Bind(c6, 32);
+ EXPECT_EQ(87, c5.Run(13, 12, 11, 10, 9));
- Callback<void(int,int)> c2 = Bind(&OutputSum, &output, 16, 8, 4);
- c = Bind(c2, 10, 9);
- c.Run();
- EXPECT_EQ(47, output);
+ Callback<int(int,int,int,int)> c4 = Bind(c5, 16);
+ EXPECT_EQ(94, c4.Run(13, 12, 11, 10));
- Callback<void(int,int,int)> c3 = Bind(&OutputSum, &output, 16, 8);
- c = Bind(c3, 10, 9, 8);
- c.Run();
- EXPECT_EQ(51, output);
+ Callback<int(int,int,int)> c3 = Bind(c4, 8);
+ EXPECT_EQ(92, c3.Run(13, 12, 11));
- Callback<void(int,int,int,int)> c4 = Bind(&OutputSum, &output, 16);
- c = Bind(c4, 10, 9, 8, 7);
- c.Run();
- EXPECT_EQ(50, output);
+ Callback<int(int,int)> c2 = Bind(c3, 4);
+ EXPECT_EQ(85, c2.Run(13, 12));
- Callback<void(int,int,int,int,int)> c5 = Bind(&OutputSum, &output);
- c = Bind(c5, 10, 9, 8, 7, 6);
- c.Run();
- EXPECT_EQ(40, output);
+ Callback<int(int)> c1 = Bind(c2, 2);
+ EXPECT_EQ(75, c1.Run(13));
+
+ Callback<int(void)> c0 = Bind(c1, 1);
+ EXPECT_EQ(63, c0.Run());
}
// Function type support.
@@ -363,13 +356,46 @@ TEST_F(BindTest, ReturnValues) {
EXPECT_EQ(51337, const_method_const_obj_cb.Run());
}
-// IgnoreReturn adapter test.
-// - Function with return value, and no params can be converted to Closure.
-TEST_F(BindTest, IgnoreReturn) {
+// IgnoreResult adapter test.
+// - Function with return value.
+// - Method with return value.
+// - Const Method with return.
+// - Method with return value bound to WeakPtr<>.
+// - Const Method with return bound to WeakPtr<>.
+TEST_F(BindTest, IgnoreResult) {
EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
- Callback<int(void)> normal_cb = Bind(&IntFunc0);
- Closure c = IgnoreReturn(normal_cb);
- c.Run();
+ EXPECT_CALL(has_ref_, AddRef()).Times(2);
+ EXPECT_CALL(has_ref_, Release()).Times(2);
+ EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10));
+ EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11));
+ EXPECT_CALL(no_ref_, IntMethod0()).WillOnce(Return(12));
+ EXPECT_CALL(no_ref_, IntConstMethod0()).WillOnce(Return(13));
+
+ Closure normal_func_cb = Bind(IgnoreResult(&IntFunc0));
+ normal_func_cb.Run();
+
+ Closure non_void_method_cb =
+ Bind(IgnoreResult(&HasRef::IntMethod0), &has_ref_);
+ non_void_method_cb.Run();
+
+ Closure non_void_const_method_cb =
+ Bind(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_);
+ non_void_const_method_cb.Run();
+
+ WeakPtrFactory<NoRef> weak_factory(&no_ref_);
+ WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
+
+ Closure non_void_weak_method_cb =
+ Bind(IgnoreResult(&NoRef::IntMethod0), weak_factory.GetWeakPtr());
+ non_void_weak_method_cb.Run();
+
+ Closure non_void_weak_const_method_cb =
+ Bind(IgnoreResult(&NoRef::IntConstMethod0), weak_factory.GetWeakPtr());
+ non_void_weak_const_method_cb.Run();
+
+ weak_factory.InvalidateWeakPtrs();
+ non_void_weak_const_method_cb.Run();
+ non_void_weak_method_cb.Run();
}
// Argument binding tests.
@@ -453,7 +479,7 @@ TEST_F(BindTest, UnboundArgumentTypeSupport) {
}
// Function with unbound reference parameter.
-// - Original paraemter is modified by callback.
+// - Original parameter is modified by callback.
TEST_F(BindTest, UnboundReferenceSupport) {
int n = 0;
Callback<void(int&)> unbound_ref_cb = Bind(&RefArgSet);
@@ -554,15 +580,15 @@ TEST_F(BindTest, WeakPtr) {
WeakPtrFactory<NoRef> weak_factory(&no_ref_);
WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
- Callback<void(void)> method_cb =
+ Closure method_cb =
Bind(&NoRef::VoidMethod0, weak_factory.GetWeakPtr());
method_cb.Run();
- Callback<void(void)> const_method_cb =
+ Closure const_method_cb =
Bind(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
const_method_cb.Run();
- Callback<void(void)> const_method_const_ptr_cb =
+ Closure const_method_const_ptr_cb =
Bind(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
const_method_const_ptr_cb.Run();
diff --git a/base/bind_unittest.nc b/base/bind_unittest.nc
index eba8747..069092c 100644
--- a/base/bind_unittest.nc
+++ b/base/bind_unittest.nc
@@ -4,6 +4,7 @@
#include "base/callback.h"
#include "base/bind.h"
+#include "base/memory/ref_counted.h"
namespace base {
@@ -21,10 +22,7 @@ class NoRef {
int IntMethod0() { return 1; }
};
-class HasRef : public NoRef {
- public:
- void AddRef(void) const {}
- bool Release(void) const { return true; }
+class HasRef : public NoRef, public base::RefCounted<HasRef> {
};
class Parent {
@@ -175,6 +173,9 @@ void WontCompile() {
// Refcounted types should not be bound as a raw pointer.
void WontCompile() {
HasRef for_raw_ptr;
+ int a;
+ Callback<void(void)> ref_count_as_raw_ptr_a =
+ Bind(&VoidPolymorphic1<int*>, &a);
Callback<void(void)> ref_count_as_raw_ptr =
Bind(&VoidPolymorphic1<HasRef*>, &for_raw_ptr);
}
@@ -190,7 +191,7 @@ void WontCompile() {
weak_ptr_with_non_void_return_type.Run();
}
-#elif defined(NCTEST_DISALLOW_ASSIGN_DIFFERINT_TYPES) // [r"creating array with negative size"]
+#elif defined(NCTEST_DISALLOW_ASSIGN_DIFFERINT_TYPES) // [r"invalid conversion from"]
// Bind result cannot be assigned to Callbacks with a mismatching type.
void WontCompile() {
diff --git a/base/callback.h b/base/callback.h
index 7579cef..6844cc5 100644
--- a/base/callback.h
+++ b/base/callback.h
@@ -126,26 +126,26 @@
// The Callback classes represent a generic function pointer. Internally,
// it stores a refcounted piece of state that represents the target function
// and all its bound parameters. Each Callback specialization has a templated
-// constructor that takes an InvokerStorageHolder<> object. In the context of
-// the constructor, the static type of this InvokerStorageHolder<> object
+// constructor that takes an BindStateHolder<> object. In the context of
+// the constructor, the static type of this BindStateHolder<> object
// uniquely identifies the function it is representing, all its bound
// parameters, and a DoInvoke() that is capable of invoking the target.
//
-// Callback's constructor is takes the InvokerStorageHolder<> that has the
+// Callback's constructor is takes the BindStateHolder<> that has the
// full static type and erases the target function type, and the bound
// parameters. It does this by storing a pointer to the specific DoInvoke()
-// function, and upcasting the state of InvokerStorageHolder<> to a
-// InvokerStorageBase. This is safe as long as this InvokerStorageBase pointer
+// function, and upcasting the state of BindStateHolder<> to a
+// BindStateBase. This is safe as long as this BindStateBase pointer
// is only used with the stored DoInvoke() pointer.
//
-// To create InvokerStorageHolder<> objects, we use the Bind() functions.
+// To create BindStateHolder<> objects, we use the Bind() functions.
// These functions, along with a set of internal templates, are reponsible for
//
// - Unwrapping the function signature into return type, and parameters
// - Determining the number of parameters that are bound
// - Creating the storage for the bound parameters
// - Performing compile-time asserts to avoid error-prone behavior
-// - Returning an InvokerStorageHolder<> with an DoInvoke() that has an arity
+// - Returning an BindStateHolder<> with an DoInvoke() that has an arity
// matching the number of unbound parameters, and knows the correct
// refcounting semantics for the target object if we are binding a class
// method.
@@ -236,12 +236,11 @@ class Callback;
template <typename R>
class Callback<R(void)> : public internal::CallbackBase {
public:
- typedef R(*PolymorphicInvoke)(
- internal::InvokerStorageBase*);
+ typedef R(RunType)();
Callback() : CallbackBase(NULL, NULL) { }
- // We pass InvokerStorageHolder by const ref to avoid incurring an
+ // We pass BindStateHolder by const ref to avoid incurring an
// unnecessary AddRef/Unref pair even though we will modify the object.
// We cannot use a normal reference because the compiler will warn
// since this is often used on a return value, which is a temporary.
@@ -249,13 +248,13 @@ class Callback<R(void)> : public internal::CallbackBase {
// Note that this constructor CANNOT be explicit, and that Bind() CANNOT
// return the exact Callback<> type. See base/bind.h for details.
template <typename T>
- Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
- : CallbackBase(
- reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
- &invoker_holder.invoker_storage_) {
- COMPILE_ASSERT((is_same<PolymorphicInvoke,
- typename T::Invoker::DoInvokeType>::value),
- callback_type_does_not_match_bind_result);
+ Callback(const internal::BindStateHolder<T>& bind_state_holder)
+ : CallbackBase(NULL, &bind_state_holder.bind_state_) {
+ // Force the assignment to a location variable of PolymorphicInvoke
+ // so the compiler will typecheck that the passed in Run() method has
+ // the correct type.
+ PolymorphicInvoke invoke_func = &T::InvokerType::Run;
+ polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
}
bool Equals(const Callback& other) const {
@@ -266,20 +265,23 @@ class Callback<R(void)> : public internal::CallbackBase {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
- return f(invoker_storage_.get());
+ return f(bind_state_.get());
}
+
+ private:
+ typedef R(*PolymorphicInvoke)(
+ internal::BindStateBase*);
+
};
template <typename R, typename A1>
class Callback<R(A1)> : public internal::CallbackBase {
public:
- typedef R(*PolymorphicInvoke)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<A1>::ForwardType);
+ typedef R(RunType)(A1);
Callback() : CallbackBase(NULL, NULL) { }
- // We pass InvokerStorageHolder by const ref to avoid incurring an
+ // We pass BindStateHolder by const ref to avoid incurring an
// unnecessary AddRef/Unref pair even though we will modify the object.
// We cannot use a normal reference because the compiler will warn
// since this is often used on a return value, which is a temporary.
@@ -287,38 +289,41 @@ class Callback<R(A1)> : public internal::CallbackBase {
// Note that this constructor CANNOT be explicit, and that Bind() CANNOT
// return the exact Callback<> type. See base/bind.h for details.
template <typename T>
- Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
- : CallbackBase(
- reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
- &invoker_holder.invoker_storage_) {
- COMPILE_ASSERT((is_same<PolymorphicInvoke,
- typename T::Invoker::DoInvokeType>::value),
- callback_type_does_not_match_bind_result);
+ Callback(const internal::BindStateHolder<T>& bind_state_holder)
+ : CallbackBase(NULL, &bind_state_holder.bind_state_) {
+ // Force the assignment to a location variable of PolymorphicInvoke
+ // so the compiler will typecheck that the passed in Run() method has
+ // the correct type.
+ PolymorphicInvoke invoke_func = &T::InvokerType::Run;
+ polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
}
bool Equals(const Callback& other) const {
return CallbackBase::Equals(other);
}
- R Run(typename internal::ParamTraits<A1>::ForwardType a1) const {
+ R Run(typename internal::CallbackParamTraits<A1>::ForwardType a1) const {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
- return f(invoker_storage_.get(), a1);
+ return f(bind_state_.get(), a1);
}
+
+ private:
+ typedef R(*PolymorphicInvoke)(
+ internal::BindStateBase*,
+ typename internal::CallbackParamTraits<A1>::ForwardType);
+
};
template <typename R, typename A1, typename A2>
class Callback<R(A1, A2)> : public internal::CallbackBase {
public:
- typedef R(*PolymorphicInvoke)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<A1>::ForwardType,
- typename internal::ParamTraits<A2>::ForwardType);
+ typedef R(RunType)(A1, A2);
Callback() : CallbackBase(NULL, NULL) { }
- // We pass InvokerStorageHolder by const ref to avoid incurring an
+ // We pass BindStateHolder by const ref to avoid incurring an
// unnecessary AddRef/Unref pair even though we will modify the object.
// We cannot use a normal reference because the compiler will warn
// since this is often used on a return value, which is a temporary.
@@ -326,41 +331,44 @@ class Callback<R(A1, A2)> : public internal::CallbackBase {
// Note that this constructor CANNOT be explicit, and that Bind() CANNOT
// return the exact Callback<> type. See base/bind.h for details.
template <typename T>
- Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
- : CallbackBase(
- reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
- &invoker_holder.invoker_storage_) {
- COMPILE_ASSERT((is_same<PolymorphicInvoke,
- typename T::Invoker::DoInvokeType>::value),
- callback_type_does_not_match_bind_result);
+ Callback(const internal::BindStateHolder<T>& bind_state_holder)
+ : CallbackBase(NULL, &bind_state_holder.bind_state_) {
+ // Force the assignment to a location variable of PolymorphicInvoke
+ // so the compiler will typecheck that the passed in Run() method has
+ // the correct type.
+ PolymorphicInvoke invoke_func = &T::InvokerType::Run;
+ polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
}
bool Equals(const Callback& other) const {
return CallbackBase::Equals(other);
}
- R Run(typename internal::ParamTraits<A1>::ForwardType a1,
- typename internal::ParamTraits<A2>::ForwardType a2) const {
+ R Run(typename internal::CallbackParamTraits<A1>::ForwardType a1,
+ typename internal::CallbackParamTraits<A2>::ForwardType a2) const {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
- return f(invoker_storage_.get(), a1,
+ return f(bind_state_.get(), a1,
a2);
}
+
+ private:
+ typedef R(*PolymorphicInvoke)(
+ internal::BindStateBase*,
+ typename internal::CallbackParamTraits<A1>::ForwardType,
+ typename internal::CallbackParamTraits<A2>::ForwardType);
+
};
template <typename R, typename A1, typename A2, typename A3>
class Callback<R(A1, A2, A3)> : public internal::CallbackBase {
public:
- typedef R(*PolymorphicInvoke)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<A1>::ForwardType,
- typename internal::ParamTraits<A2>::ForwardType,
- typename internal::ParamTraits<A3>::ForwardType);
+ typedef R(RunType)(A1, A2, A3);
Callback() : CallbackBase(NULL, NULL) { }
- // We pass InvokerStorageHolder by const ref to avoid incurring an
+ // We pass BindStateHolder by const ref to avoid incurring an
// unnecessary AddRef/Unref pair even though we will modify the object.
// We cannot use a normal reference because the compiler will warn
// since this is often used on a return value, which is a temporary.
@@ -368,44 +376,47 @@ class Callback<R(A1, A2, A3)> : public internal::CallbackBase {
// Note that this constructor CANNOT be explicit, and that Bind() CANNOT
// return the exact Callback<> type. See base/bind.h for details.
template <typename T>
- Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
- : CallbackBase(
- reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
- &invoker_holder.invoker_storage_) {
- COMPILE_ASSERT((is_same<PolymorphicInvoke,
- typename T::Invoker::DoInvokeType>::value),
- callback_type_does_not_match_bind_result);
+ Callback(const internal::BindStateHolder<T>& bind_state_holder)
+ : CallbackBase(NULL, &bind_state_holder.bind_state_) {
+ // Force the assignment to a location variable of PolymorphicInvoke
+ // so the compiler will typecheck that the passed in Run() method has
+ // the correct type.
+ PolymorphicInvoke invoke_func = &T::InvokerType::Run;
+ polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
}
bool Equals(const Callback& other) const {
return CallbackBase::Equals(other);
}
- R Run(typename internal::ParamTraits<A1>::ForwardType a1,
- typename internal::ParamTraits<A2>::ForwardType a2,
- typename internal::ParamTraits<A3>::ForwardType a3) const {
+ R Run(typename internal::CallbackParamTraits<A1>::ForwardType a1,
+ typename internal::CallbackParamTraits<A2>::ForwardType a2,
+ typename internal::CallbackParamTraits<A3>::ForwardType a3) const {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
- return f(invoker_storage_.get(), a1,
+ return f(bind_state_.get(), a1,
a2,
a3);
}
+
+ private:
+ typedef R(*PolymorphicInvoke)(
+ internal::BindStateBase*,
+ typename internal::CallbackParamTraits<A1>::ForwardType,
+ typename internal::CallbackParamTraits<A2>::ForwardType,
+ typename internal::CallbackParamTraits<A3>::ForwardType);
+
};
template <typename R, typename A1, typename A2, typename A3, typename A4>
class Callback<R(A1, A2, A3, A4)> : public internal::CallbackBase {
public:
- typedef R(*PolymorphicInvoke)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<A1>::ForwardType,
- typename internal::ParamTraits<A2>::ForwardType,
- typename internal::ParamTraits<A3>::ForwardType,
- typename internal::ParamTraits<A4>::ForwardType);
+ typedef R(RunType)(A1, A2, A3, A4);
Callback() : CallbackBase(NULL, NULL) { }
- // We pass InvokerStorageHolder by const ref to avoid incurring an
+ // We pass BindStateHolder by const ref to avoid incurring an
// unnecessary AddRef/Unref pair even though we will modify the object.
// We cannot use a normal reference because the compiler will warn
// since this is often used on a return value, which is a temporary.
@@ -413,48 +424,51 @@ class Callback<R(A1, A2, A3, A4)> : public internal::CallbackBase {
// Note that this constructor CANNOT be explicit, and that Bind() CANNOT
// return the exact Callback<> type. See base/bind.h for details.
template <typename T>
- Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
- : CallbackBase(
- reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
- &invoker_holder.invoker_storage_) {
- COMPILE_ASSERT((is_same<PolymorphicInvoke,
- typename T::Invoker::DoInvokeType>::value),
- callback_type_does_not_match_bind_result);
+ Callback(const internal::BindStateHolder<T>& bind_state_holder)
+ : CallbackBase(NULL, &bind_state_holder.bind_state_) {
+ // Force the assignment to a location variable of PolymorphicInvoke
+ // so the compiler will typecheck that the passed in Run() method has
+ // the correct type.
+ PolymorphicInvoke invoke_func = &T::InvokerType::Run;
+ polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
}
bool Equals(const Callback& other) const {
return CallbackBase::Equals(other);
}
- R Run(typename internal::ParamTraits<A1>::ForwardType a1,
- typename internal::ParamTraits<A2>::ForwardType a2,
- typename internal::ParamTraits<A3>::ForwardType a3,
- typename internal::ParamTraits<A4>::ForwardType a4) const {
+ R Run(typename internal::CallbackParamTraits<A1>::ForwardType a1,
+ typename internal::CallbackParamTraits<A2>::ForwardType a2,
+ typename internal::CallbackParamTraits<A3>::ForwardType a3,
+ typename internal::CallbackParamTraits<A4>::ForwardType a4) const {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
- return f(invoker_storage_.get(), a1,
+ return f(bind_state_.get(), a1,
a2,
a3,
a4);
}
+
+ private:
+ typedef R(*PolymorphicInvoke)(
+ internal::BindStateBase*,
+ typename internal::CallbackParamTraits<A1>::ForwardType,
+ typename internal::CallbackParamTraits<A2>::ForwardType,
+ typename internal::CallbackParamTraits<A3>::ForwardType,
+ typename internal::CallbackParamTraits<A4>::ForwardType);
+
};
template <typename R, typename A1, typename A2, typename A3, typename A4,
typename A5>
class Callback<R(A1, A2, A3, A4, A5)> : public internal::CallbackBase {
public:
- typedef R(*PolymorphicInvoke)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<A1>::ForwardType,
- typename internal::ParamTraits<A2>::ForwardType,
- typename internal::ParamTraits<A3>::ForwardType,
- typename internal::ParamTraits<A4>::ForwardType,
- typename internal::ParamTraits<A5>::ForwardType);
+ typedef R(RunType)(A1, A2, A3, A4, A5);
Callback() : CallbackBase(NULL, NULL) { }
- // We pass InvokerStorageHolder by const ref to avoid incurring an
+ // We pass BindStateHolder by const ref to avoid incurring an
// unnecessary AddRef/Unref pair even though we will modify the object.
// We cannot use a normal reference because the compiler will warn
// since this is often used on a return value, which is a temporary.
@@ -462,51 +476,54 @@ class Callback<R(A1, A2, A3, A4, A5)> : public internal::CallbackBase {
// Note that this constructor CANNOT be explicit, and that Bind() CANNOT
// return the exact Callback<> type. See base/bind.h for details.
template <typename T>
- Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
- : CallbackBase(
- reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
- &invoker_holder.invoker_storage_) {
- COMPILE_ASSERT((is_same<PolymorphicInvoke,
- typename T::Invoker::DoInvokeType>::value),
- callback_type_does_not_match_bind_result);
+ Callback(const internal::BindStateHolder<T>& bind_state_holder)
+ : CallbackBase(NULL, &bind_state_holder.bind_state_) {
+ // Force the assignment to a location variable of PolymorphicInvoke
+ // so the compiler will typecheck that the passed in Run() method has
+ // the correct type.
+ PolymorphicInvoke invoke_func = &T::InvokerType::Run;
+ polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
}
bool Equals(const Callback& other) const {
return CallbackBase::Equals(other);
}
- R Run(typename internal::ParamTraits<A1>::ForwardType a1,
- typename internal::ParamTraits<A2>::ForwardType a2,
- typename internal::ParamTraits<A3>::ForwardType a3,
- typename internal::ParamTraits<A4>::ForwardType a4,
- typename internal::ParamTraits<A5>::ForwardType a5) const {
+ R Run(typename internal::CallbackParamTraits<A1>::ForwardType a1,
+ typename internal::CallbackParamTraits<A2>::ForwardType a2,
+ typename internal::CallbackParamTraits<A3>::ForwardType a3,
+ typename internal::CallbackParamTraits<A4>::ForwardType a4,
+ typename internal::CallbackParamTraits<A5>::ForwardType a5) const {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
- return f(invoker_storage_.get(), a1,
+ return f(bind_state_.get(), a1,
a2,
a3,
a4,
a5);
}
+
+ private:
+ typedef R(*PolymorphicInvoke)(
+ internal::BindStateBase*,
+ typename internal::CallbackParamTraits<A1>::ForwardType,
+ typename internal::CallbackParamTraits<A2>::ForwardType,
+ typename internal::CallbackParamTraits<A3>::ForwardType,
+ typename internal::CallbackParamTraits<A4>::ForwardType,
+ typename internal::CallbackParamTraits<A5>::ForwardType);
+
};
template <typename R, typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6>
class Callback<R(A1, A2, A3, A4, A5, A6)> : public internal::CallbackBase {
public:
- typedef R(*PolymorphicInvoke)(
- internal::InvokerStorageBase*,
- typename internal::ParamTraits<A1>::ForwardType,
- typename internal::ParamTraits<A2>::ForwardType,
- typename internal::ParamTraits<A3>::ForwardType,
- typename internal::ParamTraits<A4>::ForwardType,
- typename internal::ParamTraits<A5>::ForwardType,
- typename internal::ParamTraits<A6>::ForwardType);
+ typedef R(RunType)(A1, A2, A3, A4, A5, A6);
Callback() : CallbackBase(NULL, NULL) { }
- // We pass InvokerStorageHolder by const ref to avoid incurring an
+ // We pass BindStateHolder by const ref to avoid incurring an
// unnecessary AddRef/Unref pair even though we will modify the object.
// We cannot use a normal reference because the compiler will warn
// since this is often used on a return value, which is a temporary.
@@ -514,35 +531,46 @@ class Callback<R(A1, A2, A3, A4, A5, A6)> : public internal::CallbackBase {
// Note that this constructor CANNOT be explicit, and that Bind() CANNOT
// return the exact Callback<> type. See base/bind.h for details.
template <typename T>
- Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
- : CallbackBase(
- reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
- &invoker_holder.invoker_storage_) {
- COMPILE_ASSERT((is_same<PolymorphicInvoke,
- typename T::Invoker::DoInvokeType>::value),
- callback_type_does_not_match_bind_result);
+ Callback(const internal::BindStateHolder<T>& bind_state_holder)
+ : CallbackBase(NULL, &bind_state_holder.bind_state_) {
+ // Force the assignment to a location variable of PolymorphicInvoke
+ // so the compiler will typecheck that the passed in Run() method has
+ // the correct type.
+ PolymorphicInvoke invoke_func = &T::InvokerType::Run;
+ polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
}
bool Equals(const Callback& other) const {
return CallbackBase::Equals(other);
}
- R Run(typename internal::ParamTraits<A1>::ForwardType a1,
- typename internal::ParamTraits<A2>::ForwardType a2,
- typename internal::ParamTraits<A3>::ForwardType a3,
- typename internal::ParamTraits<A4>::ForwardType a4,
- typename internal::ParamTraits<A5>::ForwardType a5,
- typename internal::ParamTraits<A6>::ForwardType a6) const {
+ R Run(typename internal::CallbackParamTraits<A1>::ForwardType a1,
+ typename internal::CallbackParamTraits<A2>::ForwardType a2,
+ typename internal::CallbackParamTraits<A3>::ForwardType a3,
+ typename internal::CallbackParamTraits<A4>::ForwardType a4,
+ typename internal::CallbackParamTraits<A5>::ForwardType a5,
+ typename internal::CallbackParamTraits<A6>::ForwardType a6) const {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
- return f(invoker_storage_.get(), a1,
+ return f(bind_state_.get(), a1,
a2,
a3,
a4,
a5,
a6);
}
+
+ private:
+ typedef R(*PolymorphicInvoke)(
+ internal::BindStateBase*,
+ typename internal::CallbackParamTraits<A1>::ForwardType,
+ typename internal::CallbackParamTraits<A2>::ForwardType,
+ typename internal::CallbackParamTraits<A3>::ForwardType,
+ typename internal::CallbackParamTraits<A4>::ForwardType,
+ typename internal::CallbackParamTraits<A5>::ForwardType,
+ typename internal::CallbackParamTraits<A6>::ForwardType);
+
};
diff --git a/base/callback.h.pump b/base/callback.h.pump
index 8aecdc8..eee3371 100644
--- a/base/callback.h.pump
+++ b/base/callback.h.pump
@@ -129,26 +129,26 @@ $var MAX_ARITY = 6
// The Callback classes represent a generic function pointer. Internally,
// it stores a refcounted piece of state that represents the target function
// and all its bound parameters. Each Callback specialization has a templated
-// constructor that takes an InvokerStorageHolder<> object. In the context of
-// the constructor, the static type of this InvokerStorageHolder<> object
+// constructor that takes an BindStateHolder<> object. In the context of
+// the constructor, the static type of this BindStateHolder<> object
// uniquely identifies the function it is representing, all its bound
// parameters, and a DoInvoke() that is capable of invoking the target.
//
-// Callback's constructor is takes the InvokerStorageHolder<> that has the
+// Callback's constructor is takes the BindStateHolder<> that has the
// full static type and erases the target function type, and the bound
// parameters. It does this by storing a pointer to the specific DoInvoke()
-// function, and upcasting the state of InvokerStorageHolder<> to a
-// InvokerStorageBase. This is safe as long as this InvokerStorageBase pointer
+// function, and upcasting the state of BindStateHolder<> to a
+// BindStateBase. This is safe as long as this BindStateBase pointer
// is only used with the stored DoInvoke() pointer.
//
-// To create InvokerStorageHolder<> objects, we use the Bind() functions.
+// To create BindStateHolder<> objects, we use the Bind() functions.
// These functions, along with a set of internal templates, are reponsible for
//
// - Unwrapping the function signature into return type, and parameters
// - Determining the number of parameters that are bound
// - Creating the storage for the bound parameters
// - Performing compile-time asserts to avoid error-prone behavior
-// - Returning an InvokerStorageHolder<> with an DoInvoke() that has an arity
+// - Returning an BindStateHolder<> with an DoInvoke() that has an arity
// matching the number of unbound parameters, and knows the correct
// refcounting semantics for the target object if we are binding a class
// method.
@@ -250,14 +250,11 @@ class Callback<R($for ARG , [[A$(ARG)]])> : public internal::CallbackBase {
]]
public:
- typedef R(*PolymorphicInvoke)(
- internal::InvokerStorageBase*[[]]
-$if ARITY != 0 [[, ]]
-$for ARG , [[typename internal::ParamTraits<A$(ARG)>::ForwardType]]);
+ typedef R(RunType)($for ARG , [[A$(ARG)]]);
Callback() : CallbackBase(NULL, NULL) { }
- // We pass InvokerStorageHolder by const ref to avoid incurring an
+ // We pass BindStateHolder by const ref to avoid incurring an
// unnecessary AddRef/Unref pair even though we will modify the object.
// We cannot use a normal reference because the compiler will warn
// since this is often used on a return value, which is a temporary.
@@ -265,13 +262,13 @@ $for ARG , [[typename internal::ParamTraits<A$(ARG)>::ForwardType]]);
// Note that this constructor CANNOT be explicit, and that Bind() CANNOT
// return the exact Callback<> type. See base/bind.h for details.
template <typename T>
- Callback(const internal::InvokerStorageHolder<T>& invoker_holder)
- : CallbackBase(
- reinterpret_cast<InvokeFuncStorage>(&T::Invoker::DoInvoke),
- &invoker_holder.invoker_storage_) {
- COMPILE_ASSERT((is_same<PolymorphicInvoke,
- typename T::Invoker::DoInvokeType>::value),
- callback_type_does_not_match_bind_result);
+ Callback(const internal::BindStateHolder<T>& bind_state_holder)
+ : CallbackBase(NULL, &bind_state_holder.bind_state_) {
+ // Force the assignment to a location variable of PolymorphicInvoke
+ // so the compiler will typecheck that the passed in Run() method has
+ // the correct type.
+ PolymorphicInvoke invoke_func = &T::InvokerType::Run;
+ polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
}
bool Equals(const Callback& other) const {
@@ -279,15 +276,22 @@ $for ARG , [[typename internal::ParamTraits<A$(ARG)>::ForwardType]]);
}
R Run($for ARG ,
- [[typename internal::ParamTraits<A$(ARG)>::ForwardType a$(ARG)]]) const {
+ [[typename internal::CallbackParamTraits<A$(ARG)>::ForwardType a$(ARG)]]) const {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
- return f(invoker_storage_.get()[[]]
+ return f(bind_state_.get()[[]]
$if ARITY != 0 [[, ]]
$for ARG ,
[[a$(ARG)]]);
}
+
+ private:
+ typedef R(*PolymorphicInvoke)(
+ internal::BindStateBase*[[]]
+$if ARITY != 0 [[, ]]
+$for ARG , [[typename internal::CallbackParamTraits<A$(ARG)>::ForwardType]]);
+
};
diff --git a/base/callback_internal.cc b/base/callback_internal.cc
index d9d1e6f..582fbdc 100644
--- a/base/callback_internal.cc
+++ b/base/callback_internal.cc
@@ -8,24 +8,24 @@ namespace base {
namespace internal {
bool CallbackBase::is_null() const {
- return invoker_storage_.get() == NULL;
+ return bind_state_.get() == NULL;
}
void CallbackBase::Reset() {
- invoker_storage_ = NULL;
+ bind_state_ = NULL;
polymorphic_invoke_ = NULL;
}
bool CallbackBase::Equals(const CallbackBase& other) const {
- return invoker_storage_.get() == other.invoker_storage_.get() &&
+ return bind_state_.get() == other.bind_state_.get() &&
polymorphic_invoke_ == other.polymorphic_invoke_;
}
CallbackBase::CallbackBase(InvokeFuncStorage polymorphic_invoke,
- scoped_refptr<InvokerStorageBase>* invoker_storage)
+ scoped_refptr<BindStateBase>* bind_state)
: polymorphic_invoke_(polymorphic_invoke) {
- if (invoker_storage) {
- invoker_storage_.swap(*invoker_storage);
+ if (bind_state) {
+ bind_state_.swap(*bind_state);
}
}
diff --git a/base/callback_internal.h b/base/callback_internal.h
index 4f0736f..81c87c0 100644
--- a/base/callback_internal.h
+++ b/base/callback_internal.h
@@ -17,39 +17,39 @@
namespace base {
namespace internal {
-// InvokerStorageBase is used to provide an opaque handle that the Callback
+// BindStateBase is used to provide an opaque handle that the Callback
// class can use to represent a function object with bound arguments. It
// behaves as an existential type that is used by a corresponding
// DoInvoke function to perform the function execution. This allows
// us to shield the Callback class from the types of the bound argument via
// "type erasure."
-class InvokerStorageBase : public RefCountedThreadSafe<InvokerStorageBase> {
+class BindStateBase : public RefCountedThreadSafe<BindStateBase> {
protected:
- friend class RefCountedThreadSafe<InvokerStorageBase>;
- virtual ~InvokerStorageBase() {}
+ friend class RefCountedThreadSafe<BindStateBase>;
+ virtual ~BindStateBase() {}
};
-// This structure exists purely to pass the returned |invoker_storage_| from
+// This structure exists purely to pass the returned |bind_state_| from
// Bind() to Callback while avoiding an extra AddRef/Release() pair.
//
// To do this, the constructor of Callback<> must take a const-ref. The
// reference must be to a const object otherwise the compiler will emit a
// warning about taking a reference to a temporary.
//
-// Unfortunately, this means that the internal |invoker_storage_| field must
+// Unfortunately, this means that the internal |bind_state_| field must
// be made mutable.
template <typename T>
-struct InvokerStorageHolder {
- explicit InvokerStorageHolder(T* invoker_storage)
- : invoker_storage_(invoker_storage) {
+struct BindStateHolder {
+ explicit BindStateHolder(T* bind_state)
+ : bind_state_(bind_state) {
}
- mutable scoped_refptr<InvokerStorageBase> invoker_storage_;
+ mutable scoped_refptr<BindStateBase> bind_state_;
};
template <typename T>
-InvokerStorageHolder<T> MakeInvokerStorageHolder(T* o) {
- return InvokerStorageHolder<T>(o);
+BindStateHolder<T> MakeBindStateHolder(T* o) {
+ return BindStateHolder<T>(o);
}
// Holds the Callback methods that don't require specialization to reduce
@@ -73,14 +73,14 @@ class BASE_EXPORT CallbackBase {
bool Equals(const CallbackBase& other) const;
CallbackBase(InvokeFuncStorage polymorphic_invoke,
- scoped_refptr<InvokerStorageBase>* invoker_storage);
+ scoped_refptr<BindStateBase>* bind_state);
// Force the destructor to be instantiated inside this translation unit so
// that our subclasses will not get inlined versions. Avoids more template
// bloat.
~CallbackBase();
- scoped_refptr<InvokerStorageBase> invoker_storage_;
+ scoped_refptr<BindStateBase> bind_state_;
InvokeFuncStorage polymorphic_invoke_;
};
@@ -96,7 +96,7 @@ class BASE_EXPORT CallbackBase {
// array type in the initializer list which C++ does not allow. This will
// break passing of C-string literals.
template <typename T>
-struct ParamTraits {
+struct CallbackParamTraits {
typedef const T& ForwardType;
typedef T StorageType;
};
@@ -107,7 +107,7 @@ struct ParamTraits {
//
// The ForwardType should only be used for unbound arguments.
template <typename T>
-struct ParamTraits<T&> {
+struct CallbackParamTraits<T&> {
typedef T& ForwardType;
typedef T StorageType;
};
@@ -118,14 +118,14 @@ struct ParamTraits<T&> {
// T[n]" does not seem to match correctly, so we are stuck with this
// restriction.
template <typename T, size_t n>
-struct ParamTraits<T[n]> {
+struct CallbackParamTraits<T[n]> {
typedef const T* ForwardType;
typedef const T* StorageType;
};
-// See comment for ParamTraits<T[n]>.
+// See comment for CallbackParamTraits<T[n]>.
template <typename T>
-struct ParamTraits<T[]> {
+struct CallbackParamTraits<T[]> {
typedef const T* ForwardType;
typedef const T* StorageType;
};
diff --git a/base/callback_unittest.cc b/base/callback_unittest.cc
index 713c9e48..33157ae 100644
--- a/base/callback_unittest.cc
+++ b/base/callback_unittest.cc
@@ -23,21 +23,21 @@ class HelperObject {
};
struct FakeInvoker {
- typedef void(*DoInvokeType)(internal::InvokerStorageBase*);
- static void DoInvoke(internal::InvokerStorageBase*) {
+ typedef void(RunType)(internal::BindStateBase*);
+ static void Run(internal::BindStateBase*) {
}
};
// White-box testpoints to inject into a Callback<> object for checking
// comparators and emptiness APIs.
-class FakeInvokerStorage1 : public internal::InvokerStorageBase {
+class FakeBindState1 : public internal::BindStateBase {
public:
- typedef FakeInvoker Invoker;
+ typedef FakeInvoker InvokerType;
};
-class FakeInvokerStorage2 : public internal::InvokerStorageBase {
+class FakeBindState2 : public internal::BindStateBase {
public:
- typedef FakeInvoker Invoker;
+ typedef FakeInvoker InvokerType;
};
TEST(CallbackOld, OneArg) {
@@ -61,8 +61,8 @@ TEST(CallbackOld, ReturnValue) {
class CallbackTest : public ::testing::Test {
public:
CallbackTest()
- : callback_a_(MakeInvokerStorageHolder(new FakeInvokerStorage1())),
- callback_b_(MakeInvokerStorageHolder(new FakeInvokerStorage2())) {
+ : callback_a_(MakeBindStateHolder(new FakeBindState1())),
+ callback_b_(MakeBindStateHolder(new FakeBindState2())) {
}
virtual ~CallbackTest() {
@@ -107,7 +107,7 @@ TEST_F(CallbackTest, Equals) {
// We should compare based on instance, not type.
Callback<void(void)> callback_c(
- MakeInvokerStorageHolder(new FakeInvokerStorage1()));
+ MakeBindStateHolder(new FakeBindState1()));
Callback<void(void)> callback_a2 = callback_a_;
EXPECT_TRUE(callback_a_.Equals(callback_a2));
EXPECT_FALSE(callback_a_.Equals(callback_c));
diff --git a/base/file_util_proxy.cc b/base/file_util_proxy.cc
index 9b51d34..0873c9c 100644
--- a/base/file_util_proxy.cc
+++ b/base/file_util_proxy.cc
@@ -112,7 +112,8 @@ class CreateOrOpenHelper {
~CreateOrOpenHelper() {
if (file_handle_ != kInvalidPlatformFileValue) {
message_loop_proxy_->PostTask(
- FROM_HERE, base::Bind(close_task_, file_handle_));
+ FROM_HERE,
+ base::Bind(base::IgnoreResult(close_task_), file_handle_));
}
}
diff --git a/base/task_unittest.cc b/base/task_unittest.cc
index d7d31fa..f192415 100644
--- a/base/task_unittest.cc
+++ b/base/task_unittest.cc
@@ -115,7 +115,7 @@ void Increment(int* value) {
TEST(TaskTest, TestScopedClosureRunnerExitScope) {
int run_count = 0;
{
- base::ScopedClosureRunner runner(base::Bind(Increment, &run_count));
+ base::ScopedClosureRunner runner(base::Bind(&Increment, &run_count));
EXPECT_EQ(0, run_count);
}
EXPECT_EQ(1, run_count);
@@ -125,7 +125,7 @@ TEST(TaskTest, TestScopedClosureRunnerRelease) {
int run_count = 0;
base::Closure c;
{
- base::ScopedClosureRunner runner(base::Bind(Increment, &run_count));
+ base::ScopedClosureRunner runner(base::Bind(&Increment, &run_count));
c = runner.Release();
EXPECT_EQ(0, run_count);
}
diff --git a/base/template_util.h b/base/template_util.h
index f19fb4b..916e942 100644
--- a/base/template_util.h
+++ b/base/template_util.h
@@ -70,7 +70,7 @@ struct ConvertHelper {
static NoType Test(...);
template <typename From>
- static From Create();
+ static From& Create();
};
// Used to determine if a type is a struct/union/class. Inspired by Boost's
diff --git a/base/template_util_unittest.cc b/base/template_util_unittest.cc
index daf83b6..b330a01 100644
--- a/base/template_util_unittest.cc
+++ b/base/template_util_unittest.cc
@@ -51,6 +51,12 @@ TEST(TemplateUtilTest, IsConvertible) {
EXPECT_TRUE( (is_convertible<int, double>::value) );
EXPECT_TRUE( (is_convertible<int*, void*>::value) );
EXPECT_FALSE( (is_convertible<void*, int*>::value) );
+
+ // Array types are an easy corner case. Make sure to test that
+ // it does indeed compile.
+ EXPECT_FALSE( (is_convertible<int[10], double>::value) );
+ EXPECT_FALSE( (is_convertible<double, int[10]>::value) );
+ EXPECT_TRUE( (is_convertible<int[10], int*>::value) );
}
TEST(TemplateUtilTest, IsSame) {
diff --git a/build/nocompile.gypi b/build/nocompile.gypi
index ef142b9..88dffc7 100644
--- a/build/nocompile.gypi
+++ b/build/nocompile.gypi
@@ -57,7 +57,6 @@
# least processed when things go right.
{
- 'sources/': [['exclude', '\\.nc$']],
'conditions': [
[ 'OS=="linux" and clang==0', {
'rules': [
diff --git a/chrome/browser/chrome_browser_main_x11.cc b/chrome/browser/chrome_browser_main_x11.cc
index 8448ed5..55968ca 100644
--- a/chrome/browser/chrome_browser_main_x11.cc
+++ b/chrome/browser/chrome_browser_main_x11.cc
@@ -33,7 +33,7 @@ int BrowserX11ErrorHandler(Display* d, XErrorEvent* error) {
if (!g_in_x11_io_error_handler)
MessageLoop::current()->PostTask(
FROM_HERE,
- base::Bind(ui::LogErrorEventDescription, d, *error));
+ base::Bind(&ui::LogErrorEventDescription, d, *error));
return 0;
}
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 854ef8b..d51c3f6 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -554,7 +554,7 @@ bool ExtensionService::UpdateExtension(
if (!BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
base::Bind(
- extension_file_util::DeleteFile, extension_path, false)))
+ &extension_file_util::DeleteFile, extension_path, false)))
NOTREACHED();
return false;
diff --git a/chrome/browser/extensions/extension_updater.cc b/chrome/browser/extensions/extension_updater.cc
index 433e9e0..ff1b8ce 100644
--- a/chrome/browser/extensions/extension_updater.cc
+++ b/chrome/browser/extensions/extension_updater.cc
@@ -108,7 +108,7 @@ void RecordCRXWriteHistogram(bool success, const FilePath& crx_path) {
// can not be read. Try reading.
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
- base::Bind(CheckThatCRXIsReadable, crx_path));
+ base::Bind(&CheckThatCRXIsReadable, crx_path));
}
}
@@ -128,7 +128,7 @@ void CheckThatCRXIsReadable(const FilePath& crx_path) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::Bind(RecordFileUpdateHistogram, file_write_result));
+ base::Bind(&RecordFileUpdateHistogram, file_write_result));
}
void RecordFileUpdateHistogram(FileWriteResult file_write_result) {
diff --git a/chrome/browser/net/net_pref_observer.cc b/chrome/browser/net/net_pref_observer.cc
index 0eb83344..198a993 100644
--- a/chrome/browser/net/net_pref_observer.cc
+++ b/chrome/browser/net/net_pref_observer.cc
@@ -71,7 +71,7 @@ void NetPrefObserver::ApplySettings(const std::string* pref_name) {
if (!pref_name || *pref_name == prefs::kHttpThrottlingEnabled) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- base::Bind(SetEnforceThrottlingOnThrottlerManager,
+ base::Bind(&SetEnforceThrottlingOnThrottlerManager,
*http_throttling_enabled_));
}
}
diff --git a/chrome/browser/net/predictor.cc b/chrome/browser/net/predictor.cc
index c36d3f6..54c03fa 100644
--- a/chrome/browser/net/predictor.cc
+++ b/chrome/browser/net/predictor.cc
@@ -799,7 +799,7 @@ void Predictor::SaveStateForNextStartupAndTrim(PrefService* prefs) {
BrowserThread::IO,
FROM_HERE,
base::Bind(
- SaveDnsPrefetchStateForNextStartupAndTrimOnIOThread,
+ &SaveDnsPrefetchStateForNextStartupAndTrimOnIOThread,
update_startup_list.Get(),
update_referral_list.Get(),
&completion,
diff --git a/chrome/browser/password_manager/password_store_x.cc b/chrome/browser/password_manager/password_store_x.cc
index 94b27bc..fe9640d 100644
--- a/chrome/browser/password_manager/password_store_x.cc
+++ b/chrome/browser/password_manager/password_store_x.cc
@@ -299,6 +299,6 @@ void PasswordStoreX::SetPasswordsUseLocalProfileId(PrefService* prefs) {
// This method should work on any thread, but we expect the DB thread.
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(UISetPasswordsUseLocalProfileId, prefs));
+ base::Bind(&UISetPasswordsUseLocalProfileId, prefs));
}
#endif // !defined(OS_MACOSX) && !defined(OS_CHROMEOS) && defined(OS_POSIX)
diff --git a/chrome/common/profiling.cc b/chrome/common/profiling.cc
index 946f54f..1173992 100644
--- a/chrome/common/profiling.cc
+++ b/chrome/common/profiling.cc
@@ -54,7 +54,7 @@ void FlushProfilingData(base::Thread* thread) {
}
}
thread->message_loop()->PostDelayedTask(
- FROM_HERE, base::Bind(FlushProfilingData, thread), flush_seconds * 1000);
+ FROM_HERE, base::Bind(&FlushProfilingData, thread), flush_seconds * 1000);
}
class ProfilingThreadControl {
@@ -69,7 +69,7 @@ class ProfilingThreadControl {
thread_ = new base::Thread("Profiling_Flush");
thread_->Start();
thread_->message_loop()->PostTask(
- FROM_HERE, base::Bind(FlushProfilingData, thread_));
+ FROM_HERE, base::Bind(&FlushProfilingData, thread_));
}
void Stop() {
diff --git a/content/browser/cancelable_request.h b/content/browser/cancelable_request.h
index 9a986d8..0b5c5e1 100644
--- a/content/browser/cancelable_request.h
+++ b/content/browser/cancelable_request.h
@@ -776,13 +776,14 @@ class CancelableRequest<base::Callback<void(A1)> > :
DCHECK(!callback.is_null()) << "Callback must be initialized.";
}
- void ForwardResult(typename base::internal::ParamTraits<A1>::ForwardType a1) {
+ void ForwardResult(
+ typename base::internal::CallbackParamTraits<A1>::ForwardType a1) {
if (canceled()) return;
DoForward(base::Bind(callback_, a1), false);
}
void ForwardResultAsync(
- typename base::internal::ParamTraits<A1>::ForwardType a1) {
+ typename base::internal::CallbackParamTraits<A1>::ForwardType a1) {
if (canceled()) return;
DoForward(base::Bind(callback_, a1), true);
}
@@ -806,15 +807,16 @@ class CancelableRequest<base::Callback<void(A1,A2)> > :
DCHECK(!callback.is_null()) << "Callback must be initialized.";
}
- void ForwardResult(typename base::internal::ParamTraits<A1>::ForwardType a1,
- typename base::internal::ParamTraits<A2>::ForwardType a2) {
+ void ForwardResult(
+ typename base::internal::CallbackParamTraits<A1>::ForwardType a1,
+ typename base::internal::CallbackParamTraits<A2>::ForwardType a2) {
if (canceled()) return;
DoForward(base::Bind(callback_, a1, a2), false);
}
void ForwardResultAsync(
- typename base::internal::ParamTraits<A1>::ForwardType a1,
- typename base::internal::ParamTraits<A2>::ForwardType a2) {
+ typename base::internal::CallbackParamTraits<A1>::ForwardType a1,
+ typename base::internal::CallbackParamTraits<A2>::ForwardType a2) {
if (canceled()) return;
DoForward(base::Bind(callback_, a1, a2), true);
}
@@ -838,17 +840,18 @@ class CancelableRequest<base::Callback<void(A1,A2,A3)> > :
DCHECK(!callback.is_null()) << "Callback must be initialized.";
}
- void ForwardResult(typename base::internal::ParamTraits<A1>::ForwardType a1,
- typename base::internal::ParamTraits<A2>::ForwardType a2,
- typename base::internal::ParamTraits<A3>::ForwardType a3) {
+ void ForwardResult(
+ typename base::internal::CallbackParamTraits<A1>::ForwardType a1,
+ typename base::internal::CallbackParamTraits<A2>::ForwardType a2,
+ typename base::internal::CallbackParamTraits<A3>::ForwardType a3) {
if (canceled()) return;
DoForward(base::Bind(callback_, a1, a2, a3), false);
}
void ForwardResultAsync(
- typename base::internal::ParamTraits<A1>::ForwardType a1,
- typename base::internal::ParamTraits<A2>::ForwardType a2,
- typename base::internal::ParamTraits<A3>::ForwardType a3) {
+ typename base::internal::CallbackParamTraits<A1>::ForwardType a1,
+ typename base::internal::CallbackParamTraits<A2>::ForwardType a2,
+ typename base::internal::CallbackParamTraits<A3>::ForwardType a3) {
if (canceled()) return;
DoForward(base::Bind(callback_, a1, a2, a3), true);
}
@@ -872,19 +875,20 @@ class CancelableRequest<base::Callback<void(A1, A2, A3, A4)> > :
DCHECK(!callback.is_null()) << "Callback must be initialized.";
}
- void ForwardResult(typename base::internal::ParamTraits<A1>::ForwardType a1,
- typename base::internal::ParamTraits<A2>::ForwardType a2,
- typename base::internal::ParamTraits<A3>::ForwardType a3,
- typename base::internal::ParamTraits<A4>::ForwardType a4) {
+ void ForwardResult(
+ typename base::internal::CallbackParamTraits<A1>::ForwardType a1,
+ typename base::internal::CallbackParamTraits<A2>::ForwardType a2,
+ typename base::internal::CallbackParamTraits<A3>::ForwardType a3,
+ typename base::internal::CallbackParamTraits<A4>::ForwardType a4) {
if (canceled()) return;
DoForward(base::Bind(callback_, a1, a2, a3, a4), false);
}
void ForwardResultAsync(
- typename base::internal::ParamTraits<A1>::ForwardType a1,
- typename base::internal::ParamTraits<A2>::ForwardType a2,
- typename base::internal::ParamTraits<A3>::ForwardType a3,
- typename base::internal::ParamTraits<A4>::ForwardType a4) {
+ typename base::internal::CallbackParamTraits<A1>::ForwardType a1,
+ typename base::internal::CallbackParamTraits<A2>::ForwardType a2,
+ typename base::internal::CallbackParamTraits<A3>::ForwardType a3,
+ typename base::internal::CallbackParamTraits<A4>::ForwardType a4) {
if (canceled()) return;
DoForward(base::Bind(callback_, a1, a2, a3, a4), true);
}
@@ -908,21 +912,22 @@ class CancelableRequest<base::Callback<void(A1, A2, A3, A4, A5)> > :
DCHECK(!callback.is_null()) << "Callback must be initialized.";
}
- void ForwardResult(typename base::internal::ParamTraits<A1>::ForwardType a1,
- typename base::internal::ParamTraits<A2>::ForwardType a2,
- typename base::internal::ParamTraits<A3>::ForwardType a3,
- typename base::internal::ParamTraits<A4>::ForwardType a4,
- typename base::internal::ParamTraits<A5>::ForwardType a5) {
+ void ForwardResult(
+ typename base::internal::CallbackParamTraits<A1>::ForwardType a1,
+ typename base::internal::CallbackParamTraits<A2>::ForwardType a2,
+ typename base::internal::CallbackParamTraits<A3>::ForwardType a3,
+ typename base::internal::CallbackParamTraits<A4>::ForwardType a4,
+ typename base::internal::CallbackParamTraits<A5>::ForwardType a5) {
if (canceled()) return;
DoForward(base::Bind(callback_, a1, a2, a3, a4, a5), false);
}
void ForwardResultAsync(
- typename base::internal::ParamTraits<A1>::ForwardType a1,
- typename base::internal::ParamTraits<A2>::ForwardType a2,
- typename base::internal::ParamTraits<A3>::ForwardType a3,
- typename base::internal::ParamTraits<A4>::ForwardType a4,
- typename base::internal::ParamTraits<A5>::ForwardType a5) {
+ typename base::internal::CallbackParamTraits<A1>::ForwardType a1,
+ typename base::internal::CallbackParamTraits<A2>::ForwardType a2,
+ typename base::internal::CallbackParamTraits<A3>::ForwardType a3,
+ typename base::internal::CallbackParamTraits<A4>::ForwardType a4,
+ typename base::internal::CallbackParamTraits<A5>::ForwardType a5) {
if (canceled()) return;
DoForward(base::Bind(callback_, a1, a2, a3, a4, a5), true);
}
@@ -947,23 +952,24 @@ class CancelableRequest<base::Callback<void(A1, A2, A3, A4, A5, A6)> > :
DCHECK(!callback.is_null()) << "Callback must be initialized.";
}
- void ForwardResult(typename base::internal::ParamTraits<A1>::ForwardType a1,
- typename base::internal::ParamTraits<A2>::ForwardType a2,
- typename base::internal::ParamTraits<A3>::ForwardType a3,
- typename base::internal::ParamTraits<A4>::ForwardType a4,
- typename base::internal::ParamTraits<A5>::ForwardType a5,
- typename base::internal::ParamTraits<A6>::ForwardType a6) {
+ void ForwardResult(
+ typename base::internal::CallbackParamTraits<A1>::ForwardType a1,
+ typename base::internal::CallbackParamTraits<A2>::ForwardType a2,
+ typename base::internal::CallbackParamTraits<A3>::ForwardType a3,
+ typename base::internal::CallbackParamTraits<A4>::ForwardType a4,
+ typename base::internal::CallbackParamTraits<A5>::ForwardType a5,
+ typename base::internal::CallbackParamTraits<A6>::ForwardType a6) {
if (canceled()) return;
DoForward(base::Bind(callback_, a1, a2, a3, a4, a5, a6), false);
}
void ForwardResultAsync(
- typename base::internal::ParamTraits<A1>::ForwardType a1,
- typename base::internal::ParamTraits<A2>::ForwardType a2,
- typename base::internal::ParamTraits<A3>::ForwardType a3,
- typename base::internal::ParamTraits<A4>::ForwardType a4,
- typename base::internal::ParamTraits<A5>::ForwardType a5,
- typename base::internal::ParamTraits<A6>::ForwardType a6) {
+ typename base::internal::CallbackParamTraits<A1>::ForwardType a1,
+ typename base::internal::CallbackParamTraits<A2>::ForwardType a2,
+ typename base::internal::CallbackParamTraits<A3>::ForwardType a3,
+ typename base::internal::CallbackParamTraits<A4>::ForwardType a4,
+ typename base::internal::CallbackParamTraits<A5>::ForwardType a5,
+ typename base::internal::CallbackParamTraits<A6>::ForwardType a6) {
if (canceled()) return;
DoForward(base::Bind(callback_, a1, a2, a3, a4, a5, a6), true);
}
diff --git a/content/browser/debugger/worker_devtools_manager.cc b/content/browser/debugger/worker_devtools_manager.cc
index a2f2f22..371314c 100644
--- a/content/browser/debugger/worker_devtools_manager.cc
+++ b/content/browser/debugger/worker_devtools_manager.cc
@@ -205,7 +205,7 @@ class WorkerDevToolsManager::DetachedClientHosts {
static void RemovePendingWorkerData(WorkerId id) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- base::Bind(RemoveInspectedWorkerDataOnIOThread, id));
+ base::Bind(&RemoveInspectedWorkerDataOnIOThread, id));
}
static void RemoveInspectedWorkerDataOnIOThread(WorkerId id) {
@@ -303,7 +303,7 @@ void WorkerDevToolsManager::WorkerDestroyed(
inspected_workers_.erase(it);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::Bind(DetachedClientHosts::WorkerDestroyed, worker_id));
+ base::Bind(&DetachedClientHosts::WorkerDestroyed, worker_id));
}
void WorkerDevToolsManager::WorkerContextStarted(WorkerProcessHost* process,
@@ -316,7 +316,7 @@ void WorkerDevToolsManager::WorkerContextStarted(WorkerProcessHost* process,
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(
- DetachedClientHosts::WorkerReloaded,
+ &DetachedClientHosts::WorkerReloaded,
it->second,
new_worker_id));
paused_workers_.erase(it);
@@ -394,7 +394,7 @@ void WorkerDevToolsManager::ForwardToDevToolsClient(
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(
- ForwardToDevToolsClientOnUIThread,
+ &ForwardToDevToolsClientOnUIThread,
worker_process_id,
worker_route_id,
message));
@@ -406,7 +406,7 @@ void WorkerDevToolsManager::SaveAgentRuntimeState(int worker_process_id,
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(
- SaveAgentRuntimeStateOnUIThread,
+ &SaveAgentRuntimeStateOnUIThread,
worker_process_id,
worker_route_id,
state));
@@ -479,4 +479,3 @@ void WorkerDevToolsManager::SendResumeToWorker(const WorkerId& id) {
if (WorkerProcessHost* process = FindWorkerProcess(id.first))
process->Send(new DevToolsAgentMsg_ResumeWorkerContext(id.second));
}
-
diff --git a/content/browser/plugin_service_browsertest.cc b/content/browser/plugin_service_browsertest.cc
index c8f8e1e..8c2666d 100644
--- a/content/browser/plugin_service_browsertest.cc
+++ b/content/browser/plugin_service_browsertest.cc
@@ -247,7 +247,7 @@ IN_PROC_BROWSER_TEST_F(
mock_client(browser()->profile()->GetResourceContext());
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- base::Bind(OpenChannel, &mock_client));
+ base::Bind(&OpenChannel, &mock_client));
ui_test_utils::RunMessageLoop();
EXPECT_TRUE(mock_client.get_resource_context_called());
EXPECT_TRUE(mock_client.set_plugin_info_called());
@@ -299,7 +299,7 @@ IN_PROC_BROWSER_TEST_F(
mock_client(browser()->profile()->GetResourceContext());
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- base::Bind(OpenChannel, &mock_client));
+ base::Bind(&OpenChannel, &mock_client));
ui_test_utils::RunMessageLoop();
EXPECT_TRUE(mock_client.get_resource_context_called());
EXPECT_TRUE(mock_client.set_plugin_info_called());
diff --git a/content/renderer/render_widget_fullscreen_pepper.cc b/content/renderer/render_widget_fullscreen_pepper.cc
index 9fe688d..ce90c30 100644
--- a/content/renderer/render_widget_fullscreen_pepper.cc
+++ b/content/renderer/render_widget_fullscreen_pepper.cc
@@ -497,7 +497,7 @@ void RenderWidgetFullscreenPepper::OnLostContext(
// created when the plugin recreates its own.
MessageLoop::current()->PostTask(
FROM_HERE,
- base::Bind(DestroyContext, context_, program_, buffer_));
+ base::Bind(&DestroyContext, context_, program_, buffer_));
context_ = NULL;
program_ = 0;
buffer_ = 0;
diff --git a/media/tools/player_x11/player_x11.cc b/media/tools/player_x11/player_x11.cc
index 7676eef..0a9f2066 100644
--- a/media/tools/player_x11/player_x11.cc
+++ b/media/tools/player_x11/player_x11.cc
@@ -189,7 +189,7 @@ void PeriodicalUpdate(
}
message_loop->PostDelayedTask(FROM_HERE, base::Bind(
- PeriodicalUpdate, make_scoped_refptr(pipeline),
+ &PeriodicalUpdate, make_scoped_refptr(pipeline),
message_loop, audio_only), 10);
}
@@ -250,7 +250,7 @@ int main(int argc, char** argv) {
audio_only = !pipeline->HasVideo();
message_loop.PostTask(FROM_HERE, base::Bind(
- PeriodicalUpdate, pipeline, &message_loop, audio_only));
+ &PeriodicalUpdate, pipeline, &message_loop, audio_only));
message_loop.Run();
} else{
std::cout << "Pipeline initialization failed..." << std::endl;
diff --git a/remoting/protocol/jingle_session_unittest.cc b/remoting/protocol/jingle_session_unittest.cc
index a4de003..35577fc 100644
--- a/remoting/protocol/jingle_session_unittest.cc
+++ b/remoting/protocol/jingle_session_unittest.cc
@@ -83,7 +83,7 @@ void OnTimeoutTerminateThread(bool* timeout) {
bool RunMessageLoopWithTimeout(int timeout_ms) {
bool timeout = false;
MessageLoop::current()->PostDelayedTask(
- FROM_HERE, base::Bind(OnTimeoutTerminateThread, &timeout), timeout_ms);
+ FROM_HERE, base::Bind(&OnTimeoutTerminateThread, &timeout), timeout_ms);
MessageLoop::current()->Run();
return !timeout;
}