xref: /aosp_15_r20/external/cronet/base/functional/function_ref.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2022 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_FUNCTIONAL_FUNCTION_REF_H_
6*6777b538SAndroid Build Coastguard Worker #define BASE_FUNCTIONAL_FUNCTION_REF_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <concepts>
9*6777b538SAndroid Build Coastguard Worker #include <type_traits>
10*6777b538SAndroid Build Coastguard Worker #include <utility>
11*6777b538SAndroid Build Coastguard Worker 
12*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind_internal.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/types/is_instantiation.h"
14*6777b538SAndroid Build Coastguard Worker #include "third_party/abseil-cpp/absl/base/attributes.h"
15*6777b538SAndroid Build Coastguard Worker #include "third_party/abseil-cpp/absl/functional/function_ref.h"
16*6777b538SAndroid Build Coastguard Worker 
17*6777b538SAndroid Build Coastguard Worker namespace base {
18*6777b538SAndroid Build Coastguard Worker 
19*6777b538SAndroid Build Coastguard Worker template <typename Signature>
20*6777b538SAndroid Build Coastguard Worker class FunctionRef;
21*6777b538SAndroid Build Coastguard Worker 
22*6777b538SAndroid Build Coastguard Worker // A non-owning reference to any invocable object (e.g. function pointer, method
23*6777b538SAndroid Build Coastguard Worker // pointer, functor, lambda, et cetera) suitable for use as a type-erased
24*6777b538SAndroid Build Coastguard Worker // argument to ForEach-style functions or other visitor patterns that:
25*6777b538SAndroid Build Coastguard Worker //
26*6777b538SAndroid Build Coastguard Worker // - do not need to copy or take ownership of the argument
27*6777b538SAndroid Build Coastguard Worker // - synchronously call the invocable that was passed as an argument
28*6777b538SAndroid Build Coastguard Worker //
29*6777b538SAndroid Build Coastguard Worker // `base::FunctionRef` makes no heap allocations: it is trivially copyable and
30*6777b538SAndroid Build Coastguard Worker // should be passed by value.
31*6777b538SAndroid Build Coastguard Worker //
32*6777b538SAndroid Build Coastguard Worker // `base::FunctionRef` has no null/empty state: a `base::FunctionRef` is always
33*6777b538SAndroid Build Coastguard Worker // valid to invoke.
34*6777b538SAndroid Build Coastguard Worker //
35*6777b538SAndroid Build Coastguard Worker // The usual lifetime precautions for other non-owning references types (e.g.
36*6777b538SAndroid Build Coastguard Worker // `base::StringPiece`, `base::span`) also apply to `base::FunctionRef`.
37*6777b538SAndroid Build Coastguard Worker // `base::FunctionRef` should typically be used as an argument; returning a
38*6777b538SAndroid Build Coastguard Worker // `base::FunctionRef` or storing a `base::FunctionRef` as a field is dangerous
39*6777b538SAndroid Build Coastguard Worker // and likely to result in lifetime bugs.
40*6777b538SAndroid Build Coastguard Worker //
41*6777b538SAndroid Build Coastguard Worker // `base::RepeatingCallback` and `base::BindRepeating()` is another common way
42*6777b538SAndroid Build Coastguard Worker // to represent type-erased invocable objects. In contrast, it requires a heap
43*6777b538SAndroid Build Coastguard Worker // allocation and is not trivially copyable. It should be used when there are
44*6777b538SAndroid Build Coastguard Worker // ownership requirements (e.g. partial application of arguments to a function
45*6777b538SAndroid Build Coastguard Worker // stored for asynchronous execution).
46*6777b538SAndroid Build Coastguard Worker //
47*6777b538SAndroid Build Coastguard Worker // Note: `base::FunctionRef` is similar to `absl::FunctionRef<R(Args...)>`, but
48*6777b538SAndroid Build Coastguard Worker // with stricter conversions between function types. Return type conversions are
49*6777b538SAndroid Build Coastguard Worker // allowed (e.g. `int` -> `bool`, `Derived*` -> `Base*`); other than that,
50*6777b538SAndroid Build Coastguard Worker // function parameter types must match exactly, and return values may not be
51*6777b538SAndroid Build Coastguard Worker // silently discarded, e.g. `absl::FunctionRef` allows the following:
52*6777b538SAndroid Build Coastguard Worker //
53*6777b538SAndroid Build Coastguard Worker //   // Silently discards `42`.
54*6777b538SAndroid Build Coastguard Worker //   [] (absl::FunctionRef<void()> r) {
55*6777b538SAndroid Build Coastguard Worker //     r();
56*6777b538SAndroid Build Coastguard Worker //   }([] { return 42; });
57*6777b538SAndroid Build Coastguard Worker //
58*6777b538SAndroid Build Coastguard Worker // But with `base::FunctionRef`:
59*6777b538SAndroid Build Coastguard Worker //
60*6777b538SAndroid Build Coastguard Worker //   // Does not compile!
61*6777b538SAndroid Build Coastguard Worker //   [] (base::FunctionRef<void()> r) {
62*6777b538SAndroid Build Coastguard Worker //     r();
63*6777b538SAndroid Build Coastguard Worker //   }([] { return 42; });
64*6777b538SAndroid Build Coastguard Worker template <typename R, typename... Args>
65*6777b538SAndroid Build Coastguard Worker class FunctionRef<R(Args...)> {
66*6777b538SAndroid Build Coastguard Worker   template <typename Functor,
67*6777b538SAndroid Build Coastguard Worker             typename RunType = internal::FunctorTraits<Functor>::RunType>
68*6777b538SAndroid Build Coastguard Worker   static constexpr bool kCompatibleFunctor =
69*6777b538SAndroid Build Coastguard Worker       std::convertible_to<internal::ExtractReturnType<RunType>, R> &&
70*6777b538SAndroid Build Coastguard Worker       std::same_as<internal::ExtractArgs<RunType>, internal::TypeList<Args...>>;
71*6777b538SAndroid Build Coastguard Worker 
72*6777b538SAndroid Build Coastguard Worker  public:
73*6777b538SAndroid Build Coastguard Worker   // `ABSL_ATTRIBUTE_LIFETIME_BOUND` is important; since `FunctionRef` retains
74*6777b538SAndroid Build Coastguard Worker   // only a reference to `functor`, `functor` must outlive `this`.
75*6777b538SAndroid Build Coastguard Worker   template <typename Functor>
76*6777b538SAndroid Build Coastguard Worker     requires kCompatibleFunctor<Functor> &&
77*6777b538SAndroid Build Coastguard Worker              // Prevent this constructor from participating in overload
78*6777b538SAndroid Build Coastguard Worker              // resolution if the callable is itself an instantiation of the
79*6777b538SAndroid Build Coastguard Worker              // `FunctionRef` template.
80*6777b538SAndroid Build Coastguard Worker              //
81*6777b538SAndroid Build Coastguard Worker              // If the callable is a `FunctionRef` with exactly the same
82*6777b538SAndroid Build Coastguard Worker              // signature as us, then the copy constructor will be used instead,
83*6777b538SAndroid Build Coastguard Worker              // so this has no effect. (Note that if the constructor argument
84*6777b538SAndroid Build Coastguard Worker              // were `Functor&&`, this exclusion would be necessary to force the
85*6777b538SAndroid Build Coastguard Worker              // choice of the copy constructor over this one for non-const ref
86*6777b538SAndroid Build Coastguard Worker              // args; see https://stackoverflow.com/q/57909923.)
87*6777b538SAndroid Build Coastguard Worker              //
88*6777b538SAndroid Build Coastguard Worker              // If the callable is a `FunctionRef` with some other signature
89*6777b538SAndroid Build Coastguard Worker              // then we choose not to support binding to it at all. Conceivably
90*6777b538SAndroid Build Coastguard Worker              // we could teach our trampoline to deal with this, but this may be
91*6777b538SAndroid Build Coastguard Worker              // the sign of an object lifetime bug, and again it's not clear
92*6777b538SAndroid Build Coastguard Worker              // that this isn't just a mistake on the part of the user.
93*6777b538SAndroid Build Coastguard Worker              (!internal::is_instantiation_v<FunctionRef,
94*6777b538SAndroid Build Coastguard Worker                                             std::decay_t<Functor>>) &&
95*6777b538SAndroid Build Coastguard Worker              // For the same reason as the second case above, prevent
96*6777b538SAndroid Build Coastguard Worker              // construction from `absl::FunctionRef`.
97*6777b538SAndroid Build Coastguard Worker              (!internal::is_instantiation_v<absl::FunctionRef,
98*6777b538SAndroid Build Coastguard Worker                                             std::decay_t<Functor>>)
99*6777b538SAndroid Build Coastguard Worker   // NOLINTNEXTLINE(google-explicit-constructor)
FunctionRef(const Functor & functor ABSL_ATTRIBUTE_LIFETIME_BOUND)100*6777b538SAndroid Build Coastguard Worker   FunctionRef(const Functor& functor ABSL_ATTRIBUTE_LIFETIME_BOUND)
101*6777b538SAndroid Build Coastguard Worker       : wrapped_func_ref_(functor) {}
102*6777b538SAndroid Build Coastguard Worker 
103*6777b538SAndroid Build Coastguard Worker   // Constructs a reference to the given function pointer. This constructor
104*6777b538SAndroid Build Coastguard Worker   // serves to exclude this case from lifetime analysis, since the underlying
105*6777b538SAndroid Build Coastguard Worker   // code pointed to by a function pointer is safe to invoke even if the
106*6777b538SAndroid Build Coastguard Worker   // lifetime of the pointer provided doesn't outlive us, e.g.:
107*6777b538SAndroid Build Coastguard Worker   //   `const FunctionRef<void(int)> ref = +[](int i) { ... };`
108*6777b538SAndroid Build Coastguard Worker   // Without this constructor, the above code would warn about dangling refs.
109*6777b538SAndroid Build Coastguard Worker   // TODO(pkasting): Also support ptr-to-member-functions; this requires changes
110*6777b538SAndroid Build Coastguard Worker   // in `absl::FunctionRef` or else rewriting this class to not use that one.
111*6777b538SAndroid Build Coastguard Worker   template <typename Func>
112*6777b538SAndroid Build Coastguard Worker     requires kCompatibleFunctor<Func*>
113*6777b538SAndroid Build Coastguard Worker   // NOLINTNEXTLINE(google-explicit-constructor)
FunctionRef(Func * func)114*6777b538SAndroid Build Coastguard Worker   FunctionRef(Func* func) : wrapped_func_ref_(func) {}
115*6777b538SAndroid Build Coastguard Worker 
116*6777b538SAndroid Build Coastguard Worker   // Null FunctionRefs are not allowed.
117*6777b538SAndroid Build Coastguard Worker   FunctionRef() = delete;
118*6777b538SAndroid Build Coastguard Worker 
119*6777b538SAndroid Build Coastguard Worker   FunctionRef(const FunctionRef&) = default;
120*6777b538SAndroid Build Coastguard Worker   // Reduce the likelihood of lifetime bugs by disallowing assignment.
121*6777b538SAndroid Build Coastguard Worker   FunctionRef& operator=(const FunctionRef&) = delete;
122*6777b538SAndroid Build Coastguard Worker 
operator()123*6777b538SAndroid Build Coastguard Worker   R operator()(Args... args) const {
124*6777b538SAndroid Build Coastguard Worker     return wrapped_func_ref_(std::forward<Args>(args)...);
125*6777b538SAndroid Build Coastguard Worker   }
126*6777b538SAndroid Build Coastguard Worker 
127*6777b538SAndroid Build Coastguard Worker  private:
128*6777b538SAndroid Build Coastguard Worker   absl::FunctionRef<R(Args...)> wrapped_func_ref_;
129*6777b538SAndroid Build Coastguard Worker };
130*6777b538SAndroid Build Coastguard Worker 
131*6777b538SAndroid Build Coastguard Worker }  // namespace base
132*6777b538SAndroid Build Coastguard Worker 
133*6777b538SAndroid Build Coastguard Worker #endif  // BASE_FUNCTIONAL_FUNCTION_REF_H_
134