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