tor-browser

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

function_ref.h (4062B)


      1 // Copyright 2022 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_FUNCTION_REF_H_
      6 #define BASE_FUNCTIONAL_FUNCTION_REF_H_
      7 
      8 #include <type_traits>
      9 #include <utility>
     10 
     11 #include "base/functional/bind_internal.h"
     12 #include "third_party/abseil-cpp/absl/base/attributes.h"
     13 #include "third_party/abseil-cpp/absl/functional/function_ref.h"
     14 
     15 namespace base {
     16 
     17 template <typename Signature>
     18 class FunctionRef;
     19 
     20 // A non-owning reference to any invocable object (e.g. function pointer, method
     21 // pointer, functor, lambda, et cetera) suitable for use as a type-erased
     22 // argument to ForEach-style functions or other visitor patterns that:
     23 //
     24 // - do not need to copy or take ownership of the argument
     25 // - synchronously call the invocable that was passed as an argument
     26 //
     27 // `base::FunctionRef` makes no heap allocations: it is trivially copyable and
     28 // should be passed by value.
     29 //
     30 // `base::FunctionRef` has no null/empty state: a `base::FunctionRef` is always
     31 // valid to invoke.
     32 //
     33 // The usual lifetime precautions for other non-owning references types (e.g.
     34 // `base::StringPiece`, `base::span`) also apply to `base::FunctionRef`.
     35 // `base::FunctionRef` should typically be used as an argument; returning a
     36 // `base::FunctionRef` or storing a `base::FunctionRef` as a field is dangerous
     37 // and likely to result in lifetime bugs.
     38 //
     39 // `base::RepeatingCallback` and `base::BindRepeating()` is another common way
     40 // to represent type-erased invocable objects. In contrast, it requires a heap
     41 // allocation and is not trivially copyable. It should be used when there are
     42 // ownership requirements (e.g. partial application of arguments to a function
     43 // stored for asynchronous execution).
     44 //
     45 // Note: `base::FunctionRef` is similar to `absl::FunctionRef<R(Args...)>`, but
     46 // with stricter conversions between function types. Return type conversions are
     47 // allowed (e.g. `int` -> `bool`, `Derived*` -> `Base*`); other than that,
     48 // function parameter types must match exactly, and return values may not be
     49 // silently discarded, e.g. `absl::FunctionRef` allows the following:
     50 //
     51 //   // Silently discards `42`.
     52 //   [] (absl::FunctionRef<void()> r) {
     53 //     r();
     54 //   }([] { return 42; });
     55 //
     56 // But with `base::FunctionRef`:
     57 //
     58 //   // Does not compile!
     59 //   [] (base::FunctionRef<void()> r) {
     60 //     r();
     61 //   }([] { return 42; });
     62 template <typename R, typename... Args>
     63 class FunctionRef<R(Args...)> {
     64 private:
     65  template <typename Functor,
     66            typename FunctorReturnType =
     67                typename internal::BindTypeHelper<Functor>::ReturnType,
     68            typename FunctorArgsAsTypeList =
     69                typename internal::BindTypeHelper<Functor>::RunParamsList>
     70  using EnableIfCompatible = std::enable_if_t<
     71      std::is_convertible_v<FunctorReturnType, R> &&
     72      std::is_same_v<FunctorArgsAsTypeList, internal::TypeList<Args...>>>;
     73 
     74 public:
     75  // `ABSL_ATTRIBUTE_LIFETIME_BOUND` is important since `FunctionRef` retains
     76  // only a reference to `functor`, `functor` must outlive `this`.
     77  template <typename Functor, typename = EnableIfCompatible<Functor>>
     78  // NOLINTNEXTLINE(google-explicit-constructor)
     79  FunctionRef(const Functor& functor ABSL_ATTRIBUTE_LIFETIME_BOUND)
     80      : wrapped_func_ref_(functor) {}
     81 
     82  // Null FunctionRefs are not allowed.
     83  FunctionRef() = delete;
     84 
     85  FunctionRef(const FunctionRef&) = default;
     86  // Reduce the likelihood of lifetime bugs by disallowing assignment.
     87  FunctionRef& operator=(const FunctionRef&) = delete;
     88 
     89  R operator()(Args... args) const {
     90    return wrapped_func_ref_(std::forward<Args>(args)...);
     91  }
     92 
     93  absl::FunctionRef<R(Args...)> ToAbsl() const { return wrapped_func_ref_; }
     94 
     95  // In Chrome, converting to `absl::FunctionRef` should be explicitly done
     96  // through `ToAbsl()`.
     97  template <typename Signature>
     98  operator absl::FunctionRef<Signature>() = delete;
     99 
    100 private:
    101  absl::FunctionRef<R(Args...)> wrapped_func_ref_;
    102 };
    103 
    104 }  // namespace base
    105 
    106 #endif  // BASE_FUNCTIONAL_FUNCTION_REF_H_