| Index: base/bind_helpers.h
|
| diff --git a/base/bind_helpers.h b/base/bind_helpers.h
|
| index 07f11f98d2cde4e730b0c811e6b176dac1fa9ca7..d7ddb2c49bab76629c952d132b30d9b6263b8a4c 100644
|
| --- a/base/bind_helpers.h
|
| +++ b/base/bind_helpers.h
|
| @@ -6,10 +6,13 @@
|
| // 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::ConstRef(), and
|
| -// base::IgnoreReturn().
|
| +// The public functions are base::Unretained(), base::Owned(),
|
| +// base::ConstRef(), and base::IgnoreReturn().
|
| //
|
| -// Unretained() allows Bind() to bind a non-refcounted class.
|
| +// 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.
|
| // 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
|
| @@ -26,7 +29,7 @@
|
| //
|
| // // In some function somewhere.
|
| // Foo foo;
|
| -// Callback<void(void)> foo_callback =
|
| +// Closure foo_callback =
|
| // Bind(&Foo::func, Unretained(&foo));
|
| // foo_callback.Run(); // Prints "Foo:f".
|
| //
|
| @@ -34,12 +37,32 @@
|
| // to compile because Foo does not support the AddRef() and Release() methods.
|
| //
|
| //
|
| +// EXAMPLE OF Owned():
|
| +//
|
| +// void foo(int* arg) { cout << *arg << endl }
|
| +//
|
| +// int* pn = new int(1);
|
| +// Closure foo_callback = Bind(&foo, Owned(pn));
|
| +//
|
| +// foo_callback.Run(); // Prints "1"
|
| +// foo_callback.Run(); // Prints "1"
|
| +// *n = 2;
|
| +// foo_callback.Run(); // Prints "2"
|
| +//
|
| +// foo_callback.Reset(); // |pn| is deleted. Also will happen when
|
| +// // |foo_callback| goes out of scope.
|
| +//
|
| +// Without Owned(), someone would have to know to delete |pn| when the last
|
| +// reference to the Callback is deleted.
|
| +//
|
| +//
|
| // EXAMPLE OF ConstRef():
|
| +//
|
| // void foo(int arg) { cout << arg << endl }
|
| //
|
| // int n = 1;
|
| -// Callback<void(void)> no_ref = Bind(&foo, n);
|
| -// Callback<void(void)> has_ref = Bind(&foo, ConstRef(n));
|
| +// Closure no_ref = Bind(&foo, n);
|
| +// Closure has_ref = Bind(&foo, ConstRef(n));
|
| //
|
| // no_ref.Run(); // Prints "1"
|
| // has_ref.Run(); // Prints "1"
|
| @@ -53,6 +76,7 @@
|
| //
|
| //
|
| // EXAMPLE OF IgnoreReturn():
|
| +//
|
| // int DoSomething(int arg) { cout << arg << endl; }
|
| // Callback<int(void)> cb = Bind(&DoSomething, 1);
|
| // Closure c = IgnoreReturn(cb); // Prints "1"
|
| @@ -199,21 +223,43 @@ struct UnsafeBindtoRefCountedArg<T*>
|
| template <typename T>
|
| class UnretainedWrapper {
|
| public:
|
| - explicit UnretainedWrapper(T* o) : obj_(o) {}
|
| - T* get() { return obj_; }
|
| + explicit UnretainedWrapper(T* o) : ptr_(o) {}
|
| + T* get() const { return ptr_; }
|
| private:
|
| - T* obj_;
|
| + T* ptr_;
|
| };
|
|
|
| template <typename T>
|
| class ConstRefWrapper {
|
| public:
|
| explicit ConstRefWrapper(const T& o) : ptr_(&o) {}
|
| - const T& get() { return *ptr_; }
|
| + const T& get() const { return *ptr_; }
|
| private:
|
| const T* ptr_;
|
| };
|
|
|
| +// An alternate implementation is to avoid the destructive copy, and instead
|
| +// specialize ParamTraits<> for OwnedWrapper<> to change the StorageType to
|
| +// a class that is essentially a scoped_ptr<>.
|
| +//
|
| +// The current implementation has the benefit though of leaving ParamTraits<>
|
| +// fully in callback_internal.h as well as avoiding type conversions during
|
| +// storage.
|
| +template <typename T>
|
| +class OwnedWrapper {
|
| + public:
|
| + explicit OwnedWrapper(T* o) : ptr_(o) {}
|
| + ~OwnedWrapper() { delete ptr_; }
|
| + T* get() const { return ptr_; }
|
| + OwnedWrapper(const OwnedWrapper& other) {
|
| + ptr_ = other.ptr_;
|
| + other.ptr_ = NULL;
|
| + }
|
| +
|
| + private:
|
| + mutable T* ptr_;
|
| +};
|
| +
|
|
|
| // Unwrap the stored parameters for the wrappers above.
|
| template <typename T>
|
| @@ -233,6 +279,11 @@ T* Unwrap(const scoped_refptr<T>& o) { return o.get(); }
|
| template <typename T>
|
| const WeakPtr<T>& Unwrap(const WeakPtr<T>& o) { return o; }
|
|
|
| +template <typename T>
|
| +T* Unwrap(const OwnedWrapper<T>& o) {
|
| + return o.get();
|
| +}
|
| +
|
| // Utility for handling different refcounting semantics in the Bind()
|
| // function.
|
| template <typename IsMethod, typename T>
|
| @@ -251,15 +302,21 @@ struct MaybeRefcount<base::false_type, T[n]> {
|
| };
|
|
|
| template <typename T>
|
| +struct MaybeRefcount<base::true_type, T*> {
|
| + static void AddRef(T* o) { o->AddRef(); }
|
| + static void Release(T* o) { o->Release(); }
|
| +};
|
| +
|
| +template <typename T>
|
| struct MaybeRefcount<base::true_type, UnretainedWrapper<T> > {
|
| static void AddRef(const UnretainedWrapper<T>&) {}
|
| static void Release(const UnretainedWrapper<T>&) {}
|
| };
|
|
|
| template <typename T>
|
| -struct MaybeRefcount<base::true_type, T*> {
|
| - static void AddRef(T* o) { o->AddRef(); }
|
| - static void Release(T* o) { o->Release(); }
|
| +struct MaybeRefcount<base::true_type, OwnedWrapper<T> > {
|
| + static void AddRef(const OwnedWrapper<T>&) {}
|
| + static void Release(const OwnedWrapper<T>&) {}
|
| };
|
|
|
| // No need to additionally AddRef() and Release() since we are storing a
|
| @@ -299,6 +356,11 @@ inline internal::ConstRefWrapper<T> ConstRef(const T& o) {
|
| return internal::ConstRefWrapper<T>(o);
|
| }
|
|
|
| +template <typename T>
|
| +inline internal::OwnedWrapper<T> Owned(T* o) {
|
| + return internal::OwnedWrapper<T>(o);
|
| +}
|
| +
|
| template <typename R>
|
| Closure IgnoreReturn(Callback<R(void)> callback) {
|
| return Bind(&internal::VoidReturnAdapter<R>, callback);
|
|
|