Add base:: qualification to callback examples.
Code was difficult to copy-and-paste out of the callback examples
because typically one would need to add base:: to many types.
This explicitly adds "base::" to all examples.
Originally I was going to keep the references in the text unchanged and
only change the code blocks. But this ended up being confusing. As a
result, all code-formatted references have been qualified. In some cases
this is a bit verbose and repetitive, but I think its better to be
explicit and consistent.
Expands a bit on weak pointer usage which I have found myself repeatedly
looking up.
Change-Id: I961b25ea6db6151180cf0d687e576be72e327427
Reviewed-on: https://chromium-review.googlesource.com/688505
Reviewed-by: Albert J. Wong <[email protected]>
Commit-Queue: Brett Wilson <[email protected]>
Cr-Commit-Position: refs/heads/master@{#504781}
diff --git a/docs/callback.md b/docs/callback.md
index 3c5fec5d..3a30ff4 100644
--- a/docs/callback.md
+++ b/docs/callback.md
@@ -2,9 +2,9 @@
## Introduction
-The templated `Callback<>` class is a generalized function object. Together with
-the `Bind()` function in base/bind.h, they provide a type-safe method for
-performing partial application of functions.
+The templated `base::Callback<>` class is a generalized function object.
+Together with the `base::Bind()` function in base/bind.h, they provide a
+type-safe method for performing partial application of functions.
Partial application (or "currying") is the process of binding a subset of a
function's arguments to produce another function that takes fewer arguments.
@@ -12,73 +12,74 @@
closures are used in other languages. For example, it is used in Chromium code
to schedule tasks on different MessageLoops.
-A callback with no unbound input parameters (`Callback<void()>`) is called a
-`Closure`. Note that this is NOT the same as what other languages refer to as a
-closure -- it does not retain a reference to its enclosing environment.
+A callback with no unbound input parameters (`base::Callback<void()>`) is
+called a `base::Closure`. Note that this is NOT the same as what other
+languages refer to as a closure -- it does not retain a reference to its
+enclosing environment.
### OnceCallback<> And RepeatingCallback<>
-`OnceCallback<>` and `RepeatingCallback<>` are next gen callback classes, which
-are under development.
+`base::OnceCallback<>` and `base::RepeatingCallback<>` are next gen callback
+classes, which are under development.
-`OnceCallback<>` is created by `BindOnce()`. This is a callback variant that is
-a move-only type and can be run only once. This moves out bound parameters from
-its internal storage to the bound function by default, so it's easier to use
-with movable types. This should be the preferred callback type: since the
-lifetime of the callback is clear, it's simpler to reason about when a callback
-that is passed between threads is destroyed.
+`base::OnceCallback<>` is created by `base::BindOnce()`. This is a callback
+variant that is a move-only type and can be run only once. This moves out bound
+parameters from its internal storage to the bound function by default, so it's
+easier to use with movable types. This should be the preferred callback type:
+since the lifetime of the callback is clear, it's simpler to reason about when
+a callback that is passed between threads is destroyed.
-`RepeatingCallback<>` is created by `BindRepeating()`. This is a callback
-variant that is copyable that can be run multiple times. It uses internal
-ref-counting to make copies cheap. However, since ownership is shared, it is
-harder to reason about when the callback and the bound state are destroyed,
-especially when the callback is passed between threads.
+`base::RepeatingCallback<>` is created by `base::BindRepeating()`. This is a
+callback variant that is copyable that can be run multiple times. It uses
+internal ref-counting to make copies cheap. However, since ownership is shared,
+it is harder to reason about when the callback and the bound state are
+destroyed, especially when the callback is passed between threads.
-The legacy `Callback<>` is currently aliased to `RepeatingCallback<>`. In new
-code, prefer `OnceCallback<>` where possible, and use `RepeatingCallback<>`
-otherwise. Once the migration is complete, the type alias will be removed and
-`OnceCallback<>` will be renamed to `Callback<>` to emphasize that it should be
-preferred.
+The legacy `base::Callback<>` is currently aliased to
+`base::RepeatingCallback<>`. In new code, prefer `base::OnceCallback<>` where
+possible, and use `base::RepeatingCallback<>` otherwise. Once the migration is
+complete, the type alias will be removed and `base::OnceCallback<>` will be renamed
+to `base::Callback<>` to emphasize that it should be preferred.
-`RepeatingCallback<>` is convertible to `OnceCallback<>` by the implicit
-conversion.
+`base::RepeatingCallback<>` is convertible to `base::OnceCallback<>` by the
+implicit conversion.
### Memory Management And Passing
-Pass `Callback` objects by value if ownership is transferred; otherwise, pass it
-by const-reference.
+Pass `base::Callback` objects by value if ownership is transferred; otherwise,
+pass it by const-reference.
```cpp
// |Foo| just refers to |cb| but doesn't store it nor consume it.
-bool Foo(const OnceCallback<void(int)>& cb) {
+bool Foo(const base::OnceCallback<void(int)>& cb) {
return cb.is_null();
}
// |Bar| takes the ownership of |cb| and stores |cb| into |g_cb|.
-OnceCallback<void(int)> g_cb;
-void Bar(OnceCallback<void(int)> cb) {
+base::OnceCallback<void(int)> g_cb;
+void Bar(base::OnceCallback<void(int)> cb) {
g_cb = std::move(cb);
}
// |Baz| takes the ownership of |cb| and consumes |cb| by Run().
-void Baz(OnceCallback<void(int)> cb) {
+void Baz(base::OnceCallback<void(int)> cb) {
std::move(cb).Run(42);
}
// |Qux| takes the ownership of |cb| and transfers ownership to PostTask(),
// which also takes the ownership of |cb|.
-void Qux(OnceCallback<void(int)> cb) {
+void Qux(base::OnceCallback<void(int)> cb) {
PostTask(FROM_HERE,
base::BindOnce(std::move(cb), 42));
}
```
-When you pass a `Callback` object to a function parameter, use `std::move()` if
-you don't need to keep a reference to it, otherwise, pass the object directly.
-You may see a compile error when the function requires the exclusive ownership,
-and you didn't pass the callback by move. Note that the moved-from `Callback`
-becomes null, as if its `Reset()` method had been called, and its `is_null()`
-method will return true.
+When you pass a `base::Callback` object to a function parameter, use
+`std::move()` if you don't need to keep a reference to it, otherwise, pass the
+object directly. You may see a compile error when the function requires the
+exclusive ownership, and you didn't pass the callback by move. Note that the
+moved-from `base::Callback` becomes null, as if its `Reset()` method had been
+called, and its `is_null()` method will return true.
## Quick reference for basic stuff
@@ -86,23 +87,23 @@
```cpp
int Return5() { return 5; }
-OnceCallback<int()> func_cb = BindOnce(&Return5);
+base::OnceCallback<int()> func_cb = base::BindOnce(&Return5);
LOG(INFO) << std::move(func_cb).Run(); // Prints 5.
```
```cpp
int Return5() { return 5; }
-RepeatingCallback<int()> func_cb = BindRepeating(&Return5);
+base::RepeatingCallback<int()> func_cb = base::BindRepeating(&Return5);
LOG(INFO) << func_cb.Run(); // Prints 5.
```
### Binding A Captureless Lambda
```cpp
-Callback<int()> lambda_cb = Bind([] { return 4; });
+base::Callback<int()> lambda_cb = base::Bind([] { return 4; });
LOG(INFO) << lambda_cb.Run(); // Print 4.
-OnceCallback<int()> lambda_cb2 = BindOnce([] { return 3; });
+base::OnceCallback<int()> lambda_cb2 = base::BindOnce([] { return 3; });
LOG(INFO) << std::move(lambda_cb2).Run(); // Print 3.
```
@@ -112,12 +113,12 @@
object on which to call it.
```cpp
-class Ref : public RefCountedThreadSafe<Ref> {
+class Ref : public base::RefCountedThreadSafe<Ref> {
public:
int Foo() { return 3; }
};
scoped_refptr<Ref> ref = new Ref();
-Callback<void()> ref_cb = Bind(&Ref::Foo, ref);
+base::Callback<void()> ref_cb = base::Bind(&Ref::Foo, ref);
LOG(INFO) << ref_cb.Run(); // Prints out 3.
```
@@ -129,24 +130,24 @@
### Running A Callback
Callbacks can be run with their `Run` method, which has the same signature as
-the template argument to the callback. Note that `OnceCallback::Run` consumes
-the callback object and can only be invoked on a callback rvalue.
+the template argument to the callback. Note that `base::OnceCallback::Run`
+consumes the callback object and can only be invoked on a callback rvalue.
```cpp
-void DoSomething(const Callback<void(int, std::string)>& callback) {
+void DoSomething(const base::Callback<void(int, std::string)>& callback) {
callback.Run(5, "hello");
}
-void DoSomethingOther(OnceCallback<void(int, std::string)> callback) {
+void DoSomethingOther(base::OnceCallback<void(int, std::string)> callback) {
std::move(callback).Run(5, "hello");
}
```
RepeatingCallbacks can be run more than once (they don't get deleted or marked
-when run). However, this precludes using Passed (see below).
+when run). However, this precludes using `base::Passed` (see below).
```cpp
-void DoSomething(const RepeatingCallback<double(double)>& callback) {
+void DoSomething(const base::RepeatingCallback<double(double)>& callback) {
double myresult = callback.Run(3.14159);
myresult += callback.Run(2.71828);
}
@@ -166,38 +167,38 @@
### Passing Unbound Input Parameters
Unbound parameters are specified at the time a callback is `Run()`. They are
-specified in the `Callback` template type:
+specified in the `base::Callback` template type:
```cpp
void MyFunc(int i, const std::string& str) {}
-Callback<void(int, const std::string&)> cb = Bind(&MyFunc);
+base::Callback<void(int, const std::string&)> cb = base::Bind(&MyFunc);
cb.Run(23, "hello, world");
```
### Passing Bound Input Parameters
Bound parameters are specified when you create the callback as arguments to
-`Bind()`. They will be passed to the function and the `Run()`ner of the callback
-doesn't see those values or even know that the function it's calling.
+`base::Bind()`. They will be passed to the function and the `Run()`ner of the
+callback doesn't see those values or even know that the function it's calling.
```cpp
void MyFunc(int i, const std::string& str) {}
-Callback<void()> cb = Bind(&MyFunc, 23, "hello world");
+base::Callback<void()> cb = base::Bind(&MyFunc, 23, "hello world");
cb.Run();
```
-A callback with no unbound input parameters (`Callback<void()>`) is called a
-`Closure`. So we could have also written:
+A callback with no unbound input parameters (`base::Callback<void()>`) is
+called a `base::Closure`. So we could have also written:
```cpp
-Closure cb = Bind(&MyFunc, 23, "hello world");
+base::Closure cb = base::Bind(&MyFunc, 23, "hello world");
```
When calling member functions, bound parameters just go after the object
pointer.
```cpp
-Closure cb = Bind(&MyClass::MyFunc, this, 23, "hello world");
+base::Closure cb = base::Bind(&MyClass::MyFunc, this, 23, "hello world");
```
### Partial Binding Of Parameters
@@ -207,7 +208,7 @@
```cpp
void MyFunc(int i, const std::string& str) {}
-Callback<void(const std::string&)> cb = Bind(&MyFunc, 23);
+base::Callback<void(const std::string&)> cb = base::Bind(&MyFunc, 23);
cb.Run("hello world");
```
@@ -216,32 +217,32 @@
### Avoiding Copies with Callback Parameters
-A parameter of `Bind()` is moved into its internal storage if it is passed as a
+A parameter of `base::Bind()` is moved into its internal storage if it is passed as a
rvalue.
```cpp
std::vector<int> v = {1, 2, 3};
// |v| is moved into the internal storage without copy.
-Bind(&Foo, std::move(v));
+base::Bind(&Foo, std::move(v));
```
```cpp
std::vector<int> v = {1, 2, 3};
// The vector is moved into the internal storage without copy.
-Bind(&Foo, std::vector<int>({1, 2, 3}));
+base::Bind(&Foo, std::vector<int>({1, 2, 3}));
```
-A bound object is moved out to the target function if you use `Passed()` for
-the parameter. If you use `BindOnce()`, the bound object is moved out even
-without `Passed()`.
+A bound object is moved out to the target function if you use `base::Passed()`
+for the parameter. If you use `base::BindOnce()`, the bound object is moved out
+even without `base::Passed()`.
```cpp
void Foo(std::unique_ptr<int>) {}
std::unique_ptr<int> p(new int(42));
// |p| is moved into the internal storage of Bind(), and moved out to |Foo|.
-BindOnce(&Foo, std::move(p));
-BindRepeating(&Foo, Passed(&p));
+base::BindOnce(&Foo, std::move(p));
+base::BindRepeating(&Foo, base::Passed(&p));
```
## Quick reference for advanced binding
@@ -249,17 +250,21 @@
### Binding A Class Method With Weak Pointers
```cpp
-Bind(&MyClass::Foo, GetWeakPtr());
+base::Bind(&MyClass::Foo, GetWeakPtr());
```
The callback will not be run if the object has already been destroyed.
-**DANGER**: weak pointers are not threadsafe, so don't use this when passing between
-threads!
+**DANGER**: weak pointers are not threadsafe, so don't use this when passing
+between threads!
+
+To make a weak pointer, you would typically create a
+`base::WeakPtrFactory<Foo>` member at the bottom (to ensure it's destroyed
+last) of class `Foo`, then call `weak_factory_.GetWeakPtr()`.
### Binding A Class Method With Manual Lifetime Management
```cpp
-Bind(&MyClass::Foo, Unretained(this));
+base::Bind(&MyClass::Foo, base::Unretained(this));
```
This disables all lifetime management on the object. You're responsible for
@@ -270,7 +275,7 @@
```cpp
MyClass* myclass = new MyClass;
-Bind(&MyClass::Foo, Owned(myclass));
+base::Bind(&MyClass::Foo, base::Owned(myclass));
```
The object will be deleted when the callback is destroyed, even if it's not run
@@ -281,7 +286,7 @@
```cpp
std::unique_ptr<MyClass> myclass(new MyClass);
-Bind(&MyClass::Foo, std::move(myclass));
+base::Bind(&MyClass::Foo, std::move(myclass));
```
### Ignoring Return Values
@@ -291,22 +296,23 @@
```cpp
int DoSomething(int arg) { cout << arg << endl; }
-Callback<void(int)> cb =
- Bind(IgnoreResult(&DoSomething));
+base::Callback<void(int)> cb =
+ base::Bind(IgnoreResult(&DoSomething));
```
## Quick reference for binding parameters to Bind()
-Bound parameters are specified as arguments to `Bind()` and are passed to the
-function. A callback with no parameters or no unbound parameters is called a
-`Closure` (`Callback<void()>` and `Closure` are the same thing).
+Bound parameters are specified as arguments to `base::Bind()` and are passed to
+the function. A callback with no parameters or no unbound parameters is called
+a `base::Closure` (`base::Callback<void()>` and `base::Closure` are the same
+thing).
### Passing Parameters Owned By The Callback
```cpp
void Foo(int* arg) { cout << *arg << endl; }
int* pn = new int(1);
-Closure foo_callback = Bind(&foo, Owned(pn));
+base::Closure foo_callback = base::Bind(&foo, base::Owned(pn));
```
The parameter will be deleted when the callback is destroyed, even if it's not
@@ -318,7 +324,8 @@
void TakesOwnership(std::unique_ptr<Foo> arg) {}
std::unique_ptr<Foo> f(new Foo);
// f becomes null during the following call.
-RepeatingClosure cb = BindRepeating(&TakesOwnership, Passed(&f));
+base::RepeatingClosure cb =
+ base::BindRepeating(&TakesOwnership, base::Passed(&f));
```
Ownership of the parameter will be with the callback until the callback is run,
@@ -331,7 +338,7 @@
```cpp
void TakesOneRef(scoped_refptr<Foo> arg) {}
scoped_refptr<Foo> f(new Foo);
-Closure cb = Bind(&TakesOneRef, f);
+base::Closure cb = base::Bind(&TakesOneRef, f);
```
This should "just work." The closure will take a reference as long as it is
@@ -340,21 +347,21 @@
```cpp
void DontTakeRef(Foo* arg) {}
scoped_refptr<Foo> f(new Foo);
-Closure cb = Bind(&DontTakeRef, RetainedRef(f));
+base::Closure cb = base::Bind(&DontTakeRef, base::RetainedRef(f));
```
-`RetainedRef` holds a reference to the object and passes a raw pointer to
+`base::RetainedRef` holds a reference to the object and passes a raw pointer to
the object when the Callback is run.
### Passing Parameters By Reference
-Const references are *copied* unless `ConstRef` is used. Example:
+Const references are *copied* unless `base::ConstRef` is used. Example:
```cpp
void foo(const int& arg) { printf("%d %p\n", arg, &arg); }
int n = 1;
-Closure has_copy = Bind(&foo, n);
-Closure has_ref = Bind(&foo, ConstRef(n));
+base::Closure has_copy = base::Bind(&foo, n);
+base::Closure has_ref = base::Bind(&foo, base::ConstRef(n));
n = 2;
foo(n); // Prints "2 0xaaaaaaaaaaaa"
has_copy.Run(); // Prints "1 0xbbbbbbbbbbbb"
@@ -362,7 +369,7 @@
```
Normally parameters are copied in the closure.
-**DANGER**: `ConstRef` stores a const reference instead, referencing the
+**DANGER**: `base::ConstRef` stores a const reference instead, referencing the
original parameter. This means that you must ensure the object outlives the
callback!
@@ -370,15 +377,18 @@
### Where Is This Design From:
-The design `Callback` and Bind is heavily influenced by C++'s `tr1::function` /
-`tr1::bind`, and by the "Google Callback" system used inside Google.
+The design of `base::Callback` and `base::Bind` is heavily influenced by C++'s
+`tr1::function` / `tr1::bind`, and by the "Google Callback" system used inside
+Google.
### Customizing the behavior
-There are several injection points that controls `Bind` behavior from outside of
-its implementation.
+There are several injection points that controls binding behavior from outside
+of its implementation.
```cpp
+namespace base {
+
template <typename Receiver>
struct IsWeakReceiver {
static constexpr bool value = false;
@@ -391,40 +401,43 @@
return std::forward<T>(obj);
}
};
+
+} // namespace base
```
-If `IsWeakReceiver<Receiver>::value` is true on a receiver of a method, `Bind`
-checks if the receiver is evaluated to true and cancels the invocation if it's
-evaluated to false. You can specialize `IsWeakReceiver` to make an external
-smart pointer as a weak pointer.
+If `base::IsWeakReceiver<Receiver>::value` is true on a receiver of a method,
+`base::Bind` checks if the receiver is evaluated to true and cancels the invocation
+if it's evaluated to false. You can specialize `base::IsWeakReceiver` to make
+an external smart pointer as a weak pointer.
-`UnwrapTraits<BoundObject>::Unwrap()` is called for each bound arguments right
-before `Callback` calls the target function. You can specialize this to define
-an argument wrapper such as `Unretained`, `ConstRef`, `Owned`, `RetainedRef` and
-`Passed`.
+`base::UnwrapTraits<BoundObject>::Unwrap()` is called for each bound arguments
+right before `base::Callback` calls the target function. You can specialize
+this to define an argument wrapper such as `base::Unretained`,
+`base::ConstRef`, `base::Owned`, `base::RetainedRef` and `base::Passed`.
### How The Implementation Works:
There are three main components to the system:
- 1) The `Callback<>` classes.
- 2) The `Bind()` functions.
- 3) The arguments wrappers (e.g., `Unretained()` and `ConstRef()`).
+ 1) The `base::Callback<>` classes.
+ 2) The `base::Bind()` functions.
+ 3) The arguments wrappers (e.g., `base::Unretained()` and `base::ConstRef()`).
-The Callback classes represent a generic function pointer. Internally, it stores
-a refcounted piece of state that represents the target function and all its
-bound parameters. The `Callback` constructor takes a `BindStateBase*`, which is
-upcasted from a `BindState<>`. In the context of the constructor, the static
-type of this `BindState<>` pointer uniquely identifies the function it is
-representing, all its bound parameters, and a `Run()` method that is capable of
-invoking the target.
+The Callback classes represent a generic function pointer. Internally, it
+stores a refcounted piece of state that represents the target function and all
+its bound parameters. The `base::Callback` constructor takes a
+`base::BindStateBase*`, which is upcasted from a `base::BindState<>`. In the
+context of the constructor, the static type of this `base::BindState<>` pointer
+uniquely identifies the function it is representing, all its bound parameters,
+and a `Run()` method that is capable of invoking the target.
-`Bind()` creates the `BindState<>` that has the full static type, and erases the
-target function type as well as the types of the bound parameters. It does this
-by storing a pointer to the specific `Run()` function, and upcasting the state
-of `BindState<>*` to a `BindStateBase*`. This is safe as long as this
-`BindStateBase` pointer is only used with the stored `Run()` pointer.
+`base::Bind()` creates the `base::BindState<>` that has the full static type,
+and erases the target function type as well as the types of the bound
+parameters. It does this by storing a pointer to the specific `Run()` function,
+and upcasting the state of `base::BindState<>*` to a `base::BindStateBase*`.
+This is safe as long as this `BindStateBase` pointer is only used with the
+stored `Run()` pointer.
-To `BindState<>` objects are created inside the `Bind()` functions.
+To `base::BindState<>` objects are created inside the `base::Bind()` functions.
These functions, along with a set of internal templates, are responsible for
- Unwrapping the function signature into return type, and parameters
@@ -435,23 +448,25 @@
parameters and that knows the correct refcounting semantics for the
target object if we are binding a method.
-The `Bind` functions do the above using type-inference and variadic templates.
+The `base::Bind` functions do the above using type-inference and variadic
+templates.
-By default `Bind()` will store copies of all bound parameters, and attempt to
-refcount a target object if the function being bound is a class method. These
-copies are created even if the function takes parameters as const
+By default `base::Bind()` will store copies of all bound parameters, and
+attempt to refcount a target object if the function being bound is a class
+method. These copies are created even if the function takes parameters as const
references. (Binding to non-const references is forbidden, see bind.h.)
To change this behavior, we introduce a set of argument wrappers (e.g.,
-`Unretained()`, and `ConstRef()`). These are simple container templates that
-are passed by value, and wrap a pointer to argument. See the file-level comment
-in base/bind_helpers.h for more info.
+`base::Unretained()`, and `base::ConstRef()`). These are simple container
+templates that are passed by value, and wrap a pointer to argument. See the
+file-level comment in base/bind_helpers.h for more info.
These types are passed to the `Unwrap()` functions to modify the behavior of
-`Bind()`. The `Unwrap()` functions change behavior by doing partial
+`base::Bind()`. The `Unwrap()` functions change behavior by doing partial
specialization based on whether or not a parameter is a wrapper type.
-`ConstRef()` is similar to `tr1::cref`. `Unretained()` is specific to Chromium.
+`base::ConstRef()` is similar to `tr1::cref`. `base::Unretained()` is specific
+to Chromium.
### Missing Functionality
- Binding arrays to functions that take a non-const pointer.
@@ -459,9 +474,9 @@
```cpp
void Foo(const char* ptr);
void Bar(char* ptr);
-Bind(&Foo, "test");
-Bind(&Bar, "test"); // This fails because ptr is not const.
+base::Bind(&Foo, "test");
+base::Bind(&Bar, "test"); // This fails because ptr is not const.
```
-If you are thinking of forward declaring `Callback` in your own header file,
-please include "base/callback_forward.h" instead.
+If you are thinking of forward declaring `base::Callback` in your own header
+file, please include "base/callback_forward.h" instead.