summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-24 02:02:17 +0000
committerajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-24 02:02:17 +0000
commitc18b1056be790c55f10e407a1f6a3706bff7df03 (patch)
tree7ed333791fc8dfeaef29c07307e8efcfa1b44fba
parentb2e900f755ea4e66b5f41413716ecb55720e354d (diff)
downloadchromium_src-c18b1056be790c55f10e407a1f6a3706bff7df03.zip
chromium_src-c18b1056be790c55f10e407a1f6a3706bff7df03.tar.gz
chromium_src-c18b1056be790c55f10e407a1f6a3706bff7df03.tar.bz2
Callback support for unbound reference and array arguments.
Because the callback object uses const An& for the type of the Run() function in argument forwarding, the code breaks for An=T& or An=T[]. This CL adds in code to modify the parameter type to remove duplicate references, and other fun. BUG=35223 TEST=new unittests Review URL: http://codereview.chromium.org/6718021 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79239 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/bind_helpers.h43
-rw-r--r--base/bind_internal.h795
-rw-r--r--base/bind_internal.h.pump67
-rw-r--r--base/bind_internal_win.h55
-rw-r--r--base/bind_internal_win.h.pump20
-rw-r--r--base/bind_unittest.cc38
-rw-r--r--base/callback.h100
-rw-r--r--base/callback.h.pump8
-rw-r--r--base/callback_internal.h46
9 files changed, 648 insertions, 524 deletions
diff --git a/base/bind_helpers.h b/base/bind_helpers.h
index c1ca3d7..92194e7 100644
--- a/base/bind_helpers.h
+++ b/base/bind_helpers.h
@@ -161,7 +161,11 @@ struct UnsafeBindtoRefCountedArgHelper<true, T>
};
template <typename T>
-struct UnsafeBindtoRefCountedArg
+struct UnsafeBindtoRefCountedArg : false_type {
+};
+
+template <typename T>
+struct UnsafeBindtoRefCountedArg<T*>
: UnsafeBindtoRefCountedArgHelper<is_class<T>::value, T> {
};
@@ -233,43 +237,6 @@ struct MaybeRefcount<base::true_type, const T*> {
static void Release(const T* o) { o->Release(); }
};
-
-// This is a typetraits object that's used to convert an argument type into a
-// type suitable for storage. In particular, it strips off references, and
-// converts arrays to pointers.
-//
-// This array type becomes an issue because we are passing bound parameters by
-// const reference. In this case, we end up passing an actual array type in the
-// initializer list which C++ does not allow. This will break passing of
-// C-string literals.
-template <typename T>
-struct BindType {
- typedef T StorageType;
-};
-
-// This should almost be impossible to trigger unless someone manually
-// specifies type of the bind parameters. However, in case they do,
-// this will guard against us accidentally storing a reference parameter.
-template <typename T>
-struct BindType<T&> {
- typedef T StorageType;
-};
-
-// Note that for array types, we implicitly add a const in the conversion. This
-// means that it is not possible to bind array arguments to functions that take
-// a non-const pointer. Trying to specialize the template based on a "const
-// T[n]" does not seem to match correctly, so we are stuck with this
-// restriction.
-template <typename T, size_t n>
-struct BindType<T[n]> {
- typedef const T* StorageType;
-};
-
-template <typename T>
-struct BindType<T[]> {
- typedef const T* StorageType;
-};
-
} // namespace internal
template <typename T>
diff --git a/base/bind_internal.h b/base/bind_internal.h
index bb5f46f..606e2b0 100644
--- a/base/bind_internal.h
+++ b/base/bind_internal.h
@@ -3,6 +3,7 @@
// DO NOT EDIT BY HAND!!!
+
// 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.
@@ -73,6 +74,7 @@ template <typename R>
struct FunctionTraits<R(*)()> {
typedef R (*NormalizedSig)();
typedef false_type IsMethod;
+
};
// Method: Arity 0.
@@ -80,6 +82,10 @@ template <typename R, typename T>
struct FunctionTraits<R(T::*)()> {
typedef R (T::*NormalizedSig)();
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+
};
// Const Method: Arity 0.
@@ -87,6 +93,10 @@ template <typename R, typename T>
struct FunctionTraits<R(T::*)() const> {
typedef R (T::*NormalizedSig)();
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+
};
// Function: Arity 1.
@@ -94,6 +104,9 @@ template <typename R, typename X1>
struct FunctionTraits<R(*)(X1)> {
typedef R (*NormalizedSig)(X1);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+
};
// Method: Arity 1.
@@ -101,6 +114,11 @@ template <typename R, typename T, typename X1>
struct FunctionTraits<R(T::*)(X1)> {
typedef R (T::*NormalizedSig)(X1);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+ typedef X1 B2;
+
};
// Const Method: Arity 1.
@@ -108,6 +126,11 @@ template <typename R, typename T, typename X1>
struct FunctionTraits<R(T::*)(X1) const> {
typedef R (T::*NormalizedSig)(X1);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+ typedef X1 B2;
+
};
// Function: Arity 2.
@@ -115,6 +138,10 @@ template <typename R, typename X1, typename X2>
struct FunctionTraits<R(*)(X1, X2)> {
typedef R (*NormalizedSig)(X1, X2);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+
};
// Method: Arity 2.
@@ -122,6 +149,12 @@ template <typename R, typename T, typename X1, typename X2>
struct FunctionTraits<R(T::*)(X1, X2)> {
typedef R (T::*NormalizedSig)(X1, X2);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+ typedef X1 B2;
+ typedef X2 B3;
+
};
// Const Method: Arity 2.
@@ -129,6 +162,12 @@ template <typename R, typename T, typename X1, typename X2>
struct FunctionTraits<R(T::*)(X1, X2) const> {
typedef R (T::*NormalizedSig)(X1, X2);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+ typedef X1 B2;
+ typedef X2 B3;
+
};
// Function: Arity 3.
@@ -136,6 +175,11 @@ 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;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
+
};
// Method: Arity 3.
@@ -143,6 +187,13 @@ 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);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+ typedef X1 B2;
+ typedef X2 B3;
+ typedef X3 B4;
+
};
// Const Method: Arity 3.
@@ -150,6 +201,13 @@ 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);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+ typedef X1 B2;
+ typedef X2 B3;
+ typedef X3 B4;
+
};
// Function: Arity 4.
@@ -157,6 +215,12 @@ 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;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
+ typedef X4 B4;
+
};
// Method: Arity 4.
@@ -165,6 +229,14 @@ template <typename R, typename T, typename X1, typename X2, typename X3,
struct FunctionTraits<R(T::*)(X1, X2, X3, X4)> {
typedef R (T::*NormalizedSig)(X1, X2, X3, X4);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+ typedef X1 B2;
+ typedef X2 B3;
+ typedef X3 B4;
+ typedef X4 B5;
+
};
// Const Method: Arity 4.
@@ -173,6 +245,14 @@ template <typename R, typename T, typename X1, typename X2, typename X3,
struct FunctionTraits<R(T::*)(X1, X2, X3, X4) const> {
typedef R (T::*NormalizedSig)(X1, X2, X3, X4);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+ typedef X1 B2;
+ typedef X2 B3;
+ typedef X3 B4;
+ typedef X4 B5;
+
};
// Function: Arity 5.
@@ -181,6 +261,13 @@ template <typename R, typename X1, typename X2, typename X3, typename X4,
struct FunctionTraits<R(*)(X1, X2, X3, X4, X5)> {
typedef R (*NormalizedSig)(X1, X2, X3, X4, X5);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
+ typedef X4 B4;
+ typedef X5 B5;
+
};
// Method: Arity 5.
@@ -189,6 +276,15 @@ template <typename R, typename T, typename X1, typename X2, typename X3,
struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5)> {
typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+ typedef X1 B2;
+ typedef X2 B3;
+ typedef X3 B4;
+ typedef X4 B5;
+ typedef X5 B6;
+
};
// Const Method: Arity 5.
@@ -197,6 +293,15 @@ template <typename R, typename T, typename X1, typename X2, typename X3,
struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5) const> {
typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+ typedef X1 B2;
+ typedef X2 B3;
+ typedef X3 B4;
+ typedef X4 B5;
+ typedef X5 B6;
+
};
// Function: Arity 6.
@@ -205,6 +310,14 @@ template <typename R, typename X1, typename X2, typename X3, typename X4,
struct FunctionTraits<R(*)(X1, X2, X3, X4, X5, X6)> {
typedef R (*NormalizedSig)(X1, X2, X3, X4, X5, X6);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
+ typedef X4 B4;
+ typedef X5 B5;
+ typedef X6 B6;
+
};
// Method: Arity 6.
@@ -213,6 +326,16 @@ template <typename R, typename T, typename X1, typename X2, typename X3,
struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5, X6)> {
typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5, X6);
typedef true_type IsMethod;
+
+ // 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;
+
};
// Const Method: Arity 6.
@@ -221,6 +344,16 @@ template <typename R, typename T, typename X1, typename X2, typename X3,
struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5, X6) const> {
typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5, X6);
typedef true_type IsMethod;
+
+ // 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;
+
};
// InvokerN<>
@@ -258,11 +391,8 @@ struct Invoker0<StorageType, R(*)()> {
// Function: Arity 1 -> 1.
template <typename StorageType, typename R,typename X1>
struct Invoker0<StorageType, R(*)(X1)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X1& x1) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X1>::ForwardType x1) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(x1);
}
@@ -271,12 +401,9 @@ struct Invoker0<StorageType, R(*)(X1)> {
// Function: Arity 2 -> 2.
template <typename StorageType, typename R,typename X1, typename X2>
struct Invoker0<StorageType, R(*)(X1, X2)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2) {
+ 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);
}
@@ -286,14 +413,10 @@ struct Invoker0<StorageType, R(*)(X1, X2)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3>
struct Invoker0<StorageType, R(*)(X1, X2, X3)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
- const X3& x3) {
+ 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);
}
@@ -303,15 +426,11 @@ struct Invoker0<StorageType, R(*)(X1, X2, X3)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4>
struct Invoker0<StorageType, R(*)(X1, X2, X3, X4)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
- const X3& x3, const X4& x4) {
+ 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);
}
@@ -321,16 +440,12 @@ struct Invoker0<StorageType, R(*)(X1, X2, X3, X4)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5>
struct Invoker0<StorageType, R(*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
- const X3& x3, const X4& x4, const X5& x5) {
+ 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);
}
@@ -340,17 +455,13 @@ struct Invoker0<StorageType, R(*)(X1, X2, X3, X4, X5)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5, typename X6>
struct Invoker0<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ||
- is_non_const_reference<X6>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
- const X3& x3, const X4& x4, const X5& x5, const X6& x6) {
+ 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);
}
@@ -362,10 +473,6 @@ struct Invoker1;
// Function: Arity 1 -> 0.
template <typename StorageType, typename R,typename X1>
struct Invoker1<StorageType, R(*)(X1)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
static R DoInvoke(InvokerStorageBase* base) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_));
@@ -384,12 +491,8 @@ struct Invoker1<StorageType, R(T::*)()> {
// Function: Arity 2 -> 1.
template <typename StorageType, typename R,typename X1, typename X2>
struct Invoker1<StorageType, R(*)(X1, X2)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X2& x2) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X2>::ForwardType x2) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), x2);
}
@@ -398,11 +501,8 @@ struct Invoker1<StorageType, R(*)(X1, X2)> {
// Method: Arity 1 -> 1.
template <typename StorageType, typename R, typename T, typename X1>
struct Invoker1<StorageType, R(T::*)(X1)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X1& x1) {
+ static R DoInvoke(InvokerStorageBase* base,
+ typename internal::ParamTraits<X1>::ForwardType x1) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(x1);
}
@@ -412,13 +512,9 @@ struct Invoker1<StorageType, R(T::*)(X1)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3>
struct Invoker1<StorageType, R(*)(X1, X2, X3)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3) {
+ 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);
}
@@ -428,12 +524,9 @@ struct Invoker1<StorageType, R(*)(X1, X2, X3)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2>
struct Invoker1<StorageType, R(T::*)(X1, X2)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2) {
+ 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);
}
@@ -443,15 +536,10 @@ struct Invoker1<StorageType, R(T::*)(X1, X2)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4>
struct Invoker1<StorageType, R(*)(X1, X2, X3, X4)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3,
- const X4& x4) {
+ 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);
}
@@ -461,14 +549,10 @@ struct Invoker1<StorageType, R(*)(X1, X2, X3, X4)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3>
struct Invoker1<StorageType, R(T::*)(X1, X2, X3)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
- const X3& x3) {
+ 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);
}
@@ -478,16 +562,11 @@ struct Invoker1<StorageType, R(T::*)(X1, X2, X3)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5>
struct Invoker1<StorageType, R(*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3,
- const X4& x4, const X5& x5) {
+ 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);
}
@@ -497,15 +576,11 @@ struct Invoker1<StorageType, R(*)(X1, X2, X3, X4, X5)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3, typename X4>
struct Invoker1<StorageType, R(T::*)(X1, X2, X3, X4)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
- const X3& x3, const X4& x4) {
+ 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);
}
@@ -515,17 +590,12 @@ struct Invoker1<StorageType, R(T::*)(X1, X2, X3, X4)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5, typename X6>
struct Invoker1<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ||
- is_non_const_reference<X6>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3,
- const X4& x4, const X5& x5, const X6& x6) {
+ 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);
}
@@ -535,16 +605,12 @@ struct Invoker1<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3, typename X4, typename X5>
struct Invoker1<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
- const X3& x3, const X4& x4, const X5& x5) {
+ 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);
}
@@ -556,11 +622,6 @@ struct Invoker2;
// Function: Arity 2 -> 0.
template <typename StorageType, typename R,typename X1, typename X2>
struct Invoker2<StorageType, R(*)(X1, X2)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
static R DoInvoke(InvokerStorageBase* base) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_));
@@ -570,10 +631,6 @@ struct Invoker2<StorageType, R(*)(X1, X2)> {
// Method: Arity 1 -> 0.
template <typename StorageType, typename R, typename T, typename X1>
struct Invoker2<StorageType, R(T::*)(X1)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
static R DoInvoke(InvokerStorageBase* base) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_));
@@ -584,13 +641,8 @@ struct Invoker2<StorageType, R(T::*)(X1)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3>
struct Invoker2<StorageType, R(*)(X1, X2, X3)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X3& x3) {
+ 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);
}
@@ -600,12 +652,8 @@ struct Invoker2<StorageType, R(*)(X1, X2, X3)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2>
struct Invoker2<StorageType, R(T::*)(X1, X2)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X2& x2) {
+ 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);
}
@@ -615,14 +663,9 @@ struct Invoker2<StorageType, R(T::*)(X1, X2)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4>
struct Invoker2<StorageType, R(*)(X1, X2, X3, X4)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X3& x3, const X4& x4) {
+ 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);
}
@@ -632,13 +675,9 @@ struct Invoker2<StorageType, R(*)(X1, X2, X3, X4)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3>
struct Invoker2<StorageType, R(T::*)(X1, X2, X3)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3) {
+ 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);
}
@@ -648,16 +687,10 @@ struct Invoker2<StorageType, R(T::*)(X1, X2, X3)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5>
struct Invoker2<StorageType, R(*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X3& x3, const X4& x4,
- const X5& x5) {
+ 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);
}
@@ -667,15 +700,10 @@ struct Invoker2<StorageType, R(*)(X1, X2, X3, X4, X5)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3, typename X4>
struct Invoker2<StorageType, R(T::*)(X1, X2, X3, X4)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3,
- const X4& x4) {
+ 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);
@@ -686,17 +714,11 @@ struct Invoker2<StorageType, R(T::*)(X1, X2, X3, X4)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5, typename X6>
struct Invoker2<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ||
- is_non_const_reference<X6>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X3& x3, const X4& x4,
- const X5& x5, const X6& x6) {
+ 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);
@@ -707,16 +729,11 @@ struct Invoker2<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3, typename X4, typename X5>
struct Invoker2<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3,
- const X4& x4, const X5& x5) {
+ 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);
@@ -730,12 +747,6 @@ struct Invoker3;
template <typename StorageType, typename R,typename X1, typename X2,
typename X3>
struct Invoker3<StorageType, R(*)(X1, X2, X3)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
static R DoInvoke(InvokerStorageBase* base) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
@@ -747,11 +758,6 @@ struct Invoker3<StorageType, R(*)(X1, X2, X3)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2>
struct Invoker3<StorageType, R(T::*)(X1, X2)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
static R DoInvoke(InvokerStorageBase* base) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
@@ -763,14 +769,8 @@ struct Invoker3<StorageType, R(T::*)(X1, X2)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4>
struct Invoker3<StorageType, R(*)(X1, X2, X3, X4)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X4& x4) {
+ 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);
@@ -781,13 +781,8 @@ struct Invoker3<StorageType, R(*)(X1, X2, X3, X4)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3>
struct Invoker3<StorageType, R(T::*)(X1, X2, X3)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X3& x3) {
+ 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);
@@ -798,15 +793,9 @@ struct Invoker3<StorageType, R(T::*)(X1, X2, X3)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5>
struct Invoker3<StorageType, R(*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X4& x4, const X5& x5) {
+ 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);
@@ -817,14 +806,9 @@ struct Invoker3<StorageType, R(*)(X1, X2, X3, X4, X5)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3, typename X4>
struct Invoker3<StorageType, R(T::*)(X1, X2, X3, X4)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X3& x3, const X4& x4) {
+ 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);
@@ -835,17 +819,10 @@ struct Invoker3<StorageType, R(T::*)(X1, X2, X3, X4)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5, typename X6>
struct Invoker3<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ||
- is_non_const_reference<X6>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X4& x4, const X5& x5,
- const X6& x6) {
+ 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);
@@ -856,16 +833,10 @@ struct Invoker3<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3, typename X4, typename X5>
struct Invoker3<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X3& x3, const X4& x4,
- const X5& x5) {
+ 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);
@@ -879,13 +850,6 @@ struct Invoker4;
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4>
struct Invoker4<StorageType, R(*)(X1, X2, X3, X4)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
static R DoInvoke(InvokerStorageBase* base) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
@@ -897,12 +861,6 @@ struct Invoker4<StorageType, R(*)(X1, X2, X3, X4)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3>
struct Invoker4<StorageType, R(T::*)(X1, X2, X3)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
static R DoInvoke(InvokerStorageBase* base) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
@@ -914,15 +872,8 @@ struct Invoker4<StorageType, R(T::*)(X1, X2, X3)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5>
struct Invoker4<StorageType, R(*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X5& x5) {
+ 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);
@@ -933,14 +884,8 @@ struct Invoker4<StorageType, R(*)(X1, X2, X3, X4, X5)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3, typename X4>
struct Invoker4<StorageType, R(T::*)(X1, X2, X3, X4)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X4& x4) {
+ 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);
@@ -951,16 +896,9 @@ struct Invoker4<StorageType, R(T::*)(X1, X2, X3, X4)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5, typename X6>
struct Invoker4<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ||
- is_non_const_reference<X6>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X5& x5, const X6& x6) {
+ 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);
@@ -971,15 +909,9 @@ struct Invoker4<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3, typename X4, typename X5>
struct Invoker4<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X4& x4, const X5& x5) {
+ 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);
@@ -993,14 +925,6 @@ struct Invoker5;
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5>
struct Invoker5<StorageType, R(*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
static R DoInvoke(InvokerStorageBase* base) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
@@ -1012,13 +936,6 @@ struct Invoker5<StorageType, R(*)(X1, X2, X3, X4, X5)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3, typename X4>
struct Invoker5<StorageType, R(T::*)(X1, X2, X3, X4)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
static R DoInvoke(InvokerStorageBase* base) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
@@ -1030,16 +947,8 @@ struct Invoker5<StorageType, R(T::*)(X1, X2, X3, X4)> {
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5, typename X6>
struct Invoker5<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ||
- is_non_const_reference<X6>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X6& x6) {
+ 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);
@@ -1050,15 +959,8 @@ struct Invoker5<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3, typename X4, typename X5>
struct Invoker5<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
- static R DoInvoke(InvokerStorageBase* base, const X5& x5) {
+ 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);
@@ -1072,15 +974,6 @@ struct Invoker6;
template <typename StorageType, typename R,typename X1, typename X2,
typename X3, typename X4, typename X5, typename X6>
struct Invoker6<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ||
- is_non_const_reference<X6>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
static R DoInvoke(InvokerStorageBase* base) {
StorageType* invoker = static_cast<StorageType*>(base);
return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
@@ -1093,14 +986,6 @@ struct Invoker6<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
template <typename StorageType, typename R, typename T, typename X1,
typename X2, typename X3, typename X4, typename X5>
struct Invoker6<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
- COMPILE_ASSERT(
- !( is_non_const_reference<X1>::value ||
- is_non_const_reference<X2>::value ||
- is_non_const_reference<X3>::value ||
- is_non_const_reference<X4>::value ||
- is_non_const_reference<X5>::value ),
- do_not_bind_functions_with_nonconst_ref);
-
static R DoInvoke(InvokerStorageBase* base) {
StorageType* invoker = static_cast<StorageType*>(base);
return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
@@ -1133,6 +1018,7 @@ class InvokerStorage0 : public InvokerStorageBase {
typedef typename TargetTraits::IsMethod IsMethod;
+
InvokerStorage0(Sig f)
: f_(f) {
}
@@ -1149,6 +1035,7 @@ class InvokerStorage1 : public InvokerStorageBase {
typedef FunctionTraits<Sig> TargetTraits;
typedef Invoker1<StorageType, typename TargetTraits::NormalizedSig> Invoker;
typedef typename TargetTraits::IsMethod IsMethod;
+
// 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.
@@ -1158,9 +1045,18 @@ class InvokerStorage1 : public InvokerStorageBase {
COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
first_bound_argument_to_method_cannot_be_array);
+ // 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);
+
InvokerStorage1(Sig f, const P1& p1)
- : f_(f), p1_(static_cast<typename BindType<P1>::StorageType>(p1)) {
+ : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)) {
MaybeRefcount<IsMethod, P1>::AddRef(p1_);
}
@@ -1169,7 +1065,7 @@ class InvokerStorage1 : public InvokerStorageBase {
}
Sig f_;
- typename BindType<P1>::StorageType p1_;
+ typename ParamTraits<P1>::StorageType p1_;
};
template <typename Sig, typename P1, typename P2>
@@ -1179,6 +1075,7 @@ class InvokerStorage2 : public InvokerStorageBase {
typedef FunctionTraits<Sig> TargetTraits;
typedef Invoker2<StorageType, typename TargetTraits::NormalizedSig> Invoker;
typedef typename TargetTraits::IsMethod IsMethod;
+
// 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.
@@ -1190,10 +1087,20 @@ class InvokerStorage2 : public InvokerStorageBase {
COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P2>::value,
p2_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 ),
+ do_not_bind_functions_with_nonconst_ref);
+
InvokerStorage2(Sig f, const P1& p1, const P2& p2)
- : f_(f), p1_(static_cast<typename BindType<P1>::StorageType>(p1)),
- p2_(static_cast<typename BindType<P2>::StorageType>(p2)) {
+ : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)),
+ p2_(static_cast<typename ParamTraits<P2>::StorageType>(p2)) {
MaybeRefcount<IsMethod, P1>::AddRef(p1_);
}
@@ -1202,8 +1109,8 @@ class InvokerStorage2 : public InvokerStorageBase {
}
Sig f_;
- typename BindType<P1>::StorageType p1_;
- typename BindType<P2>::StorageType p2_;
+ typename ParamTraits<P1>::StorageType p1_;
+ typename ParamTraits<P2>::StorageType p2_;
};
template <typename Sig, typename P1, typename P2, typename P3>
@@ -1213,6 +1120,7 @@ class InvokerStorage3 : public InvokerStorageBase {
typedef FunctionTraits<Sig> TargetTraits;
typedef Invoker3<StorageType, typename TargetTraits::NormalizedSig> Invoker;
typedef typename TargetTraits::IsMethod IsMethod;
+
// 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.
@@ -1226,11 +1134,22 @@ class InvokerStorage3 : public InvokerStorageBase {
COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P3>::value,
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 BindType<P1>::StorageType>(p1)),
- p2_(static_cast<typename BindType<P2>::StorageType>(p2)),
- p3_(static_cast<typename BindType<P3>::StorageType>(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_);
}
@@ -1239,9 +1158,9 @@ class InvokerStorage3 : public InvokerStorageBase {
}
Sig f_;
- typename BindType<P1>::StorageType p1_;
- typename BindType<P2>::StorageType p2_;
- typename BindType<P3>::StorageType p3_;
+ 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>
@@ -1251,6 +1170,7 @@ class InvokerStorage4 : public InvokerStorageBase {
typedef FunctionTraits<Sig> TargetTraits;
typedef Invoker4<StorageType, typename TargetTraits::NormalizedSig> Invoker;
typedef typename TargetTraits::IsMethod IsMethod;
+
// 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.
@@ -1266,12 +1186,24 @@ class InvokerStorage4 : public InvokerStorageBase {
COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P4>::value,
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 BindType<P1>::StorageType>(p1)),
- p2_(static_cast<typename BindType<P2>::StorageType>(p2)),
- p3_(static_cast<typename BindType<P3>::StorageType>(p3)),
- p4_(static_cast<typename BindType<P4>::StorageType>(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_);
}
@@ -1280,10 +1212,10 @@ class InvokerStorage4 : public InvokerStorageBase {
}
Sig f_;
- typename BindType<P1>::StorageType p1_;
- typename BindType<P2>::StorageType p2_;
- typename BindType<P3>::StorageType p3_;
- typename BindType<P4>::StorageType p4_;
+ 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,
@@ -1294,6 +1226,7 @@ class InvokerStorage5 : public InvokerStorageBase {
typedef FunctionTraits<Sig> TargetTraits;
typedef Invoker5<StorageType, typename TargetTraits::NormalizedSig> Invoker;
typedef typename TargetTraits::IsMethod IsMethod;
+
// 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.
@@ -1311,14 +1244,27 @@ class InvokerStorage5 : public InvokerStorageBase {
COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P5>::value,
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 BindType<P1>::StorageType>(p1)),
- p2_(static_cast<typename BindType<P2>::StorageType>(p2)),
- p3_(static_cast<typename BindType<P3>::StorageType>(p3)),
- p4_(static_cast<typename BindType<P4>::StorageType>(p4)),
- p5_(static_cast<typename BindType<P5>::StorageType>(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_);
}
@@ -1327,11 +1273,11 @@ class InvokerStorage5 : public InvokerStorageBase {
}
Sig f_;
- typename BindType<P1>::StorageType p1_;
- typename BindType<P2>::StorageType p2_;
- typename BindType<P3>::StorageType p3_;
- typename BindType<P4>::StorageType p4_;
- typename BindType<P5>::StorageType p5_;
+ 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_;
};
template <typename Sig, typename P1, typename P2, typename P3, typename P4,
@@ -1342,6 +1288,7 @@ class InvokerStorage6 : public InvokerStorageBase {
typedef FunctionTraits<Sig> TargetTraits;
typedef Invoker6<StorageType, typename TargetTraits::NormalizedSig> Invoker;
typedef typename TargetTraits::IsMethod IsMethod;
+
// 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.
@@ -1361,15 +1308,29 @@ class InvokerStorage6 : public InvokerStorageBase {
COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P6>::value,
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,
const P4& p4, const P5& p5, const P6& p6)
- : f_(f), p1_(static_cast<typename BindType<P1>::StorageType>(p1)),
- p2_(static_cast<typename BindType<P2>::StorageType>(p2)),
- p3_(static_cast<typename BindType<P3>::StorageType>(p3)),
- p4_(static_cast<typename BindType<P4>::StorageType>(p4)),
- p5_(static_cast<typename BindType<P5>::StorageType>(p5)),
- p6_(static_cast<typename BindType<P6>::StorageType>(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_);
}
@@ -1378,12 +1339,12 @@ class InvokerStorage6 : public InvokerStorageBase {
}
Sig f_;
- typename BindType<P1>::StorageType p1_;
- typename BindType<P2>::StorageType p2_;
- typename BindType<P3>::StorageType p3_;
- typename BindType<P4>::StorageType p4_;
- typename BindType<P5>::StorageType p5_;
- typename BindType<P6>::StorageType p6_;
+ 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_;
};
} // namespace internal
diff --git a/base/bind_internal.h.pump b/base/bind_internal.h.pump
index 84fb2ef..4ccec5e 100644
--- a/base/bind_internal.h.pump
+++ b/base/bind_internal.h.pump
@@ -82,6 +82,17 @@ $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;
+
+$if ARITY > 0 [[
+
+ // Target type for each bound parameter.
+
+$for ARG [[
+ typedef X$(ARG) B$(ARG);
+
+]] $$ for ARG
+]] $$ if ARITY > 0
+
};
// Method: Arity $(ARITY).
@@ -90,6 +101,15 @@ $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]>
struct FunctionTraits<R(T::*)($for ARG , [[X$(ARG)]])> {
typedef R (T::*NormalizedSig)($for ARG , [[X$(ARG)]]);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+
+$for ARG [[
+ typedef X$(ARG) B$(ARG + 1);
+
+]] $$ for ARG
+
};
// Const Method: Arity $(ARITY).
@@ -98,6 +118,15 @@ $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)]]);
typedef true_type IsMethod;
+
+ // Target type for each bound parameter.
+ typedef T B1;
+
+$for ARG [[
+ typedef X$(ARG) B$(ARG + 1);
+
+]] $$ for ARG
+
};
]] $$for ARITY
@@ -151,17 +180,9 @@ template <typename StorageType, typename R[[]]
$if ARITY > 0 [[,]][[]]
$for ARG , [[typename X$(ARG)]]>
struct Invoker$(BOUND)<StorageType, R(*)($for ARG , [[X$(ARG)]])> {
-$if ARITY > 0 [[
-
- COMPILE_ASSERT(
- !($for ARG || [[ is_non_const_reference<X$(ARG)>::value ]]),
- do_not_bind_functions_with_nonconst_ref);
-
-]]
-
static R DoInvoke(InvokerStorageBase* base[[]]
$if UNBOUND != 0 [[, ]][[]]
-$for UNBOUND_ARG , [[const X$(UNBOUND_ARG)& x$(UNBOUND_ARG)]]) {
+$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.
@@ -176,17 +197,9 @@ $if BOUND > 0 [[
template <typename StorageType, typename R, typename T[[]]
$if M_ARITY > 0[[, ]] $for M_ARG , [[typename X$(M_ARG)]]>
struct Invoker$(BOUND)<StorageType, R(T::*)($for M_ARG , [[X$(M_ARG)]])> {
-$if M_ARITY > 0 [[
-
- COMPILE_ASSERT(
- !($for M_ARG || [[ is_non_const_reference<X$(M_ARG)>::value ]]),
- do_not_bind_functions_with_nonconst_ref);
-
-]]
-
static R DoInvoke(InvokerStorageBase* base[[]]
$if UNBOUND > 0 [[, ]][[]]
-$for M_UNBOUND_ARG , [[const X$(M_UNBOUND_ARG)& x$(M_UNBOUND_ARG)]]) {
+$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)_)]][[]]
@@ -228,6 +241,7 @@ class InvokerStorage$(BOUND) : public InvokerStorageBase {
typedef FunctionTraits<Sig> TargetTraits;
typedef Invoker$(BOUND)<StorageType, typename TargetTraits::NormalizedSig> Invoker;
typedef typename TargetTraits::IsMethod IsMethod;
+
$for BOUND_ARG [[
$if BOUND_ARG == 1 [[
@@ -247,6 +261,19 @@ $if BOUND_ARG == 1 [[
]] $$ $for BOUND_ARG
+$if BOUND > 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 BOUND_ARG || [[ is_non_const_reference<typename TargetTraits::B$(BOUND_ARG)>::value ]]),
+ do_not_bind_functions_with_nonconst_ref);
+
+]]
+
InvokerStorage$(BOUND)(Sig f
$if BOUND > 0 [[, ]]
@@ -256,7 +283,7 @@ $if BOUND == 0 [[
{
]] $else [[
-, $for BOUND_ARG , [[p$(BOUND_ARG)_(static_cast<typename BindType<P$(BOUND_ARG)>::StorageType>(p$(BOUND_ARG)))]] {
+, $for BOUND_ARG , [[p$(BOUND_ARG)_(static_cast<typename ParamTraits<P$(BOUND_ARG)>::StorageType>(p$(BOUND_ARG)))]] {
MaybeRefcount<IsMethod, P1>::AddRef(p1_);
]]
@@ -273,7 +300,7 @@ $if BOUND > 0 [[
Sig f_;
$for BOUND_ARG [[
- typename BindType<P$(BOUND_ARG)>::StorageType p$(BOUND_ARG)_;
+ typename ParamTraits<P$(BOUND_ARG)>::StorageType p$(BOUND_ARG)_;
]]
};
diff --git a/base/bind_internal_win.h b/base/bind_internal_win.h
index dab8d51..976a4d7 100644
--- a/base/bind_internal_win.h
+++ b/base/bind_internal_win.h
@@ -3,6 +3,7 @@
// DO NOT EDIT BY HAND!!!
+
// 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.
@@ -39,6 +40,8 @@ template <typename R, typename X1>
struct FunctionTraits<R(__stdcall *)(X1)> {
typedef R (*NormalizedSig)(X1);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
};
// __fastcall Function: Arity 1.
@@ -46,6 +49,8 @@ template <typename R, typename X1>
struct FunctionTraits<R(__fastcall *)(X1)> {
typedef R (*NormalizedSig)(X1);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
};
// __stdcall Function: Arity 2.
@@ -53,6 +58,9 @@ template <typename R, typename X1, typename X2>
struct FunctionTraits<R(__stdcall *)(X1, X2)> {
typedef R (*NormalizedSig)(X1, X2);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
};
// __fastcall Function: Arity 2.
@@ -60,6 +68,9 @@ template <typename R, typename X1, typename X2>
struct FunctionTraits<R(__fastcall *)(X1, X2)> {
typedef R (*NormalizedSig)(X1, X2);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
};
// __stdcall Function: Arity 3.
@@ -67,6 +78,10 @@ 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;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
};
// __fastcall Function: Arity 3.
@@ -74,6 +89,10 @@ 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;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
};
// __stdcall Function: Arity 4.
@@ -81,6 +100,11 @@ 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;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
+ typedef X4 B4;
};
// __fastcall Function: Arity 4.
@@ -88,6 +112,11 @@ 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;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
+ typedef X4 B4;
};
// __stdcall Function: Arity 5.
@@ -96,6 +125,12 @@ template <typename R, typename X1, typename X2, typename X3, typename X4,
struct FunctionTraits<R(__stdcall *)(X1, X2, X3, X4, X5)> {
typedef R (*NormalizedSig)(X1, X2, X3, X4, X5);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
+ typedef X4 B4;
+ typedef X5 B5;
};
// __fastcall Function: Arity 5.
@@ -104,6 +139,12 @@ template <typename R, typename X1, typename X2, typename X3, typename X4,
struct FunctionTraits<R(__fastcall *)(X1, X2, X3, X4, X5)> {
typedef R (*NormalizedSig)(X1, X2, X3, X4, X5);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
+ typedef X4 B4;
+ typedef X5 B5;
};
// __stdcall Function: Arity 6.
@@ -112,6 +153,13 @@ template <typename R, typename X1, typename X2, typename X3, typename X4,
struct FunctionTraits<R(__stdcall *)(X1, X2, X3, X4, X5, X6)> {
typedef R (*NormalizedSig)(X1, X2, X3, X4, X5, X6);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
+ typedef X4 B4;
+ typedef X5 B5;
+ typedef X6 B6;
};
// __fastcall Function: Arity 6.
@@ -120,6 +168,13 @@ template <typename R, typename X1, typename X2, typename X3, typename X4,
struct FunctionTraits<R(__fastcall *)(X1, X2, X3, X4, X5, X6)> {
typedef R (*NormalizedSig)(X1, X2, X3, X4, X5, X6);
typedef false_type IsMethod;
+ // Target type for each bound parameter.
+ typedef X1 B1;
+ typedef X2 B2;
+ typedef X3 B3;
+ typedef X4 B4;
+ typedef X5 B5;
+ typedef X6 B6;
};
} // namespace internal
diff --git a/base/bind_internal_win.h.pump b/base/bind_internal_win.h.pump
index 4d213a3..06ceaca1 100644
--- a/base/bind_internal_win.h.pump
+++ b/base/bind_internal_win.h.pump
@@ -34,6 +34,16 @@ $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 [[
+
+ // Target type for each bound parameter.
+
+$for ARG [[
+ typedef X$(ARG) B$(ARG);
+
+]] $$ for ARG
+]] $$ if ARITY > 0
};
// __fastcall Function: Arity $(ARITY).
@@ -42,6 +52,16 @@ $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;
+
+$if ARITY > 0 [[
+
+ // Target type for each bound parameter.
+
+$for ARG [[
+ typedef X$(ARG) B$(ARG);
+
+]] $$ for ARG
+]] $$ if ARITY > 0
};
]] $$for ARITY
diff --git a/base/bind_unittest.cc b/base/bind_unittest.cc
index 061808b..b3e0160 100644
--- a/base/bind_unittest.cc
+++ b/base/bind_unittest.cc
@@ -174,6 +174,10 @@ int UnwrapNoRefParentConstRef(const NoRefParent& p) {
return p.value;
}
+void RefArgSet(int &n) {
+ n = 2;
+}
+
// Only useful in no-compile tests.
int UnwrapNoRefParentRef(Parent& p) {
return p.value;
@@ -351,6 +355,37 @@ TEST_F(BindTest, ArgumentBinding) {
EXPECT_EQ(8, bind_const_reference_promotes_cb.Run());
}
+// Unbound argument type support tests.
+// - Unbound value.
+// - Unbound pointer.
+// - Unbound reference.
+// - Unbound const reference.
+// - Unbound unsized array.
+// - Unbound sized array.
+// - Unbound array-of-arrays.
+TEST_F(BindTest, UnboundArgumentTypeSupport) {
+ Callback<void(int)> unbound_value_cb = Bind(&VoidPolymorphic1<int>);
+ Callback<void(int*)> unbound_pointer_cb = Bind(&VoidPolymorphic1<int*>);
+ Callback<void(int&)> unbound_ref_cb = Bind(&VoidPolymorphic1<int&>);
+ Callback<void(const int&)> unbound_const_ref_cb =
+ Bind(&VoidPolymorphic1<const int&>);
+ Callback<void(int[])> unbound_unsized_array_cb =
+ Bind(&VoidPolymorphic1<int[]>);
+ Callback<void(int[2])> unbound_sized_array_cb =
+ Bind(&VoidPolymorphic1<int[2]>);
+ Callback<void(int[][2])> unbound_array_of_arrays_cb =
+ Bind(&VoidPolymorphic1<int[][2]>);
+}
+
+// Function with unbound reference parameter.
+// - Original paraemter is modified by callback.
+TEST_F(BindTest, UnboundReferenceSupport) {
+ int n = 0;
+ Callback<void(int&)> unbound_ref_cb = Bind(&RefArgSet);
+ unbound_ref_cb.Run(n);
+ EXPECT_EQ(2, n);
+}
+
// Functions that take reference parameters.
// - Forced reference parameter type still stores a copy.
// - Forced const reference parameter type still stores a copy.
@@ -570,14 +605,13 @@ TEST_F(BindTest, NoCompile) {
//
// HasRef p[10];
// Callback<void(void)> method_bound_to_array_cb =
- // Bind(&HasRef::VoidConstMethod0, p);
+ // Bind(&HasRef::VoidConstMethod0, p);
// method_bound_to_array_cb.Run();
// - Refcounted types should not be bound as a raw pointer.
// HasRef for_raw_ptr;
// Callback<void(void)> ref_count_as_raw_ptr =
// Bind(&VoidPolymorphic1<HasRef*>, &for_raw_ptr);
- // ASSERT_EQ(&for_raw_ptr, ref_count_as_raw_ptr.Run());
}
diff --git a/base/callback.h b/base/callback.h
index bcc3dfd..2e17ae9 100644
--- a/base/callback.h
+++ b/base/callback.h
@@ -3,6 +3,7 @@
// DO NOT EDIT BY HAND!!!
+
// 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.
@@ -225,7 +226,8 @@ class Callback;
template <typename R>
class Callback<R(void)> : public internal::CallbackBase {
public:
- typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*);
+ typedef R(*PolymorphicInvoke)(
+ internal::InvokerStorageBase*);
Callback() : CallbackBase(NULL, NULL) { }
@@ -254,7 +256,9 @@ class Callback<R(void)> : public internal::CallbackBase {
template <typename R, typename A1>
class Callback<R(A1)> : public internal::CallbackBase {
public:
- typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&);
+ typedef R(*PolymorphicInvoke)(
+ internal::InvokerStorageBase*,
+ typename internal::ParamTraits<A1>::ForwardType);
Callback() : CallbackBase(NULL, NULL) { }
@@ -272,7 +276,7 @@ class Callback<R(A1)> : public internal::CallbackBase {
&invoker_holder.invoker_storage_) {
}
- R Run(const A1& a1) const {
+ R Run(typename internal::ParamTraits<A1>::ForwardType a1) const {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
@@ -283,8 +287,10 @@ class Callback<R(A1)> : public internal::CallbackBase {
template <typename R, typename A1, typename A2>
class Callback<R(A1, A2)> : public internal::CallbackBase {
public:
- typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&,
- const A2&);
+ typedef R(*PolymorphicInvoke)(
+ internal::InvokerStorageBase*,
+ typename internal::ParamTraits<A1>::ForwardType,
+ typename internal::ParamTraits<A2>::ForwardType);
Callback() : CallbackBase(NULL, NULL) { }
@@ -302,8 +308,8 @@ class Callback<R(A1, A2)> : public internal::CallbackBase {
&invoker_holder.invoker_storage_) {
}
- R Run(const A1& a1,
- const A2& a2) const {
+ R Run(typename internal::ParamTraits<A1>::ForwardType a1,
+ typename internal::ParamTraits<A2>::ForwardType a2) const {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
@@ -315,9 +321,11 @@ class Callback<R(A1, A2)> : public internal::CallbackBase {
template <typename R, typename A1, typename A2, typename A3>
class Callback<R(A1, A2, A3)> : public internal::CallbackBase {
public:
- typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*, const A1&,
- const A2&,
- const A3&);
+ typedef R(*PolymorphicInvoke)(
+ internal::InvokerStorageBase*,
+ typename internal::ParamTraits<A1>::ForwardType,
+ typename internal::ParamTraits<A2>::ForwardType,
+ typename internal::ParamTraits<A3>::ForwardType);
Callback() : CallbackBase(NULL, NULL) { }
@@ -335,9 +343,9 @@ class Callback<R(A1, A2, A3)> : public internal::CallbackBase {
&invoker_holder.invoker_storage_) {
}
- R Run(const A1& a1,
- const A2& a2,
- const A3& a3) const {
+ R Run(typename internal::ParamTraits<A1>::ForwardType a1,
+ typename internal::ParamTraits<A2>::ForwardType a2,
+ typename internal::ParamTraits<A3>::ForwardType a3) const {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
@@ -350,10 +358,12 @@ class Callback<R(A1, A2, A3)> : public internal::CallbackBase {
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*, const A1&,
- const A2&,
- const A3&,
- const A4&);
+ 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);
Callback() : CallbackBase(NULL, NULL) { }
@@ -371,10 +381,10 @@ class Callback<R(A1, A2, A3, A4)> : public internal::CallbackBase {
&invoker_holder.invoker_storage_) {
}
- R Run(const A1& a1,
- const A2& a2,
- const A3& a3,
- const A4& a4) const {
+ 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 {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
@@ -389,11 +399,13 @@ 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*, const A1&,
- const A2&,
- const A3&,
- const A4&,
- const A5&);
+ 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);
Callback() : CallbackBase(NULL, NULL) { }
@@ -411,11 +423,11 @@ class Callback<R(A1, A2, A3, A4, A5)> : public internal::CallbackBase {
&invoker_holder.invoker_storage_) {
}
- R Run(const A1& a1,
- const A2& a2,
- const A3& a3,
- const A4& a4,
- const A5& a5) const {
+ 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 {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
@@ -431,12 +443,14 @@ 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*, const A1&,
- const A2&,
- const A3&,
- const A4&,
- const A5&,
- const A6&);
+ 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);
Callback() : CallbackBase(NULL, NULL) { }
@@ -454,12 +468,12 @@ class Callback<R(A1, A2, A3, A4, A5, A6)> : public internal::CallbackBase {
&invoker_holder.invoker_storage_) {
}
- R Run(const A1& a1,
- const A2& a2,
- const A3& a3,
- const A4& a4,
- const A5& a5,
- const A6& a6) const {
+ 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 {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
diff --git a/base/callback.h.pump b/base/callback.h.pump
index 34b0eb0..542a84f 100644
--- a/base/callback.h.pump
+++ b/base/callback.h.pump
@@ -240,10 +240,10 @@ class Callback<R($for ARG , [[A$(ARG)]])> : public internal::CallbackBase {
]]
public:
- typedef R(*PolymorphicInvoke)(internal::InvokerStorageBase*[[]]
+ typedef R(*PolymorphicInvoke)(
+ internal::InvokerStorageBase*[[]]
$if ARITY != 0 [[, ]]
-$for ARG ,
- [[const A$(ARG)&]]);
+$for ARG , [[typename internal::ParamTraits<A$(ARG)>::ForwardType]]);
Callback() : CallbackBase(NULL, NULL) { }
@@ -262,7 +262,7 @@ $for ARG ,
}
R Run($for ARG ,
- [[const A$(ARG)& a$(ARG)]]) const {
+ [[typename internal::ParamTraits<A$(ARG)>::ForwardType a$(ARG)]]) const {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
diff --git a/base/callback_internal.h b/base/callback_internal.h
index 4f1d3c3..6b8fdff2 100644
--- a/base/callback_internal.h
+++ b/base/callback_internal.h
@@ -80,6 +80,52 @@ class CallbackBase {
InvokeFuncStorage polymorphic_invoke_;
};
+// This is a typetraits object that's used to take an argument type, and
+// extract a suitable type for storing and forwarding arguments.
+//
+// In particular, it strips off references, and converts arrays to
+// pointers for storage; and it avoids accidentally trying to create a
+// "reference of a reference" if the argument is a reference type.
+//
+// This array type becomes an issue for storage because we are passing bound
+// parameters by const reference. In this case, we end up passing an actual
+// array type in the initializer list which C++ does not allow. This will
+// break passing of C-string literals.
+template <typename T>
+struct ParamTraits {
+ typedef const T& ForwardType;
+ typedef T StorageType;
+};
+
+// The Storage should almost be impossible to trigger unless someone manually
+// specifies type of the bind parameters. However, in case they do,
+// this will guard against us accidentally storing a reference parameter.
+//
+// The ForwardType should only be used for unbound arguments.
+template <typename T>
+struct ParamTraits<T&> {
+ typedef T& ForwardType;
+ typedef T StorageType;
+};
+
+// Note that for array types, we implicitly add a const in the conversion. This
+// means that it is not possible to bind array arguments to functions that take
+// a non-const pointer. Trying to specialize the template based on a "const
+// 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]> {
+ typedef const T* ForwardType;
+ typedef const T* StorageType;
+};
+
+// See comment for ParamTraits<T[n]>.
+template <typename T>
+struct ParamTraits<T[]> {
+ typedef const T* ForwardType;
+ typedef const T* StorageType;
+};
+
} // namespace internal
} // namespace base