tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

bind.h (18229B)


      1 // Copyright 2011 The Chromium Authors
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef BASE_FUNCTIONAL_BIND_H_
      6 #define BASE_FUNCTIONAL_BIND_H_
      7 
      8 #include <functional>
      9 #include <memory>
     10 #include <type_traits>
     11 #include <utility>
     12 
     13 #include "base/compiler_specific.h"
     14 #include "base/functional/bind_internal.h"
     15 #include "base/memory/raw_ptr.h"
     16 #include "build/build_config.h"
     17 
     18 // -----------------------------------------------------------------------------
     19 // Usage documentation
     20 // -----------------------------------------------------------------------------
     21 //
     22 // Overview:
     23 // base::BindOnce() and base::BindRepeating() are helpers for creating
     24 // base::OnceCallback and base::RepeatingCallback objects respectively.
     25 //
     26 // For a runnable object of n-arity, the base::Bind*() family allows partial
     27 // application of the first m arguments. The remaining n - m arguments must be
     28 // passed when invoking the callback with Run().
     29 //
     30 //   // The first argument is bound at callback creation; the remaining
     31 //   // two must be passed when calling Run() on the callback object.
     32 //   base::OnceCallback<long(int, long)> cb = base::BindOnce(
     33 //       [](short x, int y, long z) { return x * y * z; }, 42);
     34 //
     35 // When binding to a method, the receiver object must also be specified at
     36 // callback creation time. When Run() is invoked, the method will be invoked on
     37 // the specified receiver object.
     38 //
     39 //   class C : public base::RefCounted<C> { void F(); };
     40 //   auto instance = base::MakeRefCounted<C>();
     41 //   auto cb = base::BindOnce(&C::F, instance);
     42 //   std::move(cb).Run();  // Identical to instance->F()
     43 //
     44 // See //docs/callback.md for the full documentation.
     45 //
     46 // -----------------------------------------------------------------------------
     47 // Implementation notes
     48 // -----------------------------------------------------------------------------
     49 //
     50 // If you're reading the implementation, before proceeding further, you should
     51 // read the top comment of base/functional/bind_internal.h for a definition of
     52 // common terms and concepts.
     53 
     54 namespace base {
     55 
     56 // Bind as OnceCallback.
     57 template <typename Functor, typename... Args>
     58 inline OnceCallback<internal::MakeUnboundRunType<Functor, Args...>> BindOnce(
     59    Functor&& functor,
     60    Args&&... args) {
     61  static_assert(!internal::IsOnceCallback<std::decay_t<Functor>>() ||
     62                    (std::is_rvalue_reference<Functor&&>() &&
     63                     !std::is_const<std::remove_reference_t<Functor>>()),
     64                "BindOnce requires non-const rvalue for OnceCallback binding."
     65                " I.e.: base::BindOnce(std::move(callback)).");
     66  static_assert(
     67      std::conjunction_v<
     68          internal::AssertBindArgIsNotBasePassed<std::decay_t<Args>>...>,
     69      "Use std::move() instead of base::Passed() with base::BindOnce()");
     70 
     71  return internal::BindImpl<OnceCallback>(std::forward<Functor>(functor),
     72                                          std::forward<Args>(args)...);
     73 }
     74 
     75 // Bind as RepeatingCallback.
     76 template <typename Functor, typename... Args>
     77 inline RepeatingCallback<internal::MakeUnboundRunType<Functor, Args...>>
     78 BindRepeating(Functor&& functor, Args&&... args) {
     79  static_assert(
     80      !internal::IsOnceCallback<std::decay_t<Functor>>(),
     81      "BindRepeating cannot bind OnceCallback. Use BindOnce with std::move().");
     82 
     83  return internal::BindImpl<RepeatingCallback>(std::forward<Functor>(functor),
     84                                               std::forward<Args>(args)...);
     85 }
     86 
     87 // Overloads to allow nicer compile errors when attempting to pass the address
     88 // an overloaded function to `BindOnce()` or `BindRepeating()`. Otherwise, clang
     89 // provides only the error message "no matching function [...] candidate
     90 // template ignored: couldn't infer template argument 'Functor'", with no
     91 // reference to the fact that `&` is being used on an overloaded function.
     92 //
     93 // These overloads to provide better error messages will never be selected
     94 // unless template type deduction fails because of how overload resolution
     95 // works; per [over.ics.rank/2.2]:
     96 //
     97 //   When comparing the basic forms of implicit conversion sequences (as defined
     98 //   in [over.best.ics])
     99 //   - a standard conversion sequence is a better conversion sequence than a
    100 //     user-defined conversion sequence or an ellipsis conversion sequence, and
    101 //   - a user-defined conversion sequence is a better conversion sequence than
    102 //     an ellipsis conversion sequence.
    103 //
    104 // So these overloads will only be selected as a last resort iff template type
    105 // deduction fails.
    106 //
    107 // These overloads also intentionally do not return `void`, as this prevents
    108 // clang from emitting spurious errors such as "variable has incomplete type
    109 // 'void'" when assigning the result of `BindOnce()`/`BindRepeating()` to a
    110 // variable with type `auto` or `decltype(auto)`.
    111 struct BindFailedCheckPreviousErrors {};
    112 BindFailedCheckPreviousErrors BindOnce(...);
    113 BindFailedCheckPreviousErrors BindRepeating(...);
    114 
    115 // Unretained(), UnsafeDangling() and UnsafeDanglingUntriaged() allow binding a
    116 // non-refcounted class, and to disable refcounting on arguments that are
    117 // refcounted. The main difference is whether or not the raw pointers will be
    118 // checked for dangling references (e.g. a pointer that points to an already
    119 // destroyed object) when the callback is run.
    120 //
    121 // It is _required_ to use one of Unretained(), UnsafeDangling() or
    122 // UnsafeDanglingUntriaged() for raw pointer receivers now. For other arguments,
    123 // it remains optional. If not specified, default behavior is Unretained().
    124 
    125 // Unretained() pointers will be checked for dangling pointers when the
    126 // callback is run, *if* the callback has not been cancelled.
    127 //
    128 // Example of Unretained() usage:
    129 //
    130 //   class Foo {
    131 //    public:
    132 //     void func() { cout << "Foo:f" << endl; }
    133 //   };
    134 //
    135 //   // In some function somewhere.
    136 //   Foo foo;
    137 //   OnceClosure foo_callback =
    138 //       BindOnce(&Foo::func, Unretained(&foo));
    139 //   std::move(foo_callback).Run();  // Prints "Foo:f".
    140 //
    141 // Without the Unretained() wrapper on |&foo|, the above call would fail
    142 // to compile because Foo does not support the AddRef() and Release() methods.
    143 //
    144 // Unretained() does not allow dangling pointers, e.g.:
    145 //   class MyClass {
    146 //    public:
    147 //     OnError(int error);
    148 //    private:
    149 //     scoped_refptr<base::TaskRunner> runner_;
    150 //     std::unique_ptr<AnotherClass> obj_;
    151 //   };
    152 //
    153 //   void MyClass::OnError(int error) {
    154 //     // the pointer (which is also the receiver here) to `AnotherClass`
    155 //     // might dangle depending on when the task is invoked.
    156 //     runner_->PostTask(FROM_HERE, base::BindOnce(&AnotherClass::OnError,
    157 //         base::Unretained(obj_.get()), error));
    158 //     // one of the way to solve this issue here would be:
    159 //     // runner_->PostTask(FROM_HERE,
    160 //     //                   base::BindOnce(&AnotherClass::OnError,
    161 //     //                   base::Owned(std::move(obj_)), error));
    162 //     delete this;
    163 //   }
    164 //
    165 // the above example is a BAD USAGE of Unretained(), which might result in a
    166 // use-after-free, as `AnotherClass::OnError` might be invoked with a dangling
    167 // pointer as receiver.
    168 template <typename T>
    169 inline auto Unretained(T* o) {
    170  return internal::UnretainedWrapper<T, unretained_traits::MayNotDangle>(o);
    171 }
    172 
    173 template <typename T, RawPtrTraits Traits>
    174 inline auto Unretained(const raw_ptr<T, Traits>& o) {
    175  return internal::UnretainedWrapper<T, unretained_traits::MayNotDangle,
    176                                     Traits>(o);
    177 }
    178 
    179 template <typename T, RawPtrTraits Traits>
    180 inline auto Unretained(raw_ptr<T, Traits>&& o) {
    181  return internal::UnretainedWrapper<T, unretained_traits::MayNotDangle,
    182                                     Traits>(std::move(o));
    183 }
    184 
    185 template <typename T, RawPtrTraits Traits>
    186 inline auto Unretained(const raw_ref<T, Traits>& o) {
    187  return internal::UnretainedRefWrapper<T, unretained_traits::MayNotDangle,
    188                                        Traits>(o);
    189 }
    190 
    191 template <typename T, RawPtrTraits Traits>
    192 inline auto Unretained(raw_ref<T, Traits>&& o) {
    193  return internal::UnretainedRefWrapper<T, unretained_traits::MayNotDangle,
    194                                        Traits>(std::move(o));
    195 }
    196 
    197 // Similar to `Unretained()`, but allows dangling pointers, e.g.:
    198 //
    199 //   class MyClass {
    200 //     public:
    201 //       DoSomething(HandlerClass* handler);
    202 //     private:
    203 //       void MyClass::DoSomethingInternal(HandlerClass::Id id,
    204 //                                         HandlerClass* handler);
    205 //
    206 //       std::unordered_map<HandlerClass::Id, HandlerClass*> handlers_;
    207 //       scoped_refptr<base::SequencedTaskRunner> runner_;
    208 //       base::Lock lock_;
    209 //   };
    210 //   void MyClass::DoSomething(HandlerClass* handler) {
    211 //      runner_->PostTask(FROM_HERE,
    212 //          base::BindOnce(&MyClass::DoSomethingInternal,
    213 //                         base::Unretained(this),
    214 //                         handler->id(),
    215 //                         base::Unretained(handler)));
    216 //   }
    217 //   void MyClass::DoSomethingInternal(HandlerClass::Id id,
    218 //                                     HandlerClass* handler) {
    219 //     base::AutoLock locker(lock_);
    220 //     if (handlers_.find(id) == std::end(handlers_)) return;
    221 //     // Now we can use `handler`.
    222 //   }
    223 //
    224 // As `DoSomethingInternal` is run on a sequence (and we can imagine
    225 // `handlers_` being modified on it as well), we protect the function from
    226 // using a dangling `handler` by making sure it is still contained in the
    227 // map.
    228 //
    229 // Strongly prefer `Unretained()`. This is useful in limited situations such as
    230 // the one above.
    231 //
    232 // When using `UnsafeDangling()`, the receiver must be of type MayBeDangling<>.
    233 template <typename T>
    234 inline auto UnsafeDangling(T* o) {
    235  return internal::UnretainedWrapper<T, unretained_traits::MayDangle>(o);
    236 }
    237 
    238 template <typename T, RawPtrTraits Traits>
    239 auto UnsafeDangling(const raw_ptr<T, Traits>& o) {
    240  return internal::UnretainedWrapper<T, unretained_traits::MayDangle, Traits>(
    241      o);
    242 }
    243 
    244 template <typename T, RawPtrTraits Traits>
    245 auto UnsafeDangling(raw_ptr<T, Traits>&& o) {
    246  return internal::UnretainedWrapper<T, unretained_traits::MayDangle, Traits>(
    247      std::move(o));
    248 }
    249 
    250 template <typename T, RawPtrTraits Traits>
    251 auto UnsafeDangling(const raw_ref<T, Traits>& o) {
    252  return internal::UnretainedRefWrapper<T, unretained_traits::MayDangle,
    253                                        Traits>(o);
    254 }
    255 
    256 template <typename T, RawPtrTraits Traits>
    257 auto UnsafeDangling(raw_ref<T, Traits>&& o) {
    258  return internal::UnretainedRefWrapper<T, unretained_traits::MayDangle,
    259                                        Traits>(std::move(o));
    260 }
    261 
    262 // Like `UnsafeDangling()`, but used to annotate places that still need to be
    263 // triaged and either migrated to `Unretained()` and safer ownership patterns
    264 // (preferred) or `UnsafeDangling()` if the correct pattern to use is the one
    265 // in the `UnsafeDangling()` example above for example.
    266 //
    267 // Unlike `UnsafeDangling()`, the receiver doesn't have to be MayBeDangling<>.
    268 template <typename T>
    269 inline auto UnsafeDanglingUntriaged(T* o) {
    270  return internal::UnretainedWrapper<T, unretained_traits::MayDangleUntriaged>(
    271      o);
    272 }
    273 
    274 template <typename T, RawPtrTraits Traits>
    275 auto UnsafeDanglingUntriaged(const raw_ptr<T, Traits>& o) {
    276  return internal::UnretainedWrapper<T, unretained_traits::MayDangleUntriaged,
    277                                     Traits>(o);
    278 }
    279 
    280 template <typename T, RawPtrTraits Traits>
    281 auto UnsafeDanglingUntriaged(raw_ptr<T, Traits>&& o) {
    282  return internal::UnretainedWrapper<T, unretained_traits::MayDangleUntriaged,
    283                                     Traits>(std::move(o));
    284 }
    285 
    286 template <typename T, RawPtrTraits Traits>
    287 auto UnsafeDanglingUntriaged(const raw_ref<T, Traits>& o) {
    288  return internal::UnretainedRefWrapper<
    289      T, unretained_traits::MayDangleUntriaged, Traits>(o);
    290 }
    291 
    292 template <typename T, RawPtrTraits Traits>
    293 auto UnsafeDanglingUntriaged(raw_ref<T, Traits>&& o) {
    294  return internal::UnretainedRefWrapper<
    295      T, unretained_traits::MayDangleUntriaged, Traits>(std::move(o));
    296 }
    297 
    298 // RetainedRef() accepts a ref counted object and retains a reference to it.
    299 // When the callback is called, the object is passed as a raw pointer.
    300 //
    301 // EXAMPLE OF RetainedRef():
    302 //
    303 //    void foo(RefCountedBytes* bytes) {}
    304 //
    305 //    scoped_refptr<RefCountedBytes> bytes = ...;
    306 //    OnceClosure callback = BindOnce(&foo, base::RetainedRef(bytes));
    307 //    std::move(callback).Run();
    308 //
    309 // Without RetainedRef, the scoped_refptr would try to implicitly convert to
    310 // a raw pointer and fail compilation:
    311 //
    312 //    OnceClosure callback = BindOnce(&foo, bytes); // ERROR!
    313 template <typename T>
    314 inline internal::RetainedRefWrapper<T> RetainedRef(T* o) {
    315  return internal::RetainedRefWrapper<T>(o);
    316 }
    317 template <typename T>
    318 inline internal::RetainedRefWrapper<T> RetainedRef(scoped_refptr<T> o) {
    319  return internal::RetainedRefWrapper<T>(std::move(o));
    320 }
    321 
    322 // Owned() transfers ownership of an object to the callback resulting from
    323 // bind; the object will be deleted when the callback is deleted.
    324 //
    325 // EXAMPLE OF Owned():
    326 //
    327 //   void foo(int* arg) { cout << *arg << endl }
    328 //
    329 //   int* pn = new int(1);
    330 //   RepeatingClosure foo_callback = BindRepeating(&foo, Owned(pn));
    331 //
    332 //   foo_callback.Run();  // Prints "1"
    333 //   foo_callback.Run();  // Prints "1"
    334 //   *pn = 2;
    335 //   foo_callback.Run();  // Prints "2"
    336 //
    337 //   foo_callback.Reset();  // |pn| is deleted.  Also will happen when
    338 //                          // |foo_callback| goes out of scope.
    339 //
    340 // Without Owned(), someone would have to know to delete |pn| when the last
    341 // reference to the callback is deleted.
    342 template <typename T>
    343 inline internal::OwnedWrapper<T> Owned(T* o) {
    344  return internal::OwnedWrapper<T>(o);
    345 }
    346 
    347 template <typename T, typename Deleter>
    348 inline internal::OwnedWrapper<T, Deleter> Owned(
    349    std::unique_ptr<T, Deleter>&& ptr) {
    350  return internal::OwnedWrapper<T, Deleter>(std::move(ptr));
    351 }
    352 
    353 // OwnedRef() stores an object in the callback resulting from
    354 // bind and passes a reference to the object to the bound function.
    355 //
    356 // EXAMPLE OF OwnedRef():
    357 //
    358 //   void foo(int& arg) { cout << ++arg << endl }
    359 //
    360 //   int counter = 0;
    361 //   RepeatingClosure foo_callback = BindRepeating(&foo, OwnedRef(counter));
    362 //
    363 //   foo_callback.Run();  // Prints "1"
    364 //   foo_callback.Run();  // Prints "2"
    365 //   foo_callback.Run();  // Prints "3"
    366 //
    367 //   cout << counter;     // Prints "0", OwnedRef creates a copy of counter.
    368 //
    369 //  Supports OnceCallbacks as well, useful to pass placeholder arguments:
    370 //
    371 //   void bar(int& ignore, const std::string& s) { cout << s << endl }
    372 //
    373 //   OnceClosure bar_callback = BindOnce(&bar, OwnedRef(0), "Hello");
    374 //
    375 //   std::move(bar_callback).Run(); // Prints "Hello"
    376 //
    377 // Without OwnedRef() it would not be possible to pass a mutable reference to an
    378 // object owned by the callback.
    379 template <typename T>
    380 internal::OwnedRefWrapper<std::decay_t<T>> OwnedRef(T&& t) {
    381  return internal::OwnedRefWrapper<std::decay_t<T>>(std::forward<T>(t));
    382 }
    383 
    384 // Passed() is for transferring movable-but-not-copyable types (eg. unique_ptr)
    385 // through a RepeatingCallback. Logically, this signifies a destructive transfer
    386 // of the state of the argument into the target function. Invoking
    387 // RepeatingCallback::Run() twice on a callback that was created with a Passed()
    388 // argument will CHECK() because the first invocation would have already
    389 // transferred ownership to the target function.
    390 //
    391 // Note that Passed() is not necessary with BindOnce(), as std::move() does the
    392 // same thing. Avoid Passed() in favor of std::move() with BindOnce().
    393 //
    394 // EXAMPLE OF Passed():
    395 //
    396 //   void TakesOwnership(std::unique_ptr<Foo> arg) { }
    397 //   std::unique_ptr<Foo> CreateFoo() { return std::make_unique<Foo>();
    398 //   }
    399 //
    400 //   auto f = std::make_unique<Foo>();
    401 //
    402 //   // |cb| is given ownership of Foo(). |f| is now NULL.
    403 //   // You can use std::move(f) in place of &f, but it's more verbose.
    404 //   RepeatingClosure cb = BindRepeating(&TakesOwnership, Passed(&f));
    405 //
    406 //   // Run was never called so |cb| still owns Foo() and deletes
    407 //   // it on Reset().
    408 //   cb.Reset();
    409 //
    410 //   // |cb| is given a new Foo created by CreateFoo().
    411 //   cb = BindRepeating(&TakesOwnership, Passed(CreateFoo()));
    412 //
    413 //   // |arg| in TakesOwnership() is given ownership of Foo(). |cb|
    414 //   // no longer owns Foo() and, if reset, would not delete Foo().
    415 //   cb.Run();  // Foo() is now transferred to |arg| and deleted.
    416 //   cb.Run();  // This CHECK()s since Foo() already been used once.
    417 //
    418 // We offer 2 syntaxes for calling Passed(). The first takes an rvalue and is
    419 // best suited for use with the return value of a function or other temporary
    420 // rvalues. The second takes a pointer to the scoper and is just syntactic sugar
    421 // to avoid having to write Passed(std::move(scoper)).
    422 //
    423 // Both versions of Passed() prevent T from being an lvalue reference. The first
    424 // via use of enable_if, and the second takes a T* which will not bind to T&.
    425 //
    426 // DEPRECATED - Do not use in new code. See https://crbug.com/1326449
    427 template <typename T,
    428          std::enable_if_t<!std::is_lvalue_reference_v<T>>* = nullptr>
    429 inline internal::PassedWrapper<T> Passed(T&& scoper) {
    430  return internal::PassedWrapper<T>(std::move(scoper));
    431 }
    432 template <typename T>
    433 inline internal::PassedWrapper<T> Passed(T* scoper) {
    434  return internal::PassedWrapper<T>(std::move(*scoper));
    435 }
    436 
    437 // IgnoreResult() is used to adapt a function or callback with a return type to
    438 // one with a void return. This is most useful if you have a function with,
    439 // say, a pesky ignorable bool return that you want to use with PostTask or
    440 // something else that expect a callback with a void return.
    441 //
    442 // EXAMPLE OF IgnoreResult():
    443 //
    444 //   int DoSomething(int arg) { cout << arg << endl; }
    445 //
    446 //   // Assign to a callback with a void return type.
    447 //   OnceCallback<void(int)> cb = BindOnce(IgnoreResult(&DoSomething));
    448 //   std::move(cb).Run(1);  // Prints "1".
    449 //
    450 //   // Prints "2" on |ml|.
    451 //   ml->PostTask(FROM_HERE, BindOnce(IgnoreResult(&DoSomething), 2);
    452 template <typename T>
    453 inline internal::IgnoreResultHelper<T> IgnoreResult(T data) {
    454  return internal::IgnoreResultHelper<T>(std::move(data));
    455 }
    456 
    457 }  // namespace base
    458 
    459 #endif  // BASE_FUNCTIONAL_BIND_H_