xref: /aosp_15_r20/external/pigweed/pw_function/docs.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker.. _module-pw_function:
2*61c4878aSAndroid Build Coastguard Worker
3*61c4878aSAndroid Build Coastguard Worker===========
4*61c4878aSAndroid Build Coastguard Workerpw_function
5*61c4878aSAndroid Build Coastguard Worker===========
6*61c4878aSAndroid Build Coastguard Worker.. pigweed-module::
7*61c4878aSAndroid Build Coastguard Worker   :name: pw_function
8*61c4878aSAndroid Build Coastguard Worker
9*61c4878aSAndroid Build Coastguard Worker* **Familiar**. ``pw_function`` provides a standard, general-purpose API for
10*61c4878aSAndroid Build Coastguard Worker  wrapping callable objects that's similar to `std::function`_.
11*61c4878aSAndroid Build Coastguard Worker* **Optimized**. ``pw_function`` doesn't allocate (unless you want it to) and
12*61c4878aSAndroid Build Coastguard Worker  uses several tricks to prevent code bloat.
13*61c4878aSAndroid Build Coastguard Worker
14*61c4878aSAndroid Build Coastguard Worker.. _std\:\:function: https://en.cppreference.com/w/cpp/utility/functional/function
15*61c4878aSAndroid Build Coastguard Worker
16*61c4878aSAndroid Build Coastguard Worker.. code-block:: c++
17*61c4878aSAndroid Build Coastguard Worker
18*61c4878aSAndroid Build Coastguard Worker   #include "pw_function/function.h"
19*61c4878aSAndroid Build Coastguard Worker
20*61c4878aSAndroid Build Coastguard Worker   // pw::Function can be constructed from a function pointer...
21*61c4878aSAndroid Build Coastguard Worker   int _a(int a, int b) { return a + b; }
22*61c4878aSAndroid Build Coastguard Worker   pw::Function<int(int, int)> add(_a);
23*61c4878aSAndroid Build Coastguard Worker   // ... or a lambda.
24*61c4878aSAndroid Build Coastguard Worker   pw::Function<int(int)> square([](int num) { return num * num; });
25*61c4878aSAndroid Build Coastguard Worker
26*61c4878aSAndroid Build Coastguard Worker   // pw::Callback can only be invoked once. After the first call, the target
27*61c4878aSAndroid Build Coastguard Worker   // function is released and destroyed, along with any resources owned by
28*61c4878aSAndroid Build Coastguard Worker   // that function.
29*61c4878aSAndroid Build Coastguard Worker   pw::Callback<void(void)> flip_table_once([](void) {
30*61c4878aSAndroid Build Coastguard Worker     // (╯°□°)╯︵ ┻━┻
31*61c4878aSAndroid Build Coastguard Worker   });
32*61c4878aSAndroid Build Coastguard Worker
33*61c4878aSAndroid Build Coastguard Worker   add(5, 6);
34*61c4878aSAndroid Build Coastguard Worker   add = nullptr;  // pw::Function and pw::Callback are nullable
35*61c4878aSAndroid Build Coastguard Worker   add(7, 2);  // CRASH
36*61c4878aSAndroid Build Coastguard Worker
37*61c4878aSAndroid Build Coastguard Worker   square(4);
38*61c4878aSAndroid Build Coastguard Worker
39*61c4878aSAndroid Build Coastguard Worker   if (flip_table_once != nullptr) {  // Safe to call
40*61c4878aSAndroid Build Coastguard Worker     flip_table_once();
41*61c4878aSAndroid Build Coastguard Worker   } else {
42*61c4878aSAndroid Build Coastguard Worker     // ┬─┬ノ( º _ ºノ)
43*61c4878aSAndroid Build Coastguard Worker   }
44*61c4878aSAndroid Build Coastguard Worker
45*61c4878aSAndroid Build Coastguard Worker
46*61c4878aSAndroid Build Coastguard Worker.. _module-pw_function-start:
47*61c4878aSAndroid Build Coastguard Worker
48*61c4878aSAndroid Build Coastguard Worker-----------
49*61c4878aSAndroid Build Coastguard WorkerGet started
50*61c4878aSAndroid Build Coastguard Worker-----------
51*61c4878aSAndroid Build Coastguard Worker.. tab-set::
52*61c4878aSAndroid Build Coastguard Worker
53*61c4878aSAndroid Build Coastguard Worker   .. tab-item:: Bazel
54*61c4878aSAndroid Build Coastguard Worker
55*61c4878aSAndroid Build Coastguard Worker      Add ``@pigweed//pw_function`` to your target's ``deps``:
56*61c4878aSAndroid Build Coastguard Worker
57*61c4878aSAndroid Build Coastguard Worker      .. code-block::
58*61c4878aSAndroid Build Coastguard Worker
59*61c4878aSAndroid Build Coastguard Worker         cc_library("...") {
60*61c4878aSAndroid Build Coastguard Worker           # ...
61*61c4878aSAndroid Build Coastguard Worker           deps = [
62*61c4878aSAndroid Build Coastguard Worker             # ...
63*61c4878aSAndroid Build Coastguard Worker             "@pigweed//pw_function",
64*61c4878aSAndroid Build Coastguard Worker             # ...
65*61c4878aSAndroid Build Coastguard Worker           ]
66*61c4878aSAndroid Build Coastguard Worker         }
67*61c4878aSAndroid Build Coastguard Worker
68*61c4878aSAndroid Build Coastguard Worker      This assumes that your Bazel ``WORKSPACE`` has a `repository
69*61c4878aSAndroid Build Coastguard Worker      <https://bazel.build/concepts/build-ref#repositories>`_ named ``@pigweed``
70*61c4878aSAndroid Build Coastguard Worker      that points to the upstream Pigweed repository.
71*61c4878aSAndroid Build Coastguard Worker
72*61c4878aSAndroid Build Coastguard Worker   .. tab-item:: GN
73*61c4878aSAndroid Build Coastguard Worker
74*61c4878aSAndroid Build Coastguard Worker      Add ``$dir_pw_function`` to your target's ``deps``:
75*61c4878aSAndroid Build Coastguard Worker
76*61c4878aSAndroid Build Coastguard Worker      .. code-block::
77*61c4878aSAndroid Build Coastguard Worker
78*61c4878aSAndroid Build Coastguard Worker         pw_executable("...") {
79*61c4878aSAndroid Build Coastguard Worker           # ...
80*61c4878aSAndroid Build Coastguard Worker           deps = [
81*61c4878aSAndroid Build Coastguard Worker             # ...
82*61c4878aSAndroid Build Coastguard Worker             "$dir_pw_function",
83*61c4878aSAndroid Build Coastguard Worker             # ...
84*61c4878aSAndroid Build Coastguard Worker           ]
85*61c4878aSAndroid Build Coastguard Worker         }
86*61c4878aSAndroid Build Coastguard Worker
87*61c4878aSAndroid Build Coastguard Worker   .. tab-item:: CMake
88*61c4878aSAndroid Build Coastguard Worker
89*61c4878aSAndroid Build Coastguard Worker      Link your library to ``pw_function``:
90*61c4878aSAndroid Build Coastguard Worker
91*61c4878aSAndroid Build Coastguard Worker      .. code-block::
92*61c4878aSAndroid Build Coastguard Worker
93*61c4878aSAndroid Build Coastguard Worker         add_library(my_lib ...)
94*61c4878aSAndroid Build Coastguard Worker         target_link_libraries(my_lib PUBLIC pw_function)
95*61c4878aSAndroid Build Coastguard Worker
96*61c4878aSAndroid Build Coastguard WorkerUse ``pw_function`` in your C++ code:
97*61c4878aSAndroid Build Coastguard Worker
98*61c4878aSAndroid Build Coastguard Worker.. code-block:: c++
99*61c4878aSAndroid Build Coastguard Worker
100*61c4878aSAndroid Build Coastguard Worker   #include "pw_function/function.h"
101*61c4878aSAndroid Build Coastguard Worker
102*61c4878aSAndroid Build Coastguard Worker   // ...
103*61c4878aSAndroid Build Coastguard Worker
104*61c4878aSAndroid Build Coastguard Worker.. _module-pw_function-guides:
105*61c4878aSAndroid Build Coastguard Worker
106*61c4878aSAndroid Build Coastguard Worker------
107*61c4878aSAndroid Build Coastguard WorkerGuides
108*61c4878aSAndroid Build Coastguard Worker------
109*61c4878aSAndroid Build Coastguard Worker
110*61c4878aSAndroid Build Coastguard WorkerConstruct ``pw::Function`` from a function pointer
111*61c4878aSAndroid Build Coastguard Worker==================================================
112*61c4878aSAndroid Build Coastguard Worker:cpp:type:`pw::Function` is a move-only callable wrapper constructable from any
113*61c4878aSAndroid Build Coastguard Workercallable object. It's templated on the signature of the callable it stores and
114*61c4878aSAndroid Build Coastguard Workerimplements the call operator; invoking a ``pw::Function`` object forwards to
115*61c4878aSAndroid Build Coastguard Workerthe stored callable.
116*61c4878aSAndroid Build Coastguard Worker
117*61c4878aSAndroid Build Coastguard Worker.. code-block:: c++
118*61c4878aSAndroid Build Coastguard Worker
119*61c4878aSAndroid Build Coastguard Worker   int Add(int a, int b) { return a + b; }
120*61c4878aSAndroid Build Coastguard Worker
121*61c4878aSAndroid Build Coastguard Worker   // Construct a Function object from a function pointer.
122*61c4878aSAndroid Build Coastguard Worker   pw::Function<int(int, int)> add_function(Add);
123*61c4878aSAndroid Build Coastguard Worker
124*61c4878aSAndroid Build Coastguard Worker   // Invoke the function object.
125*61c4878aSAndroid Build Coastguard Worker   int result = add_function(3, 5);
126*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(result, 8);
127*61c4878aSAndroid Build Coastguard Worker
128*61c4878aSAndroid Build Coastguard WorkerConstruct ``pw::Function`` from a lambda
129*61c4878aSAndroid Build Coastguard Worker========================================
130*61c4878aSAndroid Build Coastguard Worker.. code-block:: c++
131*61c4878aSAndroid Build Coastguard Worker
132*61c4878aSAndroid Build Coastguard Worker   // Construct a function from a lambda.
133*61c4878aSAndroid Build Coastguard Worker   pw::Function<int(int)> negate([](int value) { return -value; });
134*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(negate(27), -27);
135*61c4878aSAndroid Build Coastguard Worker
136*61c4878aSAndroid Build Coastguard WorkerCreate single-use functions with ``pw::Callback``
137*61c4878aSAndroid Build Coastguard Worker=================================================
138*61c4878aSAndroid Build Coastguard Worker:cpp:type:`pw::Callback` is a specialization of :cpp:type:`pw::Function` that
139*61c4878aSAndroid Build Coastguard Workercan only be called once. After a :cpp:type:`pw::Callback` is called, the target
140*61c4878aSAndroid Build Coastguard Workerfunction is released and destroyed, along with any resources owned by that
141*61c4878aSAndroid Build Coastguard Workerfunction. A :cpp:type:`pw::Callback` in the "already called" state
142*61c4878aSAndroid Build Coastguard Workerhas the same state as a :cpp:type:`pw::Function` that has been assigned to
143*61c4878aSAndroid Build Coastguard Workernullptr.
144*61c4878aSAndroid Build Coastguard Worker
145*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
146*61c4878aSAndroid Build Coastguard Worker
147*61c4878aSAndroid Build Coastguard Worker   pw::Callback<void(void)> flip_table_once([](void) {
148*61c4878aSAndroid Build Coastguard Worker     // (╯°□°)╯︵ ┻━┻
149*61c4878aSAndroid Build Coastguard Worker   });
150*61c4878aSAndroid Build Coastguard Worker
151*61c4878aSAndroid Build Coastguard Worker   flip_table_once();  // OK
152*61c4878aSAndroid Build Coastguard Worker   flip_table_once();  // CRASH
153*61c4878aSAndroid Build Coastguard Worker
154*61c4878aSAndroid Build Coastguard WorkerNullifying functions and comparing to null
155*61c4878aSAndroid Build Coastguard Worker==========================================
156*61c4878aSAndroid Build Coastguard Worker``pw::Function`` and ``pw::Callback`` are nullable and can be compared to
157*61c4878aSAndroid Build Coastguard Worker``nullptr``. Invoking a null function triggers a runtime assert.
158*61c4878aSAndroid Build Coastguard Worker
159*61c4878aSAndroid Build Coastguard Worker.. code-block:: c++
160*61c4878aSAndroid Build Coastguard Worker
161*61c4878aSAndroid Build Coastguard Worker   // A function initialized without a callable is implicitly null.
162*61c4878aSAndroid Build Coastguard Worker   pw::Function<void()> null_function;
163*61c4878aSAndroid Build Coastguard Worker
164*61c4878aSAndroid Build Coastguard Worker   // Null functions may also be explicitly created or set.
165*61c4878aSAndroid Build Coastguard Worker   pw::Function<void()> explicit_null_function(nullptr);
166*61c4878aSAndroid Build Coastguard Worker
167*61c4878aSAndroid Build Coastguard Worker   pw::Function<void()> function([]() {});  // Valid (non-null) function.
168*61c4878aSAndroid Build Coastguard Worker   function = nullptr;  // Set to null, clearing the stored callable.
169*61c4878aSAndroid Build Coastguard Worker
170*61c4878aSAndroid Build Coastguard Worker   // Functions are comparable to nullptr.
171*61c4878aSAndroid Build Coastguard Worker   if (function != nullptr) {
172*61c4878aSAndroid Build Coastguard Worker     function();
173*61c4878aSAndroid Build Coastguard Worker   }
174*61c4878aSAndroid Build Coastguard Worker
175*61c4878aSAndroid Build Coastguard Worker``constexpr`` constructors and ``constinit`` expressions
176*61c4878aSAndroid Build Coastguard Worker========================================================
177*61c4878aSAndroid Build Coastguard WorkerThe default constructor for :cpp:type:`pw::Function` is ``constexpr``, so
178*61c4878aSAndroid Build Coastguard Workerdefault-constructed functions may be used in classes with ``constexpr``
179*61c4878aSAndroid Build Coastguard Workerconstructors and in ``constinit`` expressions.
180*61c4878aSAndroid Build Coastguard Worker
181*61c4878aSAndroid Build Coastguard Worker.. code-block:: c++
182*61c4878aSAndroid Build Coastguard Worker
183*61c4878aSAndroid Build Coastguard Worker   class MyClass {
184*61c4878aSAndroid Build Coastguard Worker    public:
185*61c4878aSAndroid Build Coastguard Worker     // Default construction of a pw::Function is constexpr.
186*61c4878aSAndroid Build Coastguard Worker     constexpr MyClass() { ... }
187*61c4878aSAndroid Build Coastguard Worker
188*61c4878aSAndroid Build Coastguard Worker     pw::Function<void(int)> my_function;
189*61c4878aSAndroid Build Coastguard Worker   };
190*61c4878aSAndroid Build Coastguard Worker
191*61c4878aSAndroid Build Coastguard Worker   // pw::Function and classes that use it may be constant initialized.
192*61c4878aSAndroid Build Coastguard Worker   constinit MyClass instance;
193*61c4878aSAndroid Build Coastguard Worker
194*61c4878aSAndroid Build Coastguard Worker``pw::Function`` as a function parameter
195*61c4878aSAndroid Build Coastguard Worker========================================
196*61c4878aSAndroid Build Coastguard WorkerWhen implementing an API which uses callbacks, ``pw::Function`` can be used in
197*61c4878aSAndroid Build Coastguard Workerplace of a function pointer or equivalent callable.
198*61c4878aSAndroid Build Coastguard Worker
199*61c4878aSAndroid Build Coastguard Worker.. code-block:: c++
200*61c4878aSAndroid Build Coastguard Worker
201*61c4878aSAndroid Build Coastguard Worker   // Before:
202*61c4878aSAndroid Build Coastguard Worker   void DoTheThing(int arg, void (*callback)(int result));
203*61c4878aSAndroid Build Coastguard Worker
204*61c4878aSAndroid Build Coastguard Worker   // After:
205*61c4878aSAndroid Build Coastguard Worker   void DoTheThing(int arg, const pw::Function<void(int result)>& callback);
206*61c4878aSAndroid Build Coastguard Worker   // Note the parameter name within the function signature template for clarity.
207*61c4878aSAndroid Build Coastguard Worker
208*61c4878aSAndroid Build Coastguard Worker.. _module-pw_function-move-semantics:
209*61c4878aSAndroid Build Coastguard Worker
210*61c4878aSAndroid Build Coastguard WorkerMove semantics
211*61c4878aSAndroid Build Coastguard Worker==============
212*61c4878aSAndroid Build Coastguard Worker:cpp:type:`pw::Function` is movable, but not copyable, so APIs must accept
213*61c4878aSAndroid Build Coastguard Worker:cpp:type:`pw::Function` objects either by const reference (``const
214*61c4878aSAndroid Build Coastguard Workerpw::Function<void()>&``) or rvalue reference (``const pw::Function<void()>&&``).
215*61c4878aSAndroid Build Coastguard WorkerIf the :cpp:type:`pw::Function` simply needs to be called, it should be passed
216*61c4878aSAndroid Build Coastguard Workerby const reference. If the :cpp:type:`pw::Function` needs to be stored, it
217*61c4878aSAndroid Build Coastguard Workershould be passed as an rvalue reference and moved into a
218*61c4878aSAndroid Build Coastguard Worker:cpp:type:`pw::Function` variable as appropriate.
219*61c4878aSAndroid Build Coastguard Worker
220*61c4878aSAndroid Build Coastguard Worker.. code-block:: c++
221*61c4878aSAndroid Build Coastguard Worker
222*61c4878aSAndroid Build Coastguard Worker   // This function calls a pw::Function but doesn't store it, so it takes a
223*61c4878aSAndroid Build Coastguard Worker   // const reference.
224*61c4878aSAndroid Build Coastguard Worker   void CallTheCallback(const pw::Function<void(int)>& callback) {
225*61c4878aSAndroid Build Coastguard Worker     callback(123);
226*61c4878aSAndroid Build Coastguard Worker   }
227*61c4878aSAndroid Build Coastguard Worker
228*61c4878aSAndroid Build Coastguard Worker   // This function move-assigns a pw::Function to another variable, so it takes
229*61c4878aSAndroid Build Coastguard Worker   // an rvalue reference.
230*61c4878aSAndroid Build Coastguard Worker   void StoreTheCallback(pw::Function<void(int)>&& callback) {
231*61c4878aSAndroid Build Coastguard Worker     stored_callback_ = std::move(callback);
232*61c4878aSAndroid Build Coastguard Worker   }
233*61c4878aSAndroid Build Coastguard Worker
234*61c4878aSAndroid Build Coastguard Worker.. admonition:: Rules of thumb for passing a :cpp:type:`pw::Function` to a function
235*61c4878aSAndroid Build Coastguard Worker
236*61c4878aSAndroid Build Coastguard Worker   * **Pass by value**: Never.
237*61c4878aSAndroid Build Coastguard Worker     This results in unnecessary :cpp:type:`pw::Function` instances and move
238*61c4878aSAndroid Build Coastguard Worker     operations.
239*61c4878aSAndroid Build Coastguard Worker
240*61c4878aSAndroid Build Coastguard Worker   * **Pass by const reference** (``const pw::Function&``): When the
241*61c4878aSAndroid Build Coastguard Worker     :cpp:type:`pw::Function` is only invoked.
242*61c4878aSAndroid Build Coastguard Worker
243*61c4878aSAndroid Build Coastguard Worker     When a :cpp:type:`pw::Function` is called or inspected, but not moved, take
244*61c4878aSAndroid Build Coastguard Worker     a const reference to avoid copies and support temporaries.
245*61c4878aSAndroid Build Coastguard Worker
246*61c4878aSAndroid Build Coastguard Worker   * **Pass by rvalue reference** (``pw::Function&&``): When the
247*61c4878aSAndroid Build Coastguard Worker     :cpp:type:`pw::Function` is moved.
248*61c4878aSAndroid Build Coastguard Worker
249*61c4878aSAndroid Build Coastguard Worker     When the function takes ownership of the :cpp:type:`pw::Function` object,
250*61c4878aSAndroid Build Coastguard Worker     always use an rvalue reference (``pw::Function<void()>&&``) instead of a
251*61c4878aSAndroid Build Coastguard Worker     mutable lvalue reference (``pw::Function<void()>&``). An rvalue reference
252*61c4878aSAndroid Build Coastguard Worker     forces the caller to ``std::move`` when passing a preexisting
253*61c4878aSAndroid Build Coastguard Worker     :cpp:type:`pw::Function` variable, which makes the transfer of ownership
254*61c4878aSAndroid Build Coastguard Worker     explicit. It is possible to move-assign from an lvalue reference, but this
255*61c4878aSAndroid Build Coastguard Worker     fails to make it obvious to the caller that the object is no longer valid.
256*61c4878aSAndroid Build Coastguard Worker
257*61c4878aSAndroid Build Coastguard Worker   * **Pass by non-const reference** (``pw::Function&``): Rarely, when modifying
258*61c4878aSAndroid Build Coastguard Worker     a variable.
259*61c4878aSAndroid Build Coastguard Worker
260*61c4878aSAndroid Build Coastguard Worker     Non-const references are only necessary when modifying an existing
261*61c4878aSAndroid Build Coastguard Worker     :cpp:type:`pw::Function` variable. Use an rvalue reference instead if the
262*61c4878aSAndroid Build Coastguard Worker     :cpp:type:`pw::Function` is moved into another variable.
263*61c4878aSAndroid Build Coastguard Worker
264*61c4878aSAndroid Build Coastguard WorkerCalling functions that use ``pw::Function``
265*61c4878aSAndroid Build Coastguard Worker===========================================
266*61c4878aSAndroid Build Coastguard WorkerA :cpp:type:`pw::Function` can be implicitly constructed from any callback
267*61c4878aSAndroid Build Coastguard Workerobject. When calling an API that takes a :cpp:type:`pw::Function`, simply pass
268*61c4878aSAndroid Build Coastguard Workerthe callable object.  There is no need to create an intermediate
269*61c4878aSAndroid Build Coastguard Worker:cpp:type:`pw::Function` object.
270*61c4878aSAndroid Build Coastguard Worker
271*61c4878aSAndroid Build Coastguard Worker.. code-block:: c++
272*61c4878aSAndroid Build Coastguard Worker
273*61c4878aSAndroid Build Coastguard Worker   // Implicitly creates a pw::Function from a capturing lambda and calls it.
274*61c4878aSAndroid Build Coastguard Worker   CallTheCallback([this](int result) { result_ = result; });
275*61c4878aSAndroid Build Coastguard Worker
276*61c4878aSAndroid Build Coastguard Worker   // Implicitly creates a pw::Function from a capturing lambda and stores it.
277*61c4878aSAndroid Build Coastguard Worker   StoreTheCallback([this](int result) { result_ = result; });
278*61c4878aSAndroid Build Coastguard Worker
279*61c4878aSAndroid Build Coastguard WorkerWhen working with an existing :cpp:type:`pw::Function` variable, the variable
280*61c4878aSAndroid Build Coastguard Workercan be passed directly to functions that take a const reference. If the function
281*61c4878aSAndroid Build Coastguard Workertakes ownership of the :cpp:type:`pw::Function`, move the
282*61c4878aSAndroid Build Coastguard Worker:cpp:type:`pw::Function` variable at the call site.
283*61c4878aSAndroid Build Coastguard Worker
284*61c4878aSAndroid Build Coastguard Worker.. code-block:: c++
285*61c4878aSAndroid Build Coastguard Worker
286*61c4878aSAndroid Build Coastguard Worker   // Accepts the pw::Function by const reference.
287*61c4878aSAndroid Build Coastguard Worker   CallTheCallback(my_function_);
288*61c4878aSAndroid Build Coastguard Worker
289*61c4878aSAndroid Build Coastguard Worker   // Takes ownership of the pw::Function.
290*61c4878aSAndroid Build Coastguard Worker   void StoreTheCallback(std::move(my_function));
291*61c4878aSAndroid Build Coastguard Worker
292*61c4878aSAndroid Build Coastguard WorkerManaging inline storage size
293*61c4878aSAndroid Build Coastguard Worker============================
294*61c4878aSAndroid Build Coastguard WorkerBy default, ``pw::Function`` stores its callable inline within the object. The
295*61c4878aSAndroid Build Coastguard Workerinline storage size defaults to the size of one pointer, but is configurable
296*61c4878aSAndroid Build Coastguard Workerthrough the build system.
297*61c4878aSAndroid Build Coastguard Worker
298*61c4878aSAndroid Build Coastguard Worker:cpp:type:`pw::InlineFunction` is similar to ``pw::Function``,
299*61c4878aSAndroid Build Coastguard Workerbut is always inlined. That is, even if dynamic allocation is enabled for
300*61c4878aSAndroid Build Coastguard Worker``pw::Function``, ``pw::InlineFunction`` will fail to compile if
301*61c4878aSAndroid Build Coastguard Workerthe callable is larger than the inline storage size.
302*61c4878aSAndroid Build Coastguard Worker
303*61c4878aSAndroid Build Coastguard WorkerAttempting to construct a function from a callable larger than its inline size
304*61c4878aSAndroid Build Coastguard Workeris a compile-time error unless dynamic allocation is enabled.
305*61c4878aSAndroid Build Coastguard Worker
306*61c4878aSAndroid Build Coastguard Worker.. admonition:: Inline storage size
307*61c4878aSAndroid Build Coastguard Worker
308*61c4878aSAndroid Build Coastguard Worker   The default inline size of one pointer is sufficient to store most common
309*61c4878aSAndroid Build Coastguard Worker   callable objects, including function pointers, simple non-capturing and
310*61c4878aSAndroid Build Coastguard Worker   capturing lambdas, and lightweight custom classes.
311*61c4878aSAndroid Build Coastguard Worker
312*61c4878aSAndroid Build Coastguard Worker.. code-block:: c++
313*61c4878aSAndroid Build Coastguard Worker
314*61c4878aSAndroid Build Coastguard Worker   // The lambda is moved into the function's internal storage.
315*61c4878aSAndroid Build Coastguard Worker   pw::Function<int(int, int)> subtract([](int a, int b) { return a - b; });
316*61c4878aSAndroid Build Coastguard Worker
317*61c4878aSAndroid Build Coastguard Worker   // Functions can be also be constructed from custom classes that implement
318*61c4878aSAndroid Build Coastguard Worker   // operator(). This particular object is large (8 ints of space).
319*61c4878aSAndroid Build Coastguard Worker   class MyCallable {
320*61c4878aSAndroid Build Coastguard Worker    public:
321*61c4878aSAndroid Build Coastguard Worker     int operator()(int value);
322*61c4878aSAndroid Build Coastguard Worker
323*61c4878aSAndroid Build Coastguard Worker    private:
324*61c4878aSAndroid Build Coastguard Worker     int data_[8];
325*61c4878aSAndroid Build Coastguard Worker   };
326*61c4878aSAndroid Build Coastguard Worker
327*61c4878aSAndroid Build Coastguard Worker   // Compiler error: sizeof(MyCallable) exceeds function's inline storage size.
328*61c4878aSAndroid Build Coastguard Worker   pw::Function<int(int)> function((MyCallable()));
329*61c4878aSAndroid Build Coastguard Worker
330*61c4878aSAndroid Build Coastguard Worker.. _module-pw_function-dynamic-allocation:
331*61c4878aSAndroid Build Coastguard Worker
332*61c4878aSAndroid Build Coastguard WorkerDynamic allocation
333*61c4878aSAndroid Build Coastguard Worker==================
334*61c4878aSAndroid Build Coastguard WorkerYou can configure the inline allocation size of ``pw::Function`` and whether it
335*61c4878aSAndroid Build Coastguard Workerdynamically allocates, but it applies to all uses of ``pw::Function``.
336*61c4878aSAndroid Build Coastguard Worker
337*61c4878aSAndroid Build Coastguard WorkerAs mentioned in :ref:`module-pw_function-design`, ``pw::Function`` is an alias
338*61c4878aSAndroid Build Coastguard Workerof Fuchsia's ``fit::function``. ``fit::function`` allows you to specify the
339*61c4878aSAndroid Build Coastguard Workerinline (static) allocation size and whether to dynamically allocate if the
340*61c4878aSAndroid Build Coastguard Workercallable target doesn't inline. If you want to use a function class with
341*61c4878aSAndroid Build Coastguard Workerdifferent attributes, you can interact with ``fit::function`` directly but note
342*61c4878aSAndroid Build Coastguard Workerthat the resulting functions may not be interchangeable, i.e. callables for one
343*61c4878aSAndroid Build Coastguard Workermight not fit in the other.
344*61c4878aSAndroid Build Coastguard Worker
345*61c4878aSAndroid Build Coastguard WorkerWhen ``PW_FUNCTION_ENABLE_DYNAMIC_ALLOCATION`` is enabled, a ``pw::Function``
346*61c4878aSAndroid Build Coastguard Workerwill use dynamic allocation to store callables that exceed the inline size.
347*61c4878aSAndroid Build Coastguard WorkerAn :ref:`allocator <module-pw_allocator>` type can be optionally supplied as a
348*61c4878aSAndroid Build Coastguard Workertemplate argument. The default allocator type can also be changed by overriding
349*61c4878aSAndroid Build Coastguard Worker``PW_FUNCTION_DEFAULT_ALLOCATOR_TYPE`` (the ``value_type`` of the allocator
350*61c4878aSAndroid Build Coastguard Workeris irrelevant, since it must support rebinding). When dynamic allocation is
351*61c4878aSAndroid Build Coastguard Workerenabled but a compile-time check for the inlining is still required,
352*61c4878aSAndroid Build Coastguard Worker``pw::InlineFunction`` can be used.
353*61c4878aSAndroid Build Coastguard Worker
354*61c4878aSAndroid Build Coastguard Worker.. warning::
355*61c4878aSAndroid Build Coastguard Worker
356*61c4878aSAndroid Build Coastguard Worker   If ``PW_FUNCTION_ENABLE_DYNAMIC_ALLOCATION`` is enabled then attempts to
357*61c4878aSAndroid Build Coastguard Worker   cast from :cpp:type:`pw::InlineFunction` to a regular
358*61c4878aSAndroid Build Coastguard Worker   :cpp:type:`pw::Function` will **ALWAYS** allocate memory.
359*61c4878aSAndroid Build Coastguard Worker
360*61c4878aSAndroid Build Coastguard Worker.. note::
361*61c4878aSAndroid Build Coastguard Worker
362*61c4878aSAndroid Build Coastguard Worker   When building Pigweed itself for host platforms, we enable dynamic
363*61c4878aSAndroid Build Coastguard Worker   allocation.  This is required for some modules that use ``pw::Function``,
364*61c4878aSAndroid Build Coastguard Worker   like :ref:`module-pw_bluetooth_sapphire`.  But it is *not* the default for
365*61c4878aSAndroid Build Coastguard Worker   downstream projects because it introduces a difference between host and
366*61c4878aSAndroid Build Coastguard Worker   non-host builds. This difference has the potential to cause breakages if
367*61c4878aSAndroid Build Coastguard Worker   code is built for host first, and then later ported to device.
368*61c4878aSAndroid Build Coastguard Worker
369*61c4878aSAndroid Build Coastguard WorkerInvoking ``pw::Function`` from a C-style API
370*61c4878aSAndroid Build Coastguard Worker============================================
371*61c4878aSAndroid Build Coastguard Worker.. _trampoline layers: https://en.wikipedia.org/wiki/Trampoline_(computing)
372*61c4878aSAndroid Build Coastguard Worker
373*61c4878aSAndroid Build Coastguard WorkerOne use case for invoking ``pw_function`` from a C-style API is to automate the
374*61c4878aSAndroid Build Coastguard Workergeneration of `trampoline layers`_. See
375*61c4878aSAndroid Build Coastguard Worker:cpp:type:`pw::function::GetFunctionPointer()`.
376*61c4878aSAndroid Build Coastguard Worker
377*61c4878aSAndroid Build Coastguard Worker.. _module-pw_function-reference:
378*61c4878aSAndroid Build Coastguard Worker
379*61c4878aSAndroid Build Coastguard Worker-------------
380*61c4878aSAndroid Build Coastguard WorkerAPI reference
381*61c4878aSAndroid Build Coastguard Worker-------------
382*61c4878aSAndroid Build Coastguard Worker
383*61c4878aSAndroid Build Coastguard Worker``pw::Function``
384*61c4878aSAndroid Build Coastguard Worker================
385*61c4878aSAndroid Build Coastguard Worker.. doxygentypedef:: pw::Function
386*61c4878aSAndroid Build Coastguard Worker
387*61c4878aSAndroid Build Coastguard Worker``pw::InlineFunction``
388*61c4878aSAndroid Build Coastguard Worker======================
389*61c4878aSAndroid Build Coastguard Worker.. doxygentypedef:: pw::InlineFunction
390*61c4878aSAndroid Build Coastguard Worker
391*61c4878aSAndroid Build Coastguard Worker``pw::Callback``
392*61c4878aSAndroid Build Coastguard Worker================
393*61c4878aSAndroid Build Coastguard Worker.. doxygentypedef:: pw::Callback
394*61c4878aSAndroid Build Coastguard Worker
395*61c4878aSAndroid Build Coastguard Worker``pw::InlineCallback``
396*61c4878aSAndroid Build Coastguard Worker======================
397*61c4878aSAndroid Build Coastguard Worker.. doxygentypedef:: pw::InlineCallback
398*61c4878aSAndroid Build Coastguard Worker
399*61c4878aSAndroid Build Coastguard Worker``pw::bind_member()``
400*61c4878aSAndroid Build Coastguard Worker=====================
401*61c4878aSAndroid Build Coastguard Worker.. doxygenfunction:: pw::bind_member
402*61c4878aSAndroid Build Coastguard Worker
403*61c4878aSAndroid Build Coastguard Worker``pw::function::GetFunctionPointer()``
404*61c4878aSAndroid Build Coastguard Worker======================================
405*61c4878aSAndroid Build Coastguard Worker.. doxygenfile:: pw_function/pointer.h
406*61c4878aSAndroid Build Coastguard Worker   :sections: detaileddescription
407*61c4878aSAndroid Build Coastguard Worker.. doxygenfunction:: GetFunctionPointer()
408*61c4878aSAndroid Build Coastguard Worker.. doxygenfunction:: GetFunctionPointer(const FunctionType&)
409*61c4878aSAndroid Build Coastguard Worker
410*61c4878aSAndroid Build Coastguard Worker``pw::function::GetFunctionPointerContextFirst()``
411*61c4878aSAndroid Build Coastguard Worker==================================================
412*61c4878aSAndroid Build Coastguard Worker.. doxygenfunction:: GetFunctionPointerContextFirst()
413*61c4878aSAndroid Build Coastguard Worker.. doxygenfunction:: GetFunctionPointerContextFirst(const FunctionType&)
414*61c4878aSAndroid Build Coastguard Worker
415*61c4878aSAndroid Build Coastguard Worker``pw::ScopeGuard``
416*61c4878aSAndroid Build Coastguard Worker==================
417*61c4878aSAndroid Build Coastguard Worker.. doxygenclass:: pw::ScopeGuard
418*61c4878aSAndroid Build Coastguard Worker   :members:
419*61c4878aSAndroid Build Coastguard Worker
420*61c4878aSAndroid Build Coastguard Worker.. _module-pw_function-design:
421*61c4878aSAndroid Build Coastguard Worker
422*61c4878aSAndroid Build Coastguard Worker------
423*61c4878aSAndroid Build Coastguard WorkerDesign
424*61c4878aSAndroid Build Coastguard Worker------
425*61c4878aSAndroid Build Coastguard Worker``pw::Function`` is an alias of Fuchsia's ``fit::function_impl`` and
426*61c4878aSAndroid Build Coastguard Worker``pw::Callback`` is an alias of Fuchsia's ``fit::callback_impl``. See the
427*61c4878aSAndroid Build Coastguard Workerfollowing links for more information about Fuchsia's implementations:
428*61c4878aSAndroid Build Coastguard Worker
429*61c4878aSAndroid Build Coastguard Worker* `//third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/function.h <https://cs.opensource.google/pigweed/pigweed/+/main:third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/function.h>`_
430*61c4878aSAndroid Build Coastguard Worker* `fit::function <https://fuchsia.googlesource.com/fuchsia/+/HEAD/sdk/lib/fit/#fit_function>`_
431*61c4878aSAndroid Build Coastguard Worker
432*61c4878aSAndroid Build Coastguard Worker.. _module-pw_function-non-literal:
433*61c4878aSAndroid Build Coastguard Worker
434*61c4878aSAndroid Build Coastguard WorkerWhy ``pw::Function`` is not a literal
435*61c4878aSAndroid Build Coastguard Worker=====================================
436*61c4878aSAndroid Build Coastguard WorkerThe default constructor for ``pw::Function`` is ``constexpr`` but
437*61c4878aSAndroid Build Coastguard Worker``pw::Function`` is not a literal type. Instances can be declared ``constinit``
438*61c4878aSAndroid Build Coastguard Workerbut can't be used in ``constexpr`` contexts. There are a few reasons for this:
439*61c4878aSAndroid Build Coastguard Worker
440*61c4878aSAndroid Build Coastguard Worker* ``pw::Function`` supports wrapping any callable type, and the wrapped type
441*61c4878aSAndroid Build Coastguard Worker  might not be a literal type.
442*61c4878aSAndroid Build Coastguard Worker* ``pw::Function`` stores inline callables in a bytes array, which is not
443*61c4878aSAndroid Build Coastguard Worker  ``constexpr``-friendly.
444*61c4878aSAndroid Build Coastguard Worker* ``pw::Function`` optionally uses dynamic allocation, which doesn't work in
445*61c4878aSAndroid Build Coastguard Worker  ``constexpr`` contexts (at least before C++20).
446*61c4878aSAndroid Build Coastguard Worker
447*61c4878aSAndroid Build Coastguard Worker------------
448*61c4878aSAndroid Build Coastguard WorkerSize reports
449*61c4878aSAndroid Build Coastguard Worker------------
450*61c4878aSAndroid Build Coastguard Worker
451*61c4878aSAndroid Build Coastguard WorkerComparing ``pw::Function`` to a traditional function pointer
452*61c4878aSAndroid Build Coastguard Worker============================================================
453*61c4878aSAndroid Build Coastguard WorkerThe following size report compares an API using a :cpp:type:`pw::Function` to a
454*61c4878aSAndroid Build Coastguard Workertraditional function pointer.
455*61c4878aSAndroid Build Coastguard Worker
456*61c4878aSAndroid Build Coastguard Worker.. include:: function_size
457*61c4878aSAndroid Build Coastguard Worker
458*61c4878aSAndroid Build Coastguard WorkerTypical sizes of various callable types
459*61c4878aSAndroid Build Coastguard Worker=======================================
460*61c4878aSAndroid Build Coastguard WorkerThe table below demonstrates typical sizes of various callable types, which can
461*61c4878aSAndroid Build Coastguard Workerbe used as a reference when sizing external buffers for ``pw::Function``
462*61c4878aSAndroid Build Coastguard Workerobjects.
463*61c4878aSAndroid Build Coastguard Worker
464*61c4878aSAndroid Build Coastguard Worker.. include:: callable_size
465