| Index: base/bind_internal.h.pump
|
| diff --git a/base/bind_internal.h.pump b/base/bind_internal.h.pump
|
| index 84fb2ef63ba860624679f1aed77ca2079b9ca6f8..4ccec5ebee10e3ebe85e0bc088bfbadb33e66d98 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)_;
|
|
|
| ]]
|
| };
|
|
|