summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/bind_helpers.h152
-rw-r--r--base/bind_internal.h267
-rw-r--r--base/bind_internal.h.pump15
-rw-r--r--base/bind_unittest.cc67
-rw-r--r--base/callback.h56
-rw-r--r--base/callback.h.pump2
-rw-r--r--base/callback_internal.h59
-rw-r--r--base/memory/scoped_ptr.h93
-rw-r--r--base/memory/scoped_ptr_unittest.cc92
-rw-r--r--chrome/browser/chromeos/stub_cros_settings_provider_unittest.cc2
-rw-r--r--chrome/common/extensions/extension_manifests_unittest.cc13
-rw-r--r--content/browser/renderer_host/render_widget_host_view_win.cc9
12 files changed, 658 insertions, 169 deletions
diff --git a/base/bind_helpers.h b/base/bind_helpers.h
index 6e0f8fe..df8cf82 100644
--- a/base/bind_helpers.h
+++ b/base/bind_helpers.h
@@ -6,19 +6,29 @@
// can be used specify the refcounting and reference semantics of arguments
// that are bound by the Bind() function in base/bind.h.
//
-// The public functions are base::Unretained(), base::Owned(),
-// base::ConstRef(), and base::IgnoreReturn().
+// The public functions are base::Unretained(), base::Owned(), bass::Passed(),
+// base::ConstRef(), and base::IgnoreResult().
//
// Unretained() allows Bind() to bind a non-refcounted class, and to disable
// refcounting on arguments that are refcounted objects.
+//
// Owned() transfers ownership of an object to the Callback resulting from
// bind; the object will be deleted when the Callback is deleted.
+//
+// Passed() is for transferring movable-but-not-copyable types (eg. scoped_ptr)
+// through a Callback. Logically, this signifies a destructive transfer of
+// the state of the argument into the target function. Invoking
+// Callback::Run() twice on a Callback that was created with a Passed()
+// argument will CHECK() because the first invocation would have already
+// transferred ownership to the target function.
+//
// ConstRef() allows binding a constant reference to an argument rather
// than a copy.
-// IgnoreReturn() is used to adapt a 0-argument Callback with a return type to
-// a Closure. This is useful if you need to PostTask with a function that has
-// a return value that you don't care about.
//
+// IgnoreResult() is used to adapt a function or Callback with a return type to
+// one with a void return. This is most useful if you have a function with,
+// say, a pesky ignorable bool return that you want to use with PostTask or
+// something else that expect a Callback with a void return.
//
// EXAMPLE OF Unretained():
//
@@ -75,13 +85,45 @@
// its bound callbacks.
//
//
-// EXAMPLE OF IgnoreReturn():
+// EXAMPLE OF IgnoreResult():
//
// int DoSomething(int arg) { cout << arg << endl; }
-// Callback<int(void)> cb = Bind(&DoSomething, 1);
-// Closure c = IgnoreReturn(cb); // Prints "1"
-// or
-// ml->PostTask(FROM_HERE, IgnoreReturn(cb)); // Prints "1" on |ml|
+//
+// // Assign to a Callback with a void return type.
+// Callback<void(int)> cb = Bind(IgnoreResult(&DoSomething));
+// cb->Run(1); // Prints "1".
+//
+// // Prints "1" on |ml|.
+// ml->PostTask(FROM_HERE, Bind(IgnoreResult(&DoSomething), 1);
+//
+//
+// EXAMPLE OF Passed():
+//
+// void TakesOwnership(scoped_ptr<Foo> arg) { }
+// scoped_ptr<Foo> CreateFoo() { return scoped_ptr<Foo>(new Foo()); }
+//
+// scoped_ptr<Foo> f(new Foo());
+//
+// // |cb| is given ownership of Foo(). |f| is now NULL.
+// // You can use f.Pass() in place of &f, but it's more verbose.
+// Closure cb = Bind(&TakesOwnership, Passed(&f));
+//
+// // Run was never called so |cb| still owns Foo() and deletes
+// // it on Reset().
+// cb.Reset();
+//
+// // |cb| is given a new Foo created by CreateFoo().
+// cb = Bind(&TakesOwnership, Passed(CreateFoo()));
+//
+// // |arg| in TakesOwnership() is given ownership of Foo(). |cb|
+// // no longer owns Foo() and, if reset, would not delete Foo().
+// cb.Run(); // Foo() is now transferred to |arg| and deleted.
+// cb.Run(); // This CHECK()s since Foo() already been used once.
+//
+// Passed() is particularly useful with PostTask() when you are transferring
+// ownership of an argument into a task, but don't necessarily know if the
+// task will always be executed. This can happen if the task is cancellable
+// or if it is posted to a MessageLoopProxy.
#ifndef BASE_BIND_HELPERS_H_
#define BASE_BIND_HELPERS_H_
@@ -287,6 +329,45 @@ class OwnedWrapper {
mutable T* ptr_;
};
+// PassedWrapper is a copyable adapter for a scoper that ignores const.
+//
+// It is needed to get around the fact that Bind() takes a const reference to
+// all its arguments. Because Bind() takes a const reference to avoid
+// unnecessary copies, it is incompatible with movable-but-not-copyable
+// types; doing a destructive "move" of the type into Bind() would violate
+// the const correctness.
+//
+// This conundrum cannot be solved without either C++11 rvalue references or
+// a O(2^n) blowup of Bind() templates to handle each combination of regular
+// types and movable-but-not-copyable types. Thus we introduce a wrapper type
+// that is copyable to transmit the correct type information down into
+// BindState<>. Ignoring const in this type makes sense because it is only
+// created when we are explicitly trying to do a destructive move.
+//
+// Two notes:
+// 1) PassedWrapper supports any type that has a "Pass()" function.
+// This is intentional. The whitelisting of which specific types we
+// support is maintained by CallbackParamTraits<>.
+// 2) is_valid_ is distinct from NULL because it is valid to bind a "NULL"
+// scoper to a Callback and allow the Callback to execute once.
+template <typename T>
+class PassedWrapper {
+ public:
+ explicit PassedWrapper(T scoper) : is_valid_(true), scoper_(scoper.Pass()) {}
+ PassedWrapper(const PassedWrapper& other)
+ : is_valid_(other.is_valid_), scoper_(other.scoper_.Pass()) {
+ }
+ T Pass() const {
+ CHECK(is_valid_);
+ is_valid_ = false;
+ return scoper_.Pass();
+ }
+
+ private:
+ mutable bool is_valid_;
+ mutable T scoper_;
+};
+
// Unwrap the stored parameters for the wrappers above.
template <typename T>
struct UnwrapTraits {
@@ -330,9 +411,17 @@ struct UnwrapTraits<OwnedWrapper<T> > {
}
};
+template <typename T>
+struct UnwrapTraits<PassedWrapper<T> > {
+ typedef T ForwardType;
+ static T Unwrap(PassedWrapper<T>& o) {
+ return o.Pass();
+ }
+};
+
// Utility for handling different refcounting semantics in the Bind()
// function.
-template <bool, typename T>
+template <bool is_method, typename T>
struct MaybeRefcount;
template <typename T>
@@ -348,21 +437,15 @@ struct MaybeRefcount<false, T[n]> {
};
template <typename T>
-struct MaybeRefcount<true, T*> {
- static void AddRef(T* o) { o->AddRef(); }
- static void Release(T* o) { o->Release(); }
-};
-
-template <typename T>
-struct MaybeRefcount<true, UnretainedWrapper<T> > {
- static void AddRef(const UnretainedWrapper<T>&) {}
- static void Release(const UnretainedWrapper<T>&) {}
+struct MaybeRefcount<true, T> {
+ static void AddRef(const T&) {}
+ static void Release(const T&) {}
};
template <typename T>
-struct MaybeRefcount<true, OwnedWrapper<T> > {
- static void AddRef(const OwnedWrapper<T>&) {}
- static void Release(const OwnedWrapper<T>&) {}
+struct MaybeRefcount<true, T*> {
+ static void AddRef(T* o) { o->AddRef(); }
+ static void Release(T* o) { o->Release(); }
};
// No need to additionally AddRef() and Release() since we are storing a
@@ -379,19 +462,13 @@ struct MaybeRefcount<true, const T*> {
static void Release(const T* o) { o->Release(); }
};
-template <typename T>
-struct MaybeRefcount<true, WeakPtr<T> > {
- static void AddRef(const WeakPtr<T>&) {}
- static void Release(const WeakPtr<T>&) {}
-};
-
template <typename R>
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
+// method. It is used internally by Bind() to select the correct
// InvokeHelper that will no-op itself in the event the WeakPtr<> for
// the target object is invalidated.
//
@@ -422,6 +499,20 @@ static inline internal::OwnedWrapper<T> Owned(T* o) {
return internal::OwnedWrapper<T>(o);
}
+// We offer 2 syntaxes for calling Passed(). The first takes a temporary and
+// is best suited for use with the return value of a function. The second
+// takes a pointer to the scoper and is just syntactic sugar to avoid having
+// to write Passed(scoper.Pass()).
+template <typename T>
+static inline internal::PassedWrapper<T> Passed(T scoper) {
+ return internal::PassedWrapper<T>(scoper.Pass());
+}
+template <typename T>
+static inline internal::PassedWrapper<T> Passed(T* scoper) {
+ return internal::PassedWrapper<T>(scoper->Pass());
+}
+
+// -- DEPRECATED -- Use IgnoreResult instead.
template <typename R>
static inline Closure IgnoreReturn(Callback<R(void)> callback) {
return Bind(&internal::VoidReturnAdapter<R>, callback);
@@ -438,7 +529,6 @@ 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 ccd7ab2..50ffaa5 100644
--- a/base/bind_internal.h
+++ b/base/bind_internal.h
@@ -76,7 +76,6 @@ namespace internal {
// into the Bind() system, doing most of the type resolution.
// There are ARITY BindState types.
-
// RunnableAdapter<>
//
// The RunnableAdapter<> templates provide a uniform interface for invoking
@@ -167,7 +166,7 @@ class RunnableAdapter<R(*)(A1)> {
}
R Run(typename CallbackParamTraits<A1>::ForwardType a1) {
- return function_(a1);
+ return function_(CallbackForward(a1));
}
private:
@@ -186,7 +185,7 @@ class RunnableAdapter<R(T::*)(A1)> {
}
R Run(T* object, typename CallbackParamTraits<A1>::ForwardType a1) {
- return (object->*method_)(a1);
+ return (object->*method_)(CallbackForward(a1));
}
private:
@@ -205,7 +204,7 @@ class RunnableAdapter<R(T::*)(A1) const> {
}
R Run(const T* object, typename CallbackParamTraits<A1>::ForwardType a1) {
- return (object->*method_)(a1);
+ return (object->*method_)(CallbackForward(a1));
}
private:
@@ -224,7 +223,7 @@ class RunnableAdapter<R(*)(A1, A2)> {
R Run(typename CallbackParamTraits<A1>::ForwardType a1,
typename CallbackParamTraits<A2>::ForwardType a2) {
- return function_(a1, a2);
+ return function_(CallbackForward(a1), CallbackForward(a2));
}
private:
@@ -244,7 +243,7 @@ class RunnableAdapter<R(T::*)(A1, A2)> {
R Run(T* object, typename CallbackParamTraits<A1>::ForwardType a1,
typename CallbackParamTraits<A2>::ForwardType a2) {
- return (object->*method_)(a1, a2);
+ return (object->*method_)(CallbackForward(a1), CallbackForward(a2));
}
private:
@@ -264,7 +263,7 @@ class RunnableAdapter<R(T::*)(A1, A2) const> {
R Run(const T* object, typename CallbackParamTraits<A1>::ForwardType a1,
typename CallbackParamTraits<A2>::ForwardType a2) {
- return (object->*method_)(a1, a2);
+ return (object->*method_)(CallbackForward(a1), CallbackForward(a2));
}
private:
@@ -284,7 +283,8 @@ class RunnableAdapter<R(*)(A1, A2, A3)> {
R Run(typename CallbackParamTraits<A1>::ForwardType a1,
typename CallbackParamTraits<A2>::ForwardType a2,
typename CallbackParamTraits<A3>::ForwardType a3) {
- return function_(a1, a2, a3);
+ return function_(CallbackForward(a1), CallbackForward(a2),
+ CallbackForward(a3));
}
private:
@@ -305,7 +305,8 @@ class RunnableAdapter<R(T::*)(A1, A2, A3)> {
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);
+ return (object->*method_)(CallbackForward(a1), CallbackForward(a2),
+ CallbackForward(a3));
}
private:
@@ -326,7 +327,8 @@ class RunnableAdapter<R(T::*)(A1, A2, A3) const> {
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);
+ return (object->*method_)(CallbackForward(a1), CallbackForward(a2),
+ CallbackForward(a3));
}
private:
@@ -347,7 +349,8 @@ class RunnableAdapter<R(*)(A1, A2, A3, A4)> {
typename CallbackParamTraits<A2>::ForwardType a2,
typename CallbackParamTraits<A3>::ForwardType a3,
typename CallbackParamTraits<A4>::ForwardType a4) {
- return function_(a1, a2, a3, a4);
+ return function_(CallbackForward(a1), CallbackForward(a2),
+ CallbackForward(a3), CallbackForward(a4));
}
private:
@@ -370,7 +373,8 @@ class RunnableAdapter<R(T::*)(A1, A2, A3, A4)> {
typename CallbackParamTraits<A2>::ForwardType a2,
typename CallbackParamTraits<A3>::ForwardType a3,
typename CallbackParamTraits<A4>::ForwardType a4) {
- return (object->*method_)(a1, a2, a3, a4);
+ return (object->*method_)(CallbackForward(a1), CallbackForward(a2),
+ CallbackForward(a3), CallbackForward(a4));
}
private:
@@ -393,7 +397,8 @@ class RunnableAdapter<R(T::*)(A1, A2, A3, A4) const> {
typename CallbackParamTraits<A2>::ForwardType a2,
typename CallbackParamTraits<A3>::ForwardType a3,
typename CallbackParamTraits<A4>::ForwardType a4) {
- return (object->*method_)(a1, a2, a3, a4);
+ return (object->*method_)(CallbackForward(a1), CallbackForward(a2),
+ CallbackForward(a3), CallbackForward(a4));
}
private:
@@ -416,7 +421,8 @@ class RunnableAdapter<R(*)(A1, A2, A3, A4, A5)> {
typename CallbackParamTraits<A3>::ForwardType a3,
typename CallbackParamTraits<A4>::ForwardType a4,
typename CallbackParamTraits<A5>::ForwardType a5) {
- return function_(a1, a2, a3, a4, a5);
+ return function_(CallbackForward(a1), CallbackForward(a2),
+ CallbackForward(a3), CallbackForward(a4), CallbackForward(a5));
}
private:
@@ -440,7 +446,8 @@ class RunnableAdapter<R(T::*)(A1, A2, A3, A4, A5)> {
typename CallbackParamTraits<A3>::ForwardType a3,
typename CallbackParamTraits<A4>::ForwardType a4,
typename CallbackParamTraits<A5>::ForwardType a5) {
- return (object->*method_)(a1, a2, a3, a4, a5);
+ return (object->*method_)(CallbackForward(a1), CallbackForward(a2),
+ CallbackForward(a3), CallbackForward(a4), CallbackForward(a5));
}
private:
@@ -464,7 +471,8 @@ class RunnableAdapter<R(T::*)(A1, A2, A3, A4, A5) const> {
typename CallbackParamTraits<A3>::ForwardType a3,
typename CallbackParamTraits<A4>::ForwardType a4,
typename CallbackParamTraits<A5>::ForwardType a5) {
- return (object->*method_)(a1, a2, a3, a4, a5);
+ return (object->*method_)(CallbackForward(a1), CallbackForward(a2),
+ CallbackForward(a3), CallbackForward(a4), CallbackForward(a5));
}
private:
@@ -488,7 +496,9 @@ class RunnableAdapter<R(*)(A1, A2, A3, A4, A5, A6)> {
typename CallbackParamTraits<A4>::ForwardType a4,
typename CallbackParamTraits<A5>::ForwardType a5,
typename CallbackParamTraits<A6>::ForwardType a6) {
- return function_(a1, a2, a3, a4, a5, a6);
+ return function_(CallbackForward(a1), CallbackForward(a2),
+ CallbackForward(a3), CallbackForward(a4), CallbackForward(a5),
+ CallbackForward(a6));
}
private:
@@ -513,7 +523,9 @@ class RunnableAdapter<R(T::*)(A1, A2, A3, A4, A5, A6)> {
typename CallbackParamTraits<A4>::ForwardType a4,
typename CallbackParamTraits<A5>::ForwardType a5,
typename CallbackParamTraits<A6>::ForwardType a6) {
- return (object->*method_)(a1, a2, a3, a4, a5, a6);
+ return (object->*method_)(CallbackForward(a1), CallbackForward(a2),
+ CallbackForward(a3), CallbackForward(a4), CallbackForward(a5),
+ CallbackForward(a6));
}
private:
@@ -538,7 +550,9 @@ class RunnableAdapter<R(T::*)(A1, A2, A3, A4, A5, A6) const> {
typename CallbackParamTraits<A4>::ForwardType a4,
typename CallbackParamTraits<A5>::ForwardType a5,
typename CallbackParamTraits<A6>::ForwardType a6) {
- return (object->*method_)(a1, a2, a3, a4, a5, a6);
+ return (object->*method_)(CallbackForward(a1), CallbackForward(a2),
+ CallbackForward(a3), CallbackForward(a4), CallbackForward(a5),
+ CallbackForward(a6));
}
private:
@@ -563,7 +577,9 @@ class RunnableAdapter<R(*)(A1, A2, A3, A4, A5, A6, A7)> {
typename CallbackParamTraits<A5>::ForwardType a5,
typename CallbackParamTraits<A6>::ForwardType a6,
typename CallbackParamTraits<A7>::ForwardType a7) {
- return function_(a1, a2, a3, a4, a5, a6, a7);
+ return function_(CallbackForward(a1), CallbackForward(a2),
+ CallbackForward(a3), CallbackForward(a4), CallbackForward(a5),
+ CallbackForward(a6), CallbackForward(a7));
}
private:
@@ -589,7 +605,9 @@ class RunnableAdapter<R(T::*)(A1, A2, A3, A4, A5, A6, A7)> {
typename CallbackParamTraits<A5>::ForwardType a5,
typename CallbackParamTraits<A6>::ForwardType a6,
typename CallbackParamTraits<A7>::ForwardType a7) {
- return (object->*method_)(a1, a2, a3, a4, a5, a6, a7);
+ return (object->*method_)(CallbackForward(a1), CallbackForward(a2),
+ CallbackForward(a3), CallbackForward(a4), CallbackForward(a5),
+ CallbackForward(a6), CallbackForward(a7));
}
private:
@@ -615,7 +633,9 @@ class RunnableAdapter<R(T::*)(A1, A2, A3, A4, A5, A6, A7) const> {
typename CallbackParamTraits<A5>::ForwardType a5,
typename CallbackParamTraits<A6>::ForwardType a6,
typename CallbackParamTraits<A7>::ForwardType a7) {
- return (object->*method_)(a1, a2, a3, a4, a5, a6, a7);
+ return (object->*method_)(CallbackForward(a1), CallbackForward(a2),
+ CallbackForward(a3), CallbackForward(a4), CallbackForward(a5),
+ CallbackForward(a6), CallbackForward(a7));
}
private:
@@ -837,7 +857,7 @@ 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);
+ return runnable.Run(CallbackForward(a1));
}
};
@@ -845,7 +865,7 @@ template <typename Runnable,typename A1>
struct InvokeHelper<false, void, Runnable,
void(A1)> {
static void MakeItSo(Runnable runnable, A1 a1) {
- runnable.Run(a1);
+ runnable.Run(CallbackForward(a1));
}
};
@@ -857,7 +877,7 @@ struct InvokeHelper<true, void, Runnable,
return;
}
- runnable.Run(a1);
+ runnable.Run(CallbackForward(a1));
}
};
@@ -865,7 +885,7 @@ 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);
+ return runnable.Run(CallbackForward(a1), CallbackForward(a2));
}
};
@@ -873,7 +893,7 @@ 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);
+ runnable.Run(CallbackForward(a1), CallbackForward(a2));
}
};
@@ -885,7 +905,7 @@ struct InvokeHelper<true, void, Runnable,
return;
}
- runnable.Run(a1, a2);
+ runnable.Run(CallbackForward(a1), CallbackForward(a2));
}
};
@@ -894,7 +914,8 @@ template <typename ReturnType, typename Runnable,typename A1, typename A2,
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);
+ return runnable.Run(CallbackForward(a1), CallbackForward(a2),
+ CallbackForward(a3));
}
};
@@ -902,7 +923,7 @@ 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);
+ runnable.Run(CallbackForward(a1), CallbackForward(a2), CallbackForward(a3));
}
};
@@ -914,7 +935,7 @@ struct InvokeHelper<true, void, Runnable,
return;
}
- runnable.Run(a1, a2, a3);
+ runnable.Run(CallbackForward(a1), CallbackForward(a2), CallbackForward(a3));
}
};
@@ -923,7 +944,8 @@ template <typename ReturnType, typename Runnable,typename A1, typename A2,
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);
+ return runnable.Run(CallbackForward(a1), CallbackForward(a2),
+ CallbackForward(a3), CallbackForward(a4));
}
};
@@ -931,7 +953,8 @@ 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);
+ runnable.Run(CallbackForward(a1), CallbackForward(a2), CallbackForward(a3),
+ CallbackForward(a4));
}
};
@@ -943,7 +966,8 @@ struct InvokeHelper<true, void, Runnable,
return;
}
- runnable.Run(a1, a2, a3, a4);
+ runnable.Run(CallbackForward(a1), CallbackForward(a2), CallbackForward(a3),
+ CallbackForward(a4));
}
};
@@ -953,7 +977,8 @@ 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);
+ return runnable.Run(CallbackForward(a1), CallbackForward(a2),
+ CallbackForward(a3), CallbackForward(a4), CallbackForward(a5));
}
};
@@ -962,7 +987,8 @@ template <typename Runnable,typename A1, typename A2, typename A3, typename A4,
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);
+ runnable.Run(CallbackForward(a1), CallbackForward(a2), CallbackForward(a3),
+ CallbackForward(a4), CallbackForward(a5));
}
};
@@ -975,7 +1001,8 @@ struct InvokeHelper<true, void, Runnable,
return;
}
- runnable.Run(a1, a2, a3, a4, a5);
+ runnable.Run(CallbackForward(a1), CallbackForward(a2), CallbackForward(a3),
+ CallbackForward(a4), CallbackForward(a5));
}
};
@@ -985,7 +1012,9 @@ 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);
+ return runnable.Run(CallbackForward(a1), CallbackForward(a2),
+ CallbackForward(a3), CallbackForward(a4), CallbackForward(a5),
+ CallbackForward(a6));
}
};
@@ -995,7 +1024,8 @@ 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);
+ runnable.Run(CallbackForward(a1), CallbackForward(a2), CallbackForward(a3),
+ CallbackForward(a4), CallbackForward(a5), CallbackForward(a6));
}
};
@@ -1009,7 +1039,8 @@ struct InvokeHelper<true, void, Runnable,
return;
}
- runnable.Run(a1, a2, a3, a4, a5, a6);
+ runnable.Run(CallbackForward(a1), CallbackForward(a2), CallbackForward(a3),
+ CallbackForward(a4), CallbackForward(a5), CallbackForward(a6));
}
};
@@ -1019,7 +1050,9 @@ struct InvokeHelper<false, ReturnType, Runnable,
void(A1, A2, A3, A4, A5, A6, A7)> {
static ReturnType MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4,
A5 a5, A6 a6, A7 a7) {
- return runnable.Run(a1, a2, a3, a4, a5, a6, a7);
+ return runnable.Run(CallbackForward(a1), CallbackForward(a2),
+ CallbackForward(a3), CallbackForward(a4), CallbackForward(a5),
+ CallbackForward(a6), CallbackForward(a7));
}
};
@@ -1029,7 +1062,9 @@ struct InvokeHelper<false, void, Runnable,
void(A1, A2, A3, A4, A5, A6, A7)> {
static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5,
A6 a6, A7 a7) {
- runnable.Run(a1, a2, a3, a4, a5, a6, a7);
+ runnable.Run(CallbackForward(a1), CallbackForward(a2), CallbackForward(a3),
+ CallbackForward(a4), CallbackForward(a5), CallbackForward(a6),
+ CallbackForward(a7));
}
};
@@ -1043,7 +1078,9 @@ struct InvokeHelper<true, void, Runnable,
return;
}
- runnable.Run(a1, a2, a3, a4, a5, a6, a7);
+ runnable.Run(CallbackForward(a1), CallbackForward(a2), CallbackForward(a3),
+ CallbackForward(a4), CallbackForward(a5), CallbackForward(a6),
+ CallbackForward(a7));
}
};
@@ -1106,7 +1143,7 @@ struct Invoker<0, StorageType, R(X1)> {
return InvokeHelper<StorageType::IsWeakCall::value, R,
typename StorageType::RunnableType,
void(typename CallbackParamTraits<X1>::ForwardType x1)>
- ::MakeItSo(storage->runnable_, x1);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1));
}
};
@@ -1130,7 +1167,7 @@ struct Invoker<1, StorageType, R(X1)> {
return InvokeHelper<StorageType::IsWeakCall::value, R,
typename StorageType::RunnableType,
void(typename Bound1UnwrapTraits::ForwardType)>
- ::MakeItSo(storage->runnable_, x1);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1));
}
};
@@ -1156,7 +1193,8 @@ struct Invoker<0, StorageType, R(X1, X2)> {
typename StorageType::RunnableType,
void(typename CallbackParamTraits<X1>::ForwardType x1,
typename CallbackParamTraits<X2>::ForwardType x2)>
- ::MakeItSo(storage->runnable_, x1, x2);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2));
}
};
@@ -1183,7 +1221,8 @@ struct Invoker<1, StorageType, R(X1, X2)> {
typename StorageType::RunnableType,
void(typename Bound1UnwrapTraits::ForwardType,
typename CallbackParamTraits<X2>::ForwardType x2)>
- ::MakeItSo(storage->runnable_, x1, x2);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2));
}
};
@@ -1211,7 +1250,8 @@ struct Invoker<2, StorageType, R(X1, X2)> {
typename StorageType::RunnableType,
void(typename Bound1UnwrapTraits::ForwardType,
typename Bound2UnwrapTraits::ForwardType)>
- ::MakeItSo(storage->runnable_, x1, x2);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2));
}
};
@@ -1241,7 +1281,8 @@ struct Invoker<0, StorageType, R(X1, X2, X3)> {
void(typename CallbackParamTraits<X1>::ForwardType x1,
typename CallbackParamTraits<X2>::ForwardType x2,
typename CallbackParamTraits<X3>::ForwardType x3)>
- ::MakeItSo(storage->runnable_, x1, x2, x3);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3));
}
};
@@ -1272,7 +1313,8 @@ struct Invoker<1, StorageType, R(X1, X2, X3)> {
void(typename Bound1UnwrapTraits::ForwardType,
typename CallbackParamTraits<X2>::ForwardType x2,
typename CallbackParamTraits<X3>::ForwardType x3)>
- ::MakeItSo(storage->runnable_, x1, x2, x3);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3));
}
};
@@ -1304,7 +1346,8 @@ struct Invoker<2, StorageType, R(X1, X2, X3)> {
void(typename Bound1UnwrapTraits::ForwardType,
typename Bound2UnwrapTraits::ForwardType,
typename CallbackParamTraits<X3>::ForwardType x3)>
- ::MakeItSo(storage->runnable_, x1, x2, x3);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3));
}
};
@@ -1337,7 +1380,8 @@ struct Invoker<3, StorageType, R(X1, X2, X3)> {
void(typename Bound1UnwrapTraits::ForwardType,
typename Bound2UnwrapTraits::ForwardType,
typename Bound3UnwrapTraits::ForwardType)>
- ::MakeItSo(storage->runnable_, x1, x2, x3);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3));
}
};
@@ -1370,7 +1414,9 @@ struct Invoker<0, StorageType, R(X1, X2, X3, X4)> {
typename CallbackParamTraits<X2>::ForwardType x2,
typename CallbackParamTraits<X3>::ForwardType x3,
typename CallbackParamTraits<X4>::ForwardType x4)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4));
}
};
@@ -1404,7 +1450,9 @@ struct Invoker<1, StorageType, R(X1, X2, X3, X4)> {
typename CallbackParamTraits<X2>::ForwardType x2,
typename CallbackParamTraits<X3>::ForwardType x3,
typename CallbackParamTraits<X4>::ForwardType x4)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4));
}
};
@@ -1439,7 +1487,9 @@ struct Invoker<2, StorageType, R(X1, X2, X3, X4)> {
typename Bound2UnwrapTraits::ForwardType,
typename CallbackParamTraits<X3>::ForwardType x3,
typename CallbackParamTraits<X4>::ForwardType x4)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4));
}
};
@@ -1475,7 +1525,9 @@ struct Invoker<3, StorageType, R(X1, X2, X3, X4)> {
typename Bound2UnwrapTraits::ForwardType,
typename Bound3UnwrapTraits::ForwardType,
typename CallbackParamTraits<X4>::ForwardType x4)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4));
}
};
@@ -1512,7 +1564,9 @@ struct Invoker<4, StorageType, R(X1, X2, X3, X4)> {
typename Bound2UnwrapTraits::ForwardType,
typename Bound3UnwrapTraits::ForwardType,
typename Bound4UnwrapTraits::ForwardType)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4));
}
};
@@ -1548,7 +1602,9 @@ struct Invoker<0, StorageType, R(X1, X2, X3, X4, X5)> {
typename CallbackParamTraits<X3>::ForwardType x3,
typename CallbackParamTraits<X4>::ForwardType x4,
typename CallbackParamTraits<X5>::ForwardType x5)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4), CallbackForward(x5));
}
};
@@ -1585,7 +1641,9 @@ struct Invoker<1, StorageType, R(X1, X2, X3, X4, X5)> {
typename CallbackParamTraits<X3>::ForwardType x3,
typename CallbackParamTraits<X4>::ForwardType x4,
typename CallbackParamTraits<X5>::ForwardType x5)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4), CallbackForward(x5));
}
};
@@ -1623,7 +1681,9 @@ struct Invoker<2, StorageType, R(X1, X2, X3, X4, X5)> {
typename CallbackParamTraits<X3>::ForwardType x3,
typename CallbackParamTraits<X4>::ForwardType x4,
typename CallbackParamTraits<X5>::ForwardType x5)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4), CallbackForward(x5));
}
};
@@ -1662,7 +1722,9 @@ struct Invoker<3, StorageType, R(X1, X2, X3, X4, X5)> {
typename Bound3UnwrapTraits::ForwardType,
typename CallbackParamTraits<X4>::ForwardType x4,
typename CallbackParamTraits<X5>::ForwardType x5)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4), CallbackForward(x5));
}
};
@@ -1702,7 +1764,9 @@ struct Invoker<4, StorageType, R(X1, X2, X3, X4, X5)> {
typename Bound3UnwrapTraits::ForwardType,
typename Bound4UnwrapTraits::ForwardType,
typename CallbackParamTraits<X5>::ForwardType x5)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4), CallbackForward(x5));
}
};
@@ -1743,7 +1807,9 @@ struct Invoker<5, StorageType, R(X1, X2, X3, X4, X5)> {
typename Bound3UnwrapTraits::ForwardType,
typename Bound4UnwrapTraits::ForwardType,
typename Bound5UnwrapTraits::ForwardType)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4), CallbackForward(x5));
}
};
@@ -1782,7 +1848,10 @@ struct Invoker<0, StorageType, R(X1, X2, X3, X4, X5, X6)> {
typename CallbackParamTraits<X4>::ForwardType x4,
typename CallbackParamTraits<X5>::ForwardType x5,
typename CallbackParamTraits<X6>::ForwardType x6)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4), CallbackForward(x5),
+ CallbackForward(x6));
}
};
@@ -1822,7 +1891,10 @@ struct Invoker<1, StorageType, R(X1, X2, X3, X4, X5, X6)> {
typename CallbackParamTraits<X4>::ForwardType x4,
typename CallbackParamTraits<X5>::ForwardType x5,
typename CallbackParamTraits<X6>::ForwardType x6)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4), CallbackForward(x5),
+ CallbackForward(x6));
}
};
@@ -1863,7 +1935,10 @@ struct Invoker<2, StorageType, R(X1, X2, X3, X4, X5, X6)> {
typename CallbackParamTraits<X4>::ForwardType x4,
typename CallbackParamTraits<X5>::ForwardType x5,
typename CallbackParamTraits<X6>::ForwardType x6)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4), CallbackForward(x5),
+ CallbackForward(x6));
}
};
@@ -1905,7 +1980,10 @@ struct Invoker<3, StorageType, R(X1, X2, X3, X4, X5, X6)> {
typename CallbackParamTraits<X4>::ForwardType x4,
typename CallbackParamTraits<X5>::ForwardType x5,
typename CallbackParamTraits<X6>::ForwardType x6)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4), CallbackForward(x5),
+ CallbackForward(x6));
}
};
@@ -1948,7 +2026,10 @@ struct Invoker<4, StorageType, R(X1, X2, X3, X4, X5, X6)> {
typename Bound4UnwrapTraits::ForwardType,
typename CallbackParamTraits<X5>::ForwardType x5,
typename CallbackParamTraits<X6>::ForwardType x6)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4), CallbackForward(x5),
+ CallbackForward(x6));
}
};
@@ -1992,7 +2073,10 @@ struct Invoker<5, StorageType, R(X1, X2, X3, X4, X5, X6)> {
typename Bound4UnwrapTraits::ForwardType,
typename Bound5UnwrapTraits::ForwardType,
typename CallbackParamTraits<X6>::ForwardType x6)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4), CallbackForward(x5),
+ CallbackForward(x6));
}
};
@@ -2037,7 +2121,10 @@ struct Invoker<6, StorageType, R(X1, X2, X3, X4, X5, X6)> {
typename Bound4UnwrapTraits::ForwardType,
typename Bound5UnwrapTraits::ForwardType,
typename Bound6UnwrapTraits::ForwardType)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4), CallbackForward(x5),
+ CallbackForward(x6));
}
};
@@ -2079,7 +2166,10 @@ struct Invoker<0, StorageType, R(X1, X2, X3, X4, X5, X6, X7)> {
typename CallbackParamTraits<X5>::ForwardType x5,
typename CallbackParamTraits<X6>::ForwardType x6,
typename CallbackParamTraits<X7>::ForwardType x7)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6, x7);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4), CallbackForward(x5),
+ CallbackForward(x6), CallbackForward(x7));
}
};
@@ -2122,7 +2212,10 @@ struct Invoker<1, StorageType, R(X1, X2, X3, X4, X5, X6, X7)> {
typename CallbackParamTraits<X5>::ForwardType x5,
typename CallbackParamTraits<X6>::ForwardType x6,
typename CallbackParamTraits<X7>::ForwardType x7)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6, x7);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4), CallbackForward(x5),
+ CallbackForward(x6), CallbackForward(x7));
}
};
@@ -2166,7 +2259,10 @@ struct Invoker<2, StorageType, R(X1, X2, X3, X4, X5, X6, X7)> {
typename CallbackParamTraits<X5>::ForwardType x5,
typename CallbackParamTraits<X6>::ForwardType x6,
typename CallbackParamTraits<X7>::ForwardType x7)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6, x7);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4), CallbackForward(x5),
+ CallbackForward(x6), CallbackForward(x7));
}
};
@@ -2211,7 +2307,10 @@ struct Invoker<3, StorageType, R(X1, X2, X3, X4, X5, X6, X7)> {
typename CallbackParamTraits<X5>::ForwardType x5,
typename CallbackParamTraits<X6>::ForwardType x6,
typename CallbackParamTraits<X7>::ForwardType x7)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6, x7);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4), CallbackForward(x5),
+ CallbackForward(x6), CallbackForward(x7));
}
};
@@ -2257,7 +2356,10 @@ struct Invoker<4, StorageType, R(X1, X2, X3, X4, X5, X6, X7)> {
typename CallbackParamTraits<X5>::ForwardType x5,
typename CallbackParamTraits<X6>::ForwardType x6,
typename CallbackParamTraits<X7>::ForwardType x7)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6, x7);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4), CallbackForward(x5),
+ CallbackForward(x6), CallbackForward(x7));
}
};
@@ -2304,7 +2406,10 @@ struct Invoker<5, StorageType, R(X1, X2, X3, X4, X5, X6, X7)> {
typename Bound5UnwrapTraits::ForwardType,
typename CallbackParamTraits<X6>::ForwardType x6,
typename CallbackParamTraits<X7>::ForwardType x7)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6, x7);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4), CallbackForward(x5),
+ CallbackForward(x6), CallbackForward(x7));
}
};
@@ -2352,7 +2457,10 @@ struct Invoker<6, StorageType, R(X1, X2, X3, X4, X5, X6, X7)> {
typename Bound5UnwrapTraits::ForwardType,
typename Bound6UnwrapTraits::ForwardType,
typename CallbackParamTraits<X7>::ForwardType x7)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6, x7);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4), CallbackForward(x5),
+ CallbackForward(x6), CallbackForward(x7));
}
};
@@ -2401,7 +2509,10 @@ struct Invoker<7, StorageType, R(X1, X2, X3, X4, X5, X6, X7)> {
typename Bound5UnwrapTraits::ForwardType,
typename Bound6UnwrapTraits::ForwardType,
typename Bound7UnwrapTraits::ForwardType)>
- ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6, x7);
+ ::MakeItSo(storage->runnable_, CallbackForward(x1),
+ CallbackForward(x2), CallbackForward(x3),
+ CallbackForward(x4), CallbackForward(x5),
+ CallbackForward(x6), CallbackForward(x7));
}
};
diff --git a/base/bind_internal.h.pump b/base/bind_internal.h.pump
index 53dcbd3..7fd63d8 100644
--- a/base/bind_internal.h.pump
+++ b/base/bind_internal.h.pump
@@ -82,7 +82,6 @@ namespace internal {
// into the Bind() system, doing most of the type resolution.
// There are ARITY BindState types.
-
// RunnableAdapter<>
//
// The RunnableAdapter<> templates provide a uniform interface for invoking
@@ -121,7 +120,7 @@ class RunnableAdapter<R(*)($for ARG , [[A$(ARG)]])> {
}
R Run($for ARG , [[typename CallbackParamTraits<A$(ARG)>::ForwardType a$(ARG)]]) {
- return function_($for ARG , [[a$(ARG)]]);
+ return function_($for ARG , [[CallbackForward(a$(ARG))]]);
}
private:
@@ -143,7 +142,7 @@ $if ARITY > 0[[, ]] $for ARG , [[A$(ARG)]]);
R Run(T* object[[]]
$if ARITY > 0[[, ]] $for ARG, [[typename CallbackParamTraits<A$(ARG)>::ForwardType a$(ARG)]]) {
- return (object->*method_)($for ARG , [[a$(ARG)]]);
+ return (object->*method_)($for ARG , [[CallbackForward(a$(ARG))]]);
}
private:
@@ -165,7 +164,7 @@ $if ARITY > 0[[, ]] $for ARG , [[A$(ARG)]]);
R Run(const T* object[[]]
$if ARITY > 0[[, ]] $for ARG, [[typename CallbackParamTraits<A$(ARG)>::ForwardType a$(ARG)]]) {
- return (object->*method_)($for ARG , [[a$(ARG)]]);
+ return (object->*method_)($for ARG , [[CallbackForward(a$(ARG))]]);
}
private:
@@ -291,7 +290,7 @@ 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)]]);
+ return runnable.Run($for ARG , [[CallbackForward(a$(ARG))]]);
}
};
@@ -301,7 +300,7 @@ 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)]]);
+ runnable.Run($for ARG , [[CallbackForward(a$(ARG))]]);
}
};
@@ -316,7 +315,7 @@ $if ARITY > 0[[, ]] $for ARG , [[A$(ARG) a$(ARG)]]) {
return;
}
- runnable.Run($for ARG , [[a$(ARG)]]);
+ runnable.Run($for ARG , [[CallbackForward(a$(ARG))]]);
}
};
@@ -404,7 +403,7 @@ typename CallbackParamTraits<X$(UNBOUND_ARG)>::ForwardType x$(UNBOUND_ARG)
]]
)>
::MakeItSo(storage->runnable_
-$if ARITY > 0[[, ]] $for ARG , [[x$(ARG)]]);
+$if ARITY > 0[[, ]] $for ARG , [[CallbackForward(x$(ARG))]]);
}
};
diff --git a/base/bind_unittest.cc b/base/bind_unittest.cc
index 372523b..354b225 100644
--- a/base/bind_unittest.cc
+++ b/base/bind_unittest.cc
@@ -5,6 +5,9 @@
#include "base/bind.h"
#include "base/callback.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -102,7 +105,7 @@ class CopyCounter {
(*copies_)++;
}
- // Probing for copies from coerscion.
+ // Probing for copies from coercion.
CopyCounter(const DerivedCopyCounter& other)
: copies_(other.copies_),
assigns_(other.assigns_) {
@@ -149,6 +152,11 @@ class DeleteCounter {
int* deletes_;
};
+template <typename T>
+T PassThru(T scoper) {
+ return scoper.Pass();
+}
+
// Some test functions that we can Bind to.
template <typename T>
T PolymorphicIdentity(T t) {
@@ -668,8 +676,8 @@ TEST_F(BindTest, Owned) {
// return the same value.
Callback<DeleteCounter*(void)> no_capture_cb =
Bind(&PolymorphicIdentity<DeleteCounter*>, Owned(counter));
- EXPECT_EQ(counter, no_capture_cb.Run());
- EXPECT_EQ(counter, no_capture_cb.Run());
+ ASSERT_EQ(counter, no_capture_cb.Run());
+ ASSERT_EQ(counter, no_capture_cb.Run());
EXPECT_EQ(0, deletes);
no_capture_cb.Reset(); // This should trigger a delete.
EXPECT_EQ(1, deletes);
@@ -684,11 +692,60 @@ TEST_F(BindTest, Owned) {
EXPECT_EQ(1, deletes);
}
+// Passed() wrapper support.
+// - Passed() can be constructed from a pointer to scoper.
+// - Passed() can be constructed from a scoper rvalue.
+// - Using Passed() gives Callback Ownership.
+// - Ownership is transferred from Callback to callee on the first Run().
+// - Callback supports unbound arguments.
+TEST_F(BindTest, ScopedPtr) {
+ int deletes = 0;
+
+ // Tests the Passed() function's support for pointers.
+ scoped_ptr<DeleteCounter> ptr(new DeleteCounter(&deletes));
+ Callback<scoped_ptr<DeleteCounter>(void)> unused_callback =
+ Bind(&PassThru<scoped_ptr<DeleteCounter> >, Passed(&ptr));
+ EXPECT_FALSE(ptr.get());
+ EXPECT_EQ(0, deletes);
+
+ // If we never invoke the Callback, it retains ownership and deletes.
+ unused_callback.Reset();
+ EXPECT_EQ(1, deletes);
+
+ // Tests the Passed() function's support for rvalues.
+ deletes = 0;
+ DeleteCounter* counter = new DeleteCounter(&deletes);
+ Callback<scoped_ptr<DeleteCounter>(void)> callback =
+ Bind(&PassThru<scoped_ptr<DeleteCounter> >,
+ Passed(scoped_ptr<DeleteCounter>(counter)));
+ EXPECT_FALSE(ptr.get());
+ EXPECT_EQ(0, deletes);
+
+ // Check that ownership can be transferred back out.
+ scoped_ptr<DeleteCounter> result = callback.Run();
+ ASSERT_EQ(counter, result.get());
+ EXPECT_EQ(0, deletes);
+
+ // Resetting does not delete since ownership was transferred.
+ callback.Reset();
+ EXPECT_EQ(0, deletes);
+
+ // Ensure that we actually did get ownership.
+ result.reset();
+ EXPECT_EQ(1, deletes);
+
+ // Test unbound argument forwarding.
+ Callback<scoped_ptr<DeleteCounter>(scoped_ptr<DeleteCounter>)> cb_unbound =
+ Bind(&PassThru<scoped_ptr<DeleteCounter> >);
+ ptr.reset(new DeleteCounter(&deletes));
+ cb_unbound.Run(ptr.Pass());
+}
+
// Argument Copy-constructor usage for non-reference parameters.
// - Bound arguments are only copied once.
// - Forwarded arguments are only copied once.
-// - Forwarded arguments with coerscions are only copied twice (once for the
-// coerscion, and one for the final dispatch).
+// - Forwarded arguments with coercions are only copied twice (once for the
+// coercion, and one for the final dispatch).
TEST_F(BindTest, ArgumentCopies) {
int copies = 0;
int assigns = 0;
diff --git a/base/callback.h b/base/callback.h
index abaa438..318bff0 100644
--- a/base/callback.h
+++ b/base/callback.h
@@ -312,7 +312,7 @@ class Callback<R(A1)> : public internal::CallbackBase {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
- return f(bind_state_.get(), a1);
+ return f(bind_state_.get(), internal::CallbackForward(a1));
}
private:
@@ -353,8 +353,8 @@ class Callback<R(A1, A2)> : public internal::CallbackBase {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
- return f(bind_state_.get(), a1,
- a2);
+ return f(bind_state_.get(), internal::CallbackForward(a1),
+ internal::CallbackForward(a2));
}
private:
@@ -397,9 +397,9 @@ class Callback<R(A1, A2, A3)> : public internal::CallbackBase {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
- return f(bind_state_.get(), a1,
- a2,
- a3);
+ return f(bind_state_.get(), internal::CallbackForward(a1),
+ internal::CallbackForward(a2),
+ internal::CallbackForward(a3));
}
private:
@@ -444,10 +444,10 @@ class Callback<R(A1, A2, A3, A4)> : public internal::CallbackBase {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
- return f(bind_state_.get(), a1,
- a2,
- a3,
- a4);
+ return f(bind_state_.get(), internal::CallbackForward(a1),
+ internal::CallbackForward(a2),
+ internal::CallbackForward(a3),
+ internal::CallbackForward(a4));
}
private:
@@ -495,11 +495,11 @@ class Callback<R(A1, A2, A3, A4, A5)> : public internal::CallbackBase {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
- return f(bind_state_.get(), a1,
- a2,
- a3,
- a4,
- a5);
+ return f(bind_state_.get(), internal::CallbackForward(a1),
+ internal::CallbackForward(a2),
+ internal::CallbackForward(a3),
+ internal::CallbackForward(a4),
+ internal::CallbackForward(a5));
}
private:
@@ -549,12 +549,12 @@ class Callback<R(A1, A2, A3, A4, A5, A6)> : public internal::CallbackBase {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
- return f(bind_state_.get(), a1,
- a2,
- a3,
- a4,
- a5,
- a6);
+ return f(bind_state_.get(), internal::CallbackForward(a1),
+ internal::CallbackForward(a2),
+ internal::CallbackForward(a3),
+ internal::CallbackForward(a4),
+ internal::CallbackForward(a5),
+ internal::CallbackForward(a6));
}
private:
@@ -606,13 +606,13 @@ class Callback<R(A1, A2, A3, A4, A5, A6, A7)> : public internal::CallbackBase {
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);
- return f(bind_state_.get(), a1,
- a2,
- a3,
- a4,
- a5,
- a6,
- a7);
+ return f(bind_state_.get(), internal::CallbackForward(a1),
+ internal::CallbackForward(a2),
+ internal::CallbackForward(a3),
+ internal::CallbackForward(a4),
+ internal::CallbackForward(a5),
+ internal::CallbackForward(a6),
+ internal::CallbackForward(a7));
}
private:
diff --git a/base/callback.h.pump b/base/callback.h.pump
index 2216a3c..d2285e9 100644
--- a/base/callback.h.pump
+++ b/base/callback.h.pump
@@ -293,7 +293,7 @@ class Callback<R($for ARG , [[A$(ARG)]])> : public internal::CallbackBase {
return f(bind_state_.get()[[]]
$if ARITY != 0 [[, ]]
$for ARG ,
- [[a$(ARG)]]);
+ [[internal::CallbackForward(a$(ARG))]]);
}
private:
diff --git a/base/callback_internal.h b/base/callback_internal.h
index 4bb8aa9..21599bf 100644
--- a/base/callback_internal.h
+++ b/base/callback_internal.h
@@ -13,6 +13,7 @@
#include "base/base_export.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
namespace base {
namespace internal {
@@ -110,6 +111,64 @@ struct CallbackParamTraits<T[]> {
typedef const T* StorageType;
};
+// Parameter traits for movable-but-not-copyable scopers.
+//
+// Callback<>/Bind() understands movable-but-not-copyable semantics where
+// the type cannot be copied but can still have its state destructively
+// transferred (aka. moved) to another instance of the same type by calling a
+// helper function. When used with Bind(), this signifies transferal of the
+// object's state to the target function.
+//
+// For these types, the ForwardType must not be a const reference, or a
+// reference. A const reference is inappropriate, and would break const
+// correctness, because we are implementing a destructive move. A non-const
+// reference cannot be used with temporaries which means the result of a
+// function or a cast would not be usable with Callback<> or Bind().
+//
+// TODO(ajwong): We might be able to use SFINAE to search for the existence of
+// a Pass() function in the type and avoid the whitelist in CallbackParamTraits
+// and CallbackForward.
+template <typename T>
+struct CallbackParamTraits<scoped_ptr<T> > {
+ typedef scoped_ptr<T> ForwardType;
+ typedef scoped_ptr<T> StorageType;
+};
+
+template <typename T>
+struct CallbackParamTraits<scoped_array<T> > {
+ typedef scoped_array<T> ForwardType;
+ typedef scoped_array<T> StorageType;
+};
+
+template <typename T>
+struct CallbackParamTraits<scoped_ptr_malloc<T> > {
+ typedef scoped_ptr_malloc<T> ForwardType;
+ typedef scoped_ptr_malloc<T> StorageType;
+};
+
+// CallbackForward() is a very limited simulation of C++11's std::forward()
+// used by the Callback/Bind system for a set of movable-but-not-copyable
+// types. It is needed because forwarding a movable-but-not-copyable
+// argument to another function requires us to invoke the proper move
+// operator to create a rvalue version of the type. The supported types are
+// whitelisted below as overloads of the CallbackForward() function. The
+// default template compiles out to be a no-op.
+//
+// In C++11, std::forward would replace all uses of this function. However, it
+// is impossible to implement a general std::forward with C++11 due to a lack
+// of rvalue references.
+template <typename T>
+T& CallbackForward(T& t) { return t; }
+
+template <typename T>
+scoped_ptr<T> CallbackForward(scoped_ptr<T>& p) { return p.Pass(); }
+
+template <typename T>
+scoped_ptr<T> CallbackForward(scoped_array<T>& p) { return p.Pass(); }
+
+template <typename T>
+scoped_ptr<T> CallbackForward(scoped_ptr_malloc<T>& p) { return p.Pass(); }
+
} // namespace internal
} // namespace base
diff --git a/base/memory/scoped_ptr.h b/base/memory/scoped_ptr.h
index 5ac6846..2d69a9d 100644
--- a/base/memory/scoped_ptr.h
+++ b/base/memory/scoped_ptr.h
@@ -32,6 +32,41 @@
// foo.get()->Method(); // Foo::Method on the 0th element.
// foo[10].Method(); // Foo::Method on the 10th element.
// }
+//
+// These scopers also implement part of the functionality of C++11 unique_ptr
+// in that they are "movable but not copyable." You can use the scopers in
+// the parameter and return types of functions to signify ownership transfer
+// in to and out of a function. When calling a function that has a scoper
+// as the argument type, it must be called with the result of an analogous
+// scoper's Pass() function or another function that generates a temporary;
+// passing by copy will NOT work. Here is an example using scoped_ptr:
+//
+// void TakesOwnership(scoped_ptr<Foo> arg) {
+// // Do something with arg
+// }
+// scoped_ptr<Foo> CreateFoo() {
+// // No need for calling Pass() because we are constructing a temporary
+// // for the return value.
+// return scoped_ptr<Foo>(new Foo("new"));
+// }
+// scoped_ptr<Foo> PassThru(scoped_ptr<Foo> arg) {
+// return arg.Pass();
+// }
+//
+// {
+// scoped_ptr<Foo> ptr(new Foo("yay")); // ptr manages Foo("yay)"
+// TakesOwnership(ptr.Pass()); // ptr no longer owns Foo("yay").
+// scoped_ptr<Foo> ptr2 = CreateFoo(); // ptr2 owns the return Foo.
+// scoped_ptr<Foo> ptr3 = // ptr3 now owns what was in ptr2.
+// PassThru(ptr2.Pass()); // ptr2 is correspondingly NULL.
+// }
+//
+// Notice that if you do not call Pass() when returning from PassThru(), or
+// when invoking TakesOwnership(), the code will not compile because scopers
+// are not copyable; they only implement move semantics which require calling
+// the Pass() function to signify a destructive transfer of state. CreateFoo()
+// is different though because we are constructing a temporary on the return
+// line and thus can avoid needing to call Pass().
#ifndef BASE_MEMORY_SCOPED_PTR_H_
#define BASE_MEMORY_SCOPED_PTR_H_
@@ -47,12 +82,35 @@
#include "base/compiler_specific.h"
+// Macro with the boilerplate C++03 move emulation for a class.
+//
+// In C++11, this is done via rvalue references. Here, we use C++03 move
+// emulation to fake an rvalue reference. For a more thorough explanation
+// of the technique, see:
+//
+// http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Move_Constructor
+//
+#define CPP_03_MOVE_EMULATION(scoper, field) \
+ private: \
+ struct RValue { \
+ explicit RValue(scoper& obj) : obj_(obj) {} \
+ scoper& obj_; \
+ }; \
+ public: \
+ operator RValue() { return RValue(*this); } \
+ scoper(RValue proxy) : field(proxy.obj_.release()) { } \
+ scoper& operator=(RValue proxy) { \
+ swap(proxy.obj_); \
+ return *this; \
+ } \
+ scoper Pass() { return scoper(RValue(*this)); }
+
// A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T>
// automatically deletes the pointer it holds (if any).
// That is, scoped_ptr<T> owns the T object that it points to.
// Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object.
// Also like T*, scoped_ptr<T> is thread-compatible, and once you
-// dereference it, you get the threadsafety guarantees of T.
+// dereference it, you get the thread safety guarantees of T.
//
// The size of a scoped_ptr is small:
// sizeof(scoped_ptr<C>) == sizeof(C*)
@@ -122,6 +180,8 @@ class scoped_ptr {
return retVal;
}
+ CPP_03_MOVE_EMULATION(scoped_ptr, ptr_);
+
private:
C* ptr_;
@@ -131,9 +191,10 @@ class scoped_ptr {
template <class C2> bool operator==(scoped_ptr<C2> const& p2) const;
template <class C2> bool operator!=(scoped_ptr<C2> const& p2) const;
- // Disallow evil constructors
- scoped_ptr(const scoped_ptr&);
- void operator=(const scoped_ptr&);
+ // Disallow evil constructors. Note that MUST NOT take a const& because we
+ // are implementing move semantics. See the CPP_03_MOVE_EMULATION macro.
+ scoped_ptr(scoped_ptr&);
+ void operator=(scoped_ptr&);
};
// Free functions
@@ -158,7 +219,7 @@ bool operator!=(C* p1, const scoped_ptr<C>& p2) {
// As with scoped_ptr<C>, a scoped_array<C> either points to an object
// or is NULL. A scoped_array<C> owns the object that it points to.
// scoped_array<T> is thread-compatible, and once you index into it,
-// the returned objects have only the threadsafety guarantees of T.
+// the returned objects have only the thread safety guarantees of T.
//
// Size: sizeof(scoped_array<C>) == sizeof(C*)
template <class C>
@@ -168,7 +229,7 @@ class scoped_array {
// The element type
typedef C element_type;
- // Constructor. Defaults to intializing with NULL.
+ // Constructor. Defaults to initializing with NULL.
// There is no way to create an uninitialized scoped_array.
// The input parameter must be allocated with new [].
explicit scoped_array(C* p = NULL) : array_(p) { }
@@ -229,6 +290,8 @@ class scoped_array {
return retVal;
}
+ CPP_03_MOVE_EMULATION(scoped_array, array_);
+
private:
C* array_;
@@ -236,9 +299,10 @@ class scoped_array {
template <class C2> bool operator==(scoped_array<C2> const& p2) const;
template <class C2> bool operator!=(scoped_array<C2> const& p2) const;
- // Disallow evil constructors
- scoped_array(const scoped_array&);
- void operator=(const scoped_array&);
+ // Disallow evil constructors. Note that MUST NOT take a const& because we
+ // are implementing move semantics. See the CPP_03_MOVE_EMULATION macro.
+ scoped_array(scoped_array&);
+ void operator=(scoped_array&);
};
// Free functions
@@ -347,6 +411,8 @@ class scoped_ptr_malloc {
return tmp;
}
+ CPP_03_MOVE_EMULATION(scoped_ptr_malloc, ptr_);
+
private:
C* ptr_;
@@ -356,11 +422,14 @@ class scoped_ptr_malloc {
template <class C2, class GP>
bool operator!=(scoped_ptr_malloc<C2, GP> const& p) const;
- // Disallow evil constructors
- scoped_ptr_malloc(const scoped_ptr_malloc&);
- void operator=(const scoped_ptr_malloc&);
+ // Disallow evil constructors. Note that MUST NOT take a const& because we
+ // are implementing move semantics. See the CPP_03_MOVE_EMULATION macro.
+ scoped_ptr_malloc(scoped_ptr_malloc&);
+ void operator=(scoped_ptr_malloc&);
};
+#undef CPP_03_MOVE_EMULATION
+
template<class C, class FP> inline
void swap(scoped_ptr_malloc<C, FP>& a, scoped_ptr_malloc<C, FP>& b) {
a.swap(b);
diff --git a/base/memory/scoped_ptr_unittest.cc b/base/memory/scoped_ptr_unittest.cc
index 7519051..9a37cbf 100644
--- a/base/memory/scoped_ptr_unittest.cc
+++ b/base/memory/scoped_ptr_unittest.cc
@@ -23,6 +23,19 @@ class ConDecLogger {
DISALLOW_COPY_AND_ASSIGN(ConDecLogger);
};
+scoped_ptr<ConDecLogger> PassThru(scoped_ptr<ConDecLogger> logger) {
+ return logger.Pass();
+}
+
+void GrabAndDrop(scoped_ptr<ConDecLogger> logger) {
+}
+
+// Do not delete this function! It's existence is to test that you can
+// return a temporarily constructed version of the scoper.
+scoped_ptr<ConDecLogger> TestReturnOfType(int* constructed) {
+ return scoped_ptr<ConDecLogger>(new ConDecLogger(constructed));
+}
+
} // namespace
TEST(ScopedPtrTest, ScopedPtr) {
@@ -166,4 +179,83 @@ TEST(ScopedPtrTest, ScopedArray) {
EXPECT_EQ(0, constructed);
}
+TEST(ScopedPtrTest, PassBehavior) {
+ int constructed = 0;
+ {
+ ConDecLogger* logger = new ConDecLogger(&constructed);
+ scoped_ptr<ConDecLogger> scoper(logger);
+ EXPECT_EQ(1, constructed);
+
+ // Test Pass() with constructor;
+ scoped_ptr<ConDecLogger> scoper2(scoper.Pass());
+ EXPECT_EQ(1, constructed);
+
+ // Test Pass() with assignment;
+ scoped_ptr<ConDecLogger> scoper3;
+ scoper3 = scoper2.Pass();
+ EXPECT_EQ(1, constructed);
+ EXPECT_FALSE(scoper.get());
+ EXPECT_FALSE(scoper2.get());
+ EXPECT_TRUE(scoper3.get());
+ }
+
+ // Test uncaught Pass() does not leak.
+ {
+ ConDecLogger* logger = new ConDecLogger(&constructed);
+ scoped_ptr<ConDecLogger> scoper(logger);
+ EXPECT_EQ(1, constructed);
+
+ // Should auto-destruct logger by end of scope.
+ scoper.Pass();
+ EXPECT_FALSE(scoper.get());
+ }
+ EXPECT_EQ(0, constructed);
+
+ // Test that passing to function which does nothing does not leak.
+ {
+ ConDecLogger* logger = new ConDecLogger(&constructed);
+ scoped_ptr<ConDecLogger> scoper(logger);
+ EXPECT_EQ(1, constructed);
+
+ // Should auto-destruct logger by end of scope.
+ GrabAndDrop(scoper.Pass());
+ EXPECT_FALSE(scoper.get());
+ }
+ EXPECT_EQ(0, constructed);
+}
+
+TEST(ScopedPtrTest, ReturnTypeBehavior) {
+ int constructed = 0;
+
+ // Test that we can return a scoped_ptr.
+ {
+ ConDecLogger* logger = new ConDecLogger(&constructed);
+ scoped_ptr<ConDecLogger> scoper(logger);
+ EXPECT_EQ(1, constructed);
+
+ PassThru(scoper.Pass());
+ EXPECT_FALSE(scoper.get());
+ }
+ EXPECT_EQ(0, constructed);
+
+ // Test uncaught return type not leak.
+ {
+ ConDecLogger* logger = new ConDecLogger(&constructed);
+ scoped_ptr<ConDecLogger> scoper(logger);
+ EXPECT_EQ(1, constructed);
+
+ // Should auto-destruct logger by end of scope.
+ PassThru(scoper.Pass());
+ EXPECT_FALSE(scoper.get());
+ }
+ EXPECT_EQ(0, constructed);
+
+ // Call TestReturnOfType() so the compiler doesn't warn for an unused
+ // function.
+ {
+ TestReturnOfType(&constructed);
+ }
+ EXPECT_EQ(0, constructed);
+}
+
// TODO scoped_ptr_malloc
diff --git a/chrome/browser/chromeos/stub_cros_settings_provider_unittest.cc b/chrome/browser/chromeos/stub_cros_settings_provider_unittest.cc
index f561bb5..fe1d25b 100644
--- a/chrome/browser/chromeos/stub_cros_settings_provider_unittest.cc
+++ b/chrome/browser/chromeos/stub_cros_settings_provider_unittest.cc
@@ -7,7 +7,7 @@
#include <string>
#include "base/bind.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "chrome/browser/chromeos/cros_settings_names.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/common/extensions/extension_manifests_unittest.cc b/chrome/common/extensions/extension_manifests_unittest.cc
index 6fd314e..5f63aca 100644
--- a/chrome/common/extensions/extension_manifests_unittest.cc
+++ b/chrome/common/extensions/extension_manifests_unittest.cc
@@ -74,6 +74,19 @@ class ExtensionManifestTest : public testing::Test {
Manifest(DictionaryValue* manifest, const char* name)
: name_(name), manifest_(manifest) {
}
+ Manifest(const Manifest& m) {
+ // C++98 requires the copy constructor for a type to be visiable if you
+ // take a const-ref of a temporary for that type. Since Manifest
+ // contains a scoped_ptr, its implicit copy constructor is declared
+ // Manifest(Manifest&) according to spec 12.8.5. This breaks the first
+ // requirement and thus you cannot use it with LoadAndExpectError() or
+ // LoadAndExpectSuccess() easily.
+ //
+ // To get around this spec pedantry, we declare the copy constructor
+ // explicitly. It will never get invoked.
+ NOTREACHED();
+ }
+
const std::string& name() const { return name_; }
diff --git a/content/browser/renderer_host/render_widget_host_view_win.cc b/content/browser/renderer_host/render_widget_host_view_win.cc
index 7584256..62571a1 100644
--- a/content/browser/renderer_host/render_widget_host_view_win.cc
+++ b/content/browser/renderer_host/render_widget_host_view_win.cc
@@ -181,10 +181,7 @@ LRESULT CALLBACK PluginWrapperWindowProc(HWND window, unsigned int message,
return ::DefWindowProc(window, message, wparam, lparam);
}
-void SendToGpuProcessHost(int gpu_host_id, IPC::Message* m) {
- // TODO(ajwong): Switch back to Passed() when it becomes available again.
- scoped_ptr<IPC::Message> message(m);
-
+void SendToGpuProcessHost(int gpu_host_id, scoped_ptr<IPC::Message> message) {
GpuProcessHost* gpu_process_host = GpuProcessHost::FromID(gpu_host_id);
if (!gpu_process_host)
return;
@@ -2048,10 +2045,12 @@ void RenderWidgetHostViewWin::AcceleratedSurfaceBuffersSwapped(
accelerated_surface_->Initialize();
}
+ scoped_ptr<IPC::Message> message(
+ new AcceleratedSurfaceMsg_BuffersSwappedACK(params.route_id));
base::Closure acknowledge_task = base::Bind(
SendToGpuProcessHost,
gpu_host_id,
- new AcceleratedSurfaceMsg_BuffersSwappedACK(params.route_id));
+ base::Passed(&message));
accelerated_surface_->AsyncPresentAndAcknowledge(
params.size,