xref: /aosp_15_r20/frameworks/native/include/ftl/function.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2022 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #pragma once
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include <cstddef>
20*38e8c45fSAndroid Build Coastguard Worker #include <functional>
21*38e8c45fSAndroid Build Coastguard Worker #include <type_traits>
22*38e8c45fSAndroid Build Coastguard Worker #include <utility>
23*38e8c45fSAndroid Build Coastguard Worker 
24*38e8c45fSAndroid Build Coastguard Worker #include <ftl/details/function.h>
25*38e8c45fSAndroid Build Coastguard Worker 
26*38e8c45fSAndroid Build Coastguard Worker namespace android::ftl {
27*38e8c45fSAndroid Build Coastguard Worker 
28*38e8c45fSAndroid Build Coastguard Worker // ftl::Function<F, N> is a container for function object, and can mostly be used in place of
29*38e8c45fSAndroid Build Coastguard Worker // std::function<F>.
30*38e8c45fSAndroid Build Coastguard Worker //
31*38e8c45fSAndroid Build Coastguard Worker // Unlike std::function<F>, a ftl::Function<F, N>:
32*38e8c45fSAndroid Build Coastguard Worker //
33*38e8c45fSAndroid Build Coastguard Worker //  * Uses a static amount of memory (controlled by N), and never any dynamic allocation.
34*38e8c45fSAndroid Build Coastguard Worker //  * Satisfies the std::is_trivially_copyable<> trait.
35*38e8c45fSAndroid Build Coastguard Worker //  * Satisfies the std::is_trivially_destructible<> trait.
36*38e8c45fSAndroid Build Coastguard Worker //
37*38e8c45fSAndroid Build Coastguard Worker // However those same limits are also required from the contained function object in turn.
38*38e8c45fSAndroid Build Coastguard Worker //
39*38e8c45fSAndroid Build Coastguard Worker // The size of a ftl::Function<F, N> is guaranteed to be:
40*38e8c45fSAndroid Build Coastguard Worker //
41*38e8c45fSAndroid Build Coastguard Worker //     sizeof(std::intptr_t) * (N + 2)
42*38e8c45fSAndroid Build Coastguard Worker //
43*38e8c45fSAndroid Build Coastguard Worker // A ftl::Function<F, N> can always be implicitly converted to a larger size ftl::Function<F, M>.
44*38e8c45fSAndroid Build Coastguard Worker // Trying to convert the other way leads to a compilation error.
45*38e8c45fSAndroid Build Coastguard Worker //
46*38e8c45fSAndroid Build Coastguard Worker // A default-constructed ftl::Function is in an empty state. The operator bool() overload returns
47*38e8c45fSAndroid Build Coastguard Worker // false in this state. It is undefined behavior to attempt to invoke the function in this state.
48*38e8c45fSAndroid Build Coastguard Worker //
49*38e8c45fSAndroid Build Coastguard Worker // The ftl::Function<F, N> can also be constructed or assigned from ftl::no_op. This sets up the
50*38e8c45fSAndroid Build Coastguard Worker // ftl::Function to be non-empty, with a function that when called does nothing except
51*38e8c45fSAndroid Build Coastguard Worker // default-constructs a return value.
52*38e8c45fSAndroid Build Coastguard Worker //
53*38e8c45fSAndroid Build Coastguard Worker // The ftl::make_function() helpers construct a ftl::Function<F, N>, including deducing the
54*38e8c45fSAndroid Build Coastguard Worker // values of F and N from the arguments it is given.
55*38e8c45fSAndroid Build Coastguard Worker //
56*38e8c45fSAndroid Build Coastguard Worker // The static ftl::Function<F, N>::make() helpers construct a ftl::Function<F, N> without that
57*38e8c45fSAndroid Build Coastguard Worker // deduction, and also allow for implicit argument conversion if the target being called needs them.
58*38e8c45fSAndroid Build Coastguard Worker //
59*38e8c45fSAndroid Build Coastguard Worker // The construction helpers allow any of the following types of functions to be stored:
60*38e8c45fSAndroid Build Coastguard Worker //
61*38e8c45fSAndroid Build Coastguard Worker //  * Any SMALL function object (as defined by the C++ Standard), such as a lambda with a small
62*38e8c45fSAndroid Build Coastguard Worker //    capture, or other "functor". The requirements are:
63*38e8c45fSAndroid Build Coastguard Worker //
64*38e8c45fSAndroid Build Coastguard Worker //      1) The function object must be trivial to destroy (in fact, the destructor will never
65*38e8c45fSAndroid Build Coastguard Worker //         actually be called once copied to the internal storage).
66*38e8c45fSAndroid Build Coastguard Worker //      2) The function object must be trivial to copy (the raw bytes will be copied as the
67*38e8c45fSAndroid Build Coastguard Worker //         ftl::Function<F, N> is copied/moved).
68*38e8c45fSAndroid Build Coastguard Worker //      3) The size of the function object cannot be larger than sizeof(std::intptr_t) * (N + 1),
69*38e8c45fSAndroid Build Coastguard Worker //         and it cannot require stricter alignment than alignof(std::intptr_t).
70*38e8c45fSAndroid Build Coastguard Worker //
71*38e8c45fSAndroid Build Coastguard Worker //    With the default of N=0, a lambda can only capture a single pointer-sized argument. This is
72*38e8c45fSAndroid Build Coastguard Worker //    enough to capture `this`, which is why N=0 is the default.
73*38e8c45fSAndroid Build Coastguard Worker //
74*38e8c45fSAndroid Build Coastguard Worker //  * A member function, with the address passed as the template value argument to the construction
75*38e8c45fSAndroid Build Coastguard Worker //    helper function, along with the instance pointer needed to invoke it passed as an ordinary
76*38e8c45fSAndroid Build Coastguard Worker //    argument.
77*38e8c45fSAndroid Build Coastguard Worker //
78*38e8c45fSAndroid Build Coastguard Worker //        ftl::make_function<&Class::member_function>(this);
79*38e8c45fSAndroid Build Coastguard Worker //
80*38e8c45fSAndroid Build Coastguard Worker //    Note that the indicated member function will be invoked non-virtually. If you need it to be
81*38e8c45fSAndroid Build Coastguard Worker //    invoked virtually, you should invoke it yourself with a small lambda like so:
82*38e8c45fSAndroid Build Coastguard Worker //
83*38e8c45fSAndroid Build Coastguard Worker //        ftl::function([this] { virtual_member_function(); });
84*38e8c45fSAndroid Build Coastguard Worker //
85*38e8c45fSAndroid Build Coastguard Worker //  * An ordinary function ("free function"), with the address of the function passed as a template
86*38e8c45fSAndroid Build Coastguard Worker //    value argument.
87*38e8c45fSAndroid Build Coastguard Worker //
88*38e8c45fSAndroid Build Coastguard Worker //        ftl::make_function<&std::atoi>();
89*38e8c45fSAndroid Build Coastguard Worker //
90*38e8c45fSAndroid Build Coastguard Worker //   As with the member function helper, as the function is known at compile time, it will be called
91*38e8c45fSAndroid Build Coastguard Worker //   directly.
92*38e8c45fSAndroid Build Coastguard Worker //
93*38e8c45fSAndroid Build Coastguard Worker // Example usage:
94*38e8c45fSAndroid Build Coastguard Worker //
95*38e8c45fSAndroid Build Coastguard Worker //   class MyClass {
96*38e8c45fSAndroid Build Coastguard Worker //    public:
97*38e8c45fSAndroid Build Coastguard Worker //     void on_event() const {}
98*38e8c45fSAndroid Build Coastguard Worker //     int on_string(int*, std::string_view) { return 1; }
99*38e8c45fSAndroid Build Coastguard Worker //
100*38e8c45fSAndroid Build Coastguard Worker //     auto get_function() {
101*38e8c45fSAndroid Build Coastguard Worker //       return ftl::function([this] { on_event(); });
102*38e8c45fSAndroid Build Coastguard Worker //     }
103*38e8c45fSAndroid Build Coastguard Worker //   } cls;
104*38e8c45fSAndroid Build Coastguard Worker //
105*38e8c45fSAndroid Build Coastguard Worker //   // A function container with no arguments, and returning no value.
106*38e8c45fSAndroid Build Coastguard Worker //   ftl::Function<void()> f;
107*38e8c45fSAndroid Build Coastguard Worker //
108*38e8c45fSAndroid Build Coastguard Worker //   // Construct a ftl::Function containing a small lambda.
109*38e8c45fSAndroid Build Coastguard Worker //   f = cls.get_function();
110*38e8c45fSAndroid Build Coastguard Worker //
111*38e8c45fSAndroid Build Coastguard Worker //   // Construct a ftl::Function that calls `cls.on_event()`.
112*38e8c45fSAndroid Build Coastguard Worker //   f = ftl::function<&MyClass::on_event>(&cls);
113*38e8c45fSAndroid Build Coastguard Worker //
114*38e8c45fSAndroid Build Coastguard Worker //   // Create a do-nothing function.
115*38e8c45fSAndroid Build Coastguard Worker //   f = ftl::no_op;
116*38e8c45fSAndroid Build Coastguard Worker //
117*38e8c45fSAndroid Build Coastguard Worker //   // Invoke the contained function.
118*38e8c45fSAndroid Build Coastguard Worker //   f();
119*38e8c45fSAndroid Build Coastguard Worker //
120*38e8c45fSAndroid Build Coastguard Worker //   // Also invokes it.
121*38e8c45fSAndroid Build Coastguard Worker //   std::invoke(f);
122*38e8c45fSAndroid Build Coastguard Worker //
123*38e8c45fSAndroid Build Coastguard Worker //   // Create a typedef to give a more meaningful name and bound the size.
124*38e8c45fSAndroid Build Coastguard Worker //   using MyFunction = ftl::Function<int(std::string_view), 2>;
125*38e8c45fSAndroid Build Coastguard Worker //   int* ptr = nullptr;
126*38e8c45fSAndroid Build Coastguard Worker //   auto f1 = MyFunction::make(
127*38e8c45fSAndroid Build Coastguard Worker //       [cls = &cls, ptr](std::string_view sv) {
128*38e8c45fSAndroid Build Coastguard Worker //           return cls->on_string(ptr, sv);
129*38e8c45fSAndroid Build Coastguard Worker //       });
130*38e8c45fSAndroid Build Coastguard Worker //   int r = f1("abc"sv);
131*38e8c45fSAndroid Build Coastguard Worker //
132*38e8c45fSAndroid Build Coastguard Worker //   // Returns a default-constructed int (0).
133*38e8c45fSAndroid Build Coastguard Worker //   f1 = ftl::no_op;
134*38e8c45fSAndroid Build Coastguard Worker //   r = f1("abc"sv);
135*38e8c45fSAndroid Build Coastguard Worker //   assert(r == 0);
136*38e8c45fSAndroid Build Coastguard Worker 
137*38e8c45fSAndroid Build Coastguard Worker template <typename F, std::size_t N = 0>
138*38e8c45fSAndroid Build Coastguard Worker class Function;
139*38e8c45fSAndroid Build Coastguard Worker 
140*38e8c45fSAndroid Build Coastguard Worker // Used to construct a Function that does nothing.
141*38e8c45fSAndroid Build Coastguard Worker struct NoOpTag {};
142*38e8c45fSAndroid Build Coastguard Worker 
143*38e8c45fSAndroid Build Coastguard Worker constexpr NoOpTag no_op;
144*38e8c45fSAndroid Build Coastguard Worker 
145*38e8c45fSAndroid Build Coastguard Worker // Detects that a type is a `ftl::Function<F, N>` regardless of what `F` and `N` are.
146*38e8c45fSAndroid Build Coastguard Worker template <typename>
147*38e8c45fSAndroid Build Coastguard Worker struct is_function : public std::false_type {};
148*38e8c45fSAndroid Build Coastguard Worker 
149*38e8c45fSAndroid Build Coastguard Worker template <typename F, std::size_t N>
150*38e8c45fSAndroid Build Coastguard Worker struct is_function<Function<F, N>> : public std::true_type {};
151*38e8c45fSAndroid Build Coastguard Worker 
152*38e8c45fSAndroid Build Coastguard Worker template <typename T>
153*38e8c45fSAndroid Build Coastguard Worker constexpr bool is_function_v = is_function<T>::value;
154*38e8c45fSAndroid Build Coastguard Worker 
155*38e8c45fSAndroid Build Coastguard Worker template <typename Ret, typename... Args, std::size_t N>
156*38e8c45fSAndroid Build Coastguard Worker class Function<Ret(Args...), N> final {
157*38e8c45fSAndroid Build Coastguard Worker   // Enforce a valid size, with an arbitrary maximum allowed size for the container of
158*38e8c45fSAndroid Build Coastguard Worker   // sizeof(std::intptr_t) * 16, though that maximum can be relaxed.
159*38e8c45fSAndroid Build Coastguard Worker   static_assert(N <= details::kFunctionMaximumN);
160*38e8c45fSAndroid Build Coastguard Worker 
161*38e8c45fSAndroid Build Coastguard Worker   using OpaqueStorageTraits = details::function_opaque_storage<N>;
162*38e8c45fSAndroid Build Coastguard Worker 
163*38e8c45fSAndroid Build Coastguard Worker  public:
164*38e8c45fSAndroid Build Coastguard Worker   // Defining result_type allows ftl::Function to be substituted for std::function.
165*38e8c45fSAndroid Build Coastguard Worker   using result_type = Ret;
166*38e8c45fSAndroid Build Coastguard Worker 
167*38e8c45fSAndroid Build Coastguard Worker   // Constructs an empty ftl::Function.
168*38e8c45fSAndroid Build Coastguard Worker   Function() = default;
169*38e8c45fSAndroid Build Coastguard Worker 
170*38e8c45fSAndroid Build Coastguard Worker   // Constructing or assigning from nullptr_t also creates an empty ftl::Function.
171*38e8c45fSAndroid Build Coastguard Worker   Function(std::nullptr_t) {}
172*38e8c45fSAndroid Build Coastguard Worker   Function& operator=(std::nullptr_t) { return *this = Function(nullptr); }
173*38e8c45fSAndroid Build Coastguard Worker 
174*38e8c45fSAndroid Build Coastguard Worker   // Constructing from NoOpTag sets up a a special no-op function which is valid to call, and which
175*38e8c45fSAndroid Build Coastguard Worker   // returns a default constructed return value.
176*38e8c45fSAndroid Build Coastguard Worker   Function(NoOpTag) : function_(details::bind_opaque_no_op<Ret, Args...>()) {}
177*38e8c45fSAndroid Build Coastguard Worker   Function& operator=(NoOpTag) { return *this = Function(no_op); }
178*38e8c45fSAndroid Build Coastguard Worker 
179*38e8c45fSAndroid Build Coastguard Worker   // Constructing/assigning from a function object stores a copy of that function object, however:
180*38e8c45fSAndroid Build Coastguard Worker   //  * It must be trivially copyable, as the implementation makes a copy with memcpy().
181*38e8c45fSAndroid Build Coastguard Worker   //  * It must be trivially destructible, as the implementation doesn't destroy the copy!
182*38e8c45fSAndroid Build Coastguard Worker   //  * It must fit in the limited internal storage, which enforces size/alignment restrictions.
183*38e8c45fSAndroid Build Coastguard Worker 
184*38e8c45fSAndroid Build Coastguard Worker   template <typename F, typename = std::enable_if_t<std::is_invocable_r_v<Ret, F, Args...>>>
185*38e8c45fSAndroid Build Coastguard Worker   Function(const F& f)
186*38e8c45fSAndroid Build Coastguard Worker       : opaque_(OpaqueStorageTraits::opaque_copy(f)),
187*38e8c45fSAndroid Build Coastguard Worker         function_(details::bind_opaque_function_object<F, Ret, Args...>(f)) {}
188*38e8c45fSAndroid Build Coastguard Worker 
189*38e8c45fSAndroid Build Coastguard Worker   template <typename F, typename = std::enable_if_t<std::is_invocable_r_v<Ret, F, Args...>>>
190*38e8c45fSAndroid Build Coastguard Worker   Function& operator=(const F& f) noexcept {
191*38e8c45fSAndroid Build Coastguard Worker     return *this = Function{OpaqueStorageTraits::opaque_copy(f),
192*38e8c45fSAndroid Build Coastguard Worker                             details::bind_opaque_function_object<F, Ret, Args...>(f)};
193*38e8c45fSAndroid Build Coastguard Worker   }
194*38e8c45fSAndroid Build Coastguard Worker 
195*38e8c45fSAndroid Build Coastguard Worker   // Constructing/assigning from a smaller ftl::Function is allowed, but not anything else.
196*38e8c45fSAndroid Build Coastguard Worker 
197*38e8c45fSAndroid Build Coastguard Worker   template <std::size_t M>
198*38e8c45fSAndroid Build Coastguard Worker   Function(const Function<Ret(Args...), M>& other)
199*38e8c45fSAndroid Build Coastguard Worker       : opaque_{OpaqueStorageTraits::opaque_copy(other.opaque_)}, function_(other.function_) {}
200*38e8c45fSAndroid Build Coastguard Worker 
201*38e8c45fSAndroid Build Coastguard Worker   template <std::size_t M>
202*38e8c45fSAndroid Build Coastguard Worker   auto& operator=(const Function<Ret(Args...), M>& other) {
203*38e8c45fSAndroid Build Coastguard Worker     return *this = Function{OpaqueStorageTraits::opaque_copy(other.opaque_), other.function_};
204*38e8c45fSAndroid Build Coastguard Worker   }
205*38e8c45fSAndroid Build Coastguard Worker 
206*38e8c45fSAndroid Build Coastguard Worker   // Returns true if a function is set.
207*38e8c45fSAndroid Build Coastguard Worker   explicit operator bool() const { return function_ != nullptr; }
208*38e8c45fSAndroid Build Coastguard Worker 
209*38e8c45fSAndroid Build Coastguard Worker   // Checks if the other function has the same contents as this one.
210*38e8c45fSAndroid Build Coastguard Worker   bool operator==(const Function& other) const {
211*38e8c45fSAndroid Build Coastguard Worker     return other.opaque_ == opaque_ && other.function_ == function_;
212*38e8c45fSAndroid Build Coastguard Worker   }
213*38e8c45fSAndroid Build Coastguard Worker   bool operator!=(const Function& other) const { return !operator==(other); }
214*38e8c45fSAndroid Build Coastguard Worker 
215*38e8c45fSAndroid Build Coastguard Worker   // Alternative way of testing for a function being set.
216*38e8c45fSAndroid Build Coastguard Worker   bool operator==(std::nullptr_t) const { return function_ == nullptr; }
217*38e8c45fSAndroid Build Coastguard Worker   bool operator!=(std::nullptr_t) const { return function_ != nullptr; }
218*38e8c45fSAndroid Build Coastguard Worker 
219*38e8c45fSAndroid Build Coastguard Worker   // Invokes the function.
220*38e8c45fSAndroid Build Coastguard Worker   Ret operator()(Args... args) const {
221*38e8c45fSAndroid Build Coastguard Worker     return std::invoke(function_, opaque_.data(), std::forward<Args>(args)...);
222*38e8c45fSAndroid Build Coastguard Worker   }
223*38e8c45fSAndroid Build Coastguard Worker 
224*38e8c45fSAndroid Build Coastguard Worker   // Creation helper for function objects, such as lambdas.
225*38e8c45fSAndroid Build Coastguard Worker   template <typename F>
226*38e8c45fSAndroid Build Coastguard Worker   static auto make(const F& f) -> decltype(Function{f}) {
227*38e8c45fSAndroid Build Coastguard Worker     return Function{f};
228*38e8c45fSAndroid Build Coastguard Worker   }
229*38e8c45fSAndroid Build Coastguard Worker 
230*38e8c45fSAndroid Build Coastguard Worker   // Creation helper for a class pointer and a compile-time chosen member function to call.
231*38e8c45fSAndroid Build Coastguard Worker   template <auto MemberFunction, typename Class>
232*38e8c45fSAndroid Build Coastguard Worker   static auto make(Class* instance) -> decltype(Function{
233*38e8c45fSAndroid Build Coastguard Worker       details::bind_member_function<MemberFunction>(instance,
234*38e8c45fSAndroid Build Coastguard Worker                                                     static_cast<Ret (*)(Args...)>(nullptr))}) {
235*38e8c45fSAndroid Build Coastguard Worker     return Function{details::bind_member_function<MemberFunction>(
236*38e8c45fSAndroid Build Coastguard Worker         instance, static_cast<Ret (*)(Args...)>(nullptr))};
237*38e8c45fSAndroid Build Coastguard Worker   }
238*38e8c45fSAndroid Build Coastguard Worker 
239*38e8c45fSAndroid Build Coastguard Worker   // Creation helper for a compile-time chosen free function to call.
240*38e8c45fSAndroid Build Coastguard Worker   template <auto FreeFunction>
241*38e8c45fSAndroid Build Coastguard Worker   static auto make() -> decltype(Function{
242*38e8c45fSAndroid Build Coastguard Worker       details::bind_free_function<FreeFunction>(static_cast<Ret (*)(Args...)>(nullptr))}) {
243*38e8c45fSAndroid Build Coastguard Worker     return Function{
244*38e8c45fSAndroid Build Coastguard Worker         details::bind_free_function<FreeFunction>(static_cast<Ret (*)(Args...)>(nullptr))};
245*38e8c45fSAndroid Build Coastguard Worker   }
246*38e8c45fSAndroid Build Coastguard Worker 
247*38e8c45fSAndroid Build Coastguard Worker  private:
248*38e8c45fSAndroid Build Coastguard Worker   // Needed so a Function<F, M> can be converted to a Function<F, N>.
249*38e8c45fSAndroid Build Coastguard Worker   template <typename, std::size_t>
250*38e8c45fSAndroid Build Coastguard Worker   friend class Function;
251*38e8c45fSAndroid Build Coastguard Worker 
252*38e8c45fSAndroid Build Coastguard Worker   // The function pointer type of function stored in `function_`. The first argument is always
253*38e8c45fSAndroid Build Coastguard Worker   // `&opaque_`.
254*38e8c45fSAndroid Build Coastguard Worker   using StoredFunction = Ret(void*, Args...);
255*38e8c45fSAndroid Build Coastguard Worker 
256*38e8c45fSAndroid Build Coastguard Worker   // The type of the opaque storage, used to hold an appropriate function object.
257*38e8c45fSAndroid Build Coastguard Worker   // The type stored here is ONLY known to the StoredFunction.
258*38e8c45fSAndroid Build Coastguard Worker   // We always use at least one std::intptr_t worth of storage, and always a multiple of that size.
259*38e8c45fSAndroid Build Coastguard Worker   using OpaqueStorage = typename OpaqueStorageTraits::type;
260*38e8c45fSAndroid Build Coastguard Worker 
261*38e8c45fSAndroid Build Coastguard Worker   // Internal constructor for creating from a raw opaque blob + function pointer.
262*38e8c45fSAndroid Build Coastguard Worker   Function(const OpaqueStorage& opaque, StoredFunction* function)
263*38e8c45fSAndroid Build Coastguard Worker       : opaque_(opaque), function_(function) {}
264*38e8c45fSAndroid Build Coastguard Worker 
265*38e8c45fSAndroid Build Coastguard Worker   // Note: `mutable` so that `operator() const` can use it.
266*38e8c45fSAndroid Build Coastguard Worker   mutable OpaqueStorage opaque_{};
267*38e8c45fSAndroid Build Coastguard Worker   StoredFunction* function_{nullptr};
268*38e8c45fSAndroid Build Coastguard Worker };
269*38e8c45fSAndroid Build Coastguard Worker 
270*38e8c45fSAndroid Build Coastguard Worker // Makes a ftl::Function given a function object `F`.
271*38e8c45fSAndroid Build Coastguard Worker template <typename F, typename T = details::function_traits<F>>
272*38e8c45fSAndroid Build Coastguard Worker Function(const F&) -> Function<typename T::type, T::size>;
273*38e8c45fSAndroid Build Coastguard Worker 
274*38e8c45fSAndroid Build Coastguard Worker template <typename F>
275*38e8c45fSAndroid Build Coastguard Worker auto make_function(const F& f) -> decltype(Function{f}) {
276*38e8c45fSAndroid Build Coastguard Worker   return Function{f};
277*38e8c45fSAndroid Build Coastguard Worker }
278*38e8c45fSAndroid Build Coastguard Worker 
279*38e8c45fSAndroid Build Coastguard Worker // Makes a ftl::Function given a `MemberFunction` and a instance pointer to the associated `Class`.
280*38e8c45fSAndroid Build Coastguard Worker template <auto MemberFunction, typename Class>
281*38e8c45fSAndroid Build Coastguard Worker auto make_function(Class* instance)
282*38e8c45fSAndroid Build Coastguard Worker     -> decltype(Function{details::bind_member_function<MemberFunction>(
283*38e8c45fSAndroid Build Coastguard Worker         instance,
284*38e8c45fSAndroid Build Coastguard Worker         static_cast<details::remove_member_function_pointer_t<MemberFunction>*>(nullptr))}) {
285*38e8c45fSAndroid Build Coastguard Worker   return Function{details::bind_member_function<MemberFunction>(
286*38e8c45fSAndroid Build Coastguard Worker       instance, static_cast<details::remove_member_function_pointer_t<MemberFunction>*>(nullptr))};
287*38e8c45fSAndroid Build Coastguard Worker }
288*38e8c45fSAndroid Build Coastguard Worker 
289*38e8c45fSAndroid Build Coastguard Worker // Makes a ftl::Function given an ordinary free function.
290*38e8c45fSAndroid Build Coastguard Worker template <auto FreeFunction>
291*38e8c45fSAndroid Build Coastguard Worker auto make_function() -> decltype(Function{
292*38e8c45fSAndroid Build Coastguard Worker     details::bind_free_function<FreeFunction>(static_cast<decltype(FreeFunction)>(nullptr))}) {
293*38e8c45fSAndroid Build Coastguard Worker   return Function{
294*38e8c45fSAndroid Build Coastguard Worker       details::bind_free_function<FreeFunction>(static_cast<decltype(FreeFunction)>(nullptr))};
295*38e8c45fSAndroid Build Coastguard Worker }
296*38e8c45fSAndroid Build Coastguard Worker 
297*38e8c45fSAndroid Build Coastguard Worker }  // namespace android::ftl
298