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