aboutsummaryrefslogtreecommitdiff
path: root/pw_function/docs.rst
diff options
context:
space:
mode:
Diffstat (limited to 'pw_function/docs.rst')
-rw-r--r--pw_function/docs.rst179
1 files changed, 103 insertions, 76 deletions
diff --git a/pw_function/docs.rst b/pw_function/docs.rst
index 18041ef51..b8d9b7ed8 100644
--- a/pw_function/docs.rst
+++ b/pw_function/docs.rst
@@ -23,36 +23,36 @@ the stored callable.
.. code-block:: c++
- int Add(int a, int b) { return a + b; }
+ int Add(int a, int b) { return a + b; }
- // Construct a Function object from a function pointer.
- pw::Function<int(int, int)> add_function(Add);
+ // Construct a Function object from a function pointer.
+ pw::Function<int(int, int)> add_function(Add);
- // Invoke the function object.
- int result = add_function(3, 5);
- EXPECT_EQ(result, 8);
+ // Invoke the function object.
+ int result = add_function(3, 5);
+ EXPECT_EQ(result, 8);
- // Construct a function from a lambda.
- pw::Function<int(int)> negate([](int value) { return -value; });
- EXPECT_EQ(negate(27), -27);
+ // Construct a function from a lambda.
+ pw::Function<int(int)> negate([](int value) { return -value; });
+ EXPECT_EQ(negate(27), -27);
Functions are nullable. Invoking a null function triggers a runtime assert.
.. code-block:: c++
- // A function initialized without a callable is implicitly null.
- pw::Function<void()> null_function;
+ // A function initialized without a callable is implicitly null.
+ pw::Function<void()> null_function;
- // Null functions may also be explicitly created or set.
- pw::Function<void()> explicit_null_function(nullptr);
+ // Null functions may also be explicitly created or set.
+ pw::Function<void()> explicit_null_function(nullptr);
- pw::Function<void()> function([]() {}); // Valid (non-null) function.
- function = nullptr; // Set to null, clearing the stored callable.
+ pw::Function<void()> function([]() {}); // Valid (non-null) function.
+ function = nullptr; // Set to null, clearing the stored callable.
- // Functions are comparable to nullptr.
- if (function != nullptr) {
- function();
- }
+ // Functions are comparable to nullptr.
+ if (function != nullptr) {
+ function();
+ }
:cpp:type:`pw::Function`'s default constructor is ``constexpr``, so
default-constructed functions may be used in classes with ``constexpr``
@@ -60,23 +60,22 @@ constructors and in ``constinit`` expressions.
.. code-block:: c++
- class MyClass {
- public:
- // Default construction of a pw::Function is constexpr.
- constexpr MyClass() { ... }
+ class MyClass {
+ public:
+ // Default construction of a pw::Function is constexpr.
+ constexpr MyClass() { ... }
- pw::Function<void(int)> my_function;
- };
+ pw::Function<void(int)> my_function;
+ };
- // pw::Function and classes that use it may be constant initialized.
- constinit MyClass instance;
+ // pw::Function and classes that use it may be constant initialized.
+ constinit MyClass instance;
Storage
=======
By default, a ``Function`` stores its callable inline within the object. The
-inline storage size defaults to the size of two pointers, but is configurable
-through the build system. The size of a ``Function`` object is equivalent to its
-inline storage size.
+inline storage size defaults to the size of one pointer, but is configurable
+through the build system.
The :cpp:type:`pw::InlineFunction` alias is similar to :cpp:type:`pw::Function`,
but is always inlined. That is, even if dynamic allocation is enabled for
@@ -88,36 +87,41 @@ is a compile-time error unless dynamic allocation is enabled.
.. admonition:: Inline storage size
- The default inline size of two pointers is sufficient to store most common
- callable objects, including function pointers, simple non-capturing and
- capturing lambdas, and lightweight custom classes.
+ The default inline size of one pointer is sufficient to store most common
+ callable objects, including function pointers, simple non-capturing and
+ capturing lambdas, and lightweight custom classes.
.. code-block:: c++
- // The lambda is moved into the function's internal storage.
- pw::Function<int(int, int)> subtract([](int a, int b) { return a - b; });
+ // The lambda is moved into the function's internal storage.
+ pw::Function<int(int, int)> subtract([](int a, int b) { return a - b; });
- // Functions can be also be constructed from custom classes that implement
- // operator(). This particular object is large (8 ints of space).
- class MyCallable {
- public:
- int operator()(int value);
+ // Functions can be also be constructed from custom classes that implement
+ // operator(). This particular object is large (8 ints of space).
+ class MyCallable {
+ public:
+ int operator()(int value);
- private:
- int data_[8];
- };
+ private:
+ int data_[8];
+ };
- // Compiler error: sizeof(MyCallable) exceeds function's inline storage size.
- pw::Function<int(int)> function((MyCallable()));
+ // Compiler error: sizeof(MyCallable) exceeds function's inline storage size.
+ pw::Function<int(int)> function((MyCallable()));
.. admonition:: Dynamic allocation
- When ``PW_FUNCTION_ENABLE_DYNAMIC_ALLOCATION`` is enabled, a ``Function``
- will use dynamic allocation to store callables that exceed the inline size.
- When it is enabled but a compile-time check for the inlining is still required
- ``pw::InlineFunction`` can be used.
+ When ``PW_FUNCTION_ENABLE_DYNAMIC_ALLOCATION`` is enabled, a ``Function``
+ will use dynamic allocation to store callables that exceed the inline size.
+ An Allocator type can be optionally supplied as a template argument. The
+ default Allocator type can also be changed by overriding
+ ``PW_FUNCTION_DEFAULT_ALLOCATOR_TYPE`` (the ``value_type`` of the Allocator
+ is irrelevant, since it must support rebinding). When dynamic allocation is
+ enabled but a compile-time check for the inlining is still required
+ ``pw::InlineFunction`` can be used.
.. warning::
+
If ``PW_FUNCTION_ENABLE_DYNAMIC_ALLOCATION`` is enabled then attempts to cast
from `:cpp:type:`pw::InlineFunction` to a regular :cpp:type:`pw::Function`
will **ALWAYS** allocate memory.
@@ -132,6 +136,7 @@ Reference
.. doxygentypedef:: pw::InlineFunction
.. doxygentypedef:: pw::Callback
.. doxygentypedef:: pw::InlineCallback
+.. doxygenfunction:: pw::bind_member
``pw::Function`` as a function parameter
========================================
@@ -140,12 +145,12 @@ place of a function pointer or equivalent callable.
.. code-block:: c++
- // Before:
- void DoTheThing(int arg, void (*callback)(int result));
+ // Before:
+ void DoTheThing(int arg, void (*callback)(int result));
- // After. Note that it is possible to have parameter names within the function
- // signature template for clarity.
- void DoTheThing(int arg, const pw::Function<void(int result)>& callback);
+ // After. Note that it is possible to have parameter names within the function
+ // signature template for clarity.
+ void DoTheThing(int arg, const pw::Function<void(int result)>& callback);
:cpp:type:`pw::Function` is movable, but not copyable, so APIs must accept
:cpp:type:`pw::Function` objects either by const reference (``const
@@ -157,29 +162,30 @@ should be passed as an rvalue reference and moved into a
.. code-block:: c++
- // This function calls a pw::Function but doesn't store it, so it takes a
- // const reference.
- void CallTheCallback(const pw::Function<void(int)>& callback) {
- callback(123);
- }
+ // This function calls a pw::Function but doesn't store it, so it takes a
+ // const reference.
+ void CallTheCallback(const pw::Function<void(int)>& callback) {
+ callback(123);
+ }
- // This function move-assigns a pw::Function to another variable, so it takes
- // an rvalue reference.
- void StoreTheCallback(pw::Function<void(int)>&& callback) {
- stored_callback_ = std::move(callback);
- }
+ // This function move-assigns a pw::Function to another variable, so it takes
+ // an rvalue reference.
+ void StoreTheCallback(pw::Function<void(int)>&& callback) {
+ stored_callback_ = std::move(callback);
+ }
.. admonition:: Rules of thumb for passing a :cpp:type:`pw::Function` to a function
* **Pass by value**: Never.
-
This results in unnecessary :cpp:type:`pw::Function` instances and move
operations.
+
* **Pass by const reference** (``const pw::Function&``): When the
:cpp:type:`pw::Function` is only invoked.
When a :cpp:type:`pw::Function` is called or inspected, but not moved, take
a const reference to avoid copies and support temporaries.
+
* **Pass by rvalue reference** (``pw::Function&&``): When the
:cpp:type:`pw::Function` is moved.
@@ -190,6 +196,7 @@ should be passed as an rvalue reference and moved into a
:cpp:type:`pw::Function` variable, which makes the transfer of ownership
explicit. It is possible to move-assign from an lvalue reference, but this
fails to make it obvious to the caller that the object is no longer valid.
+
* **Pass by non-const reference** (``pw::Function&``): Rarely, when modifying
a variable.
@@ -206,11 +213,11 @@ the callable object. There is no need to create an intermediate
.. code-block:: c++
- // Implicitly creates a pw::Function from a capturing lambda and calls it.
- CallTheCallback([this](int result) { result_ = result; });
+ // Implicitly creates a pw::Function from a capturing lambda and calls it.
+ CallTheCallback([this](int result) { result_ = result; });
- // Implicitly creates a pw::Function from a capturing lambda and stores it.
- StoreTheCallback([this](int result) { result_ = result; });
+ // Implicitly creates a pw::Function from a capturing lambda and stores it.
+ StoreTheCallback([this](int result) { result_ = result; });
When working with an existing :cpp:type:`pw::Function` variable, the variable
can be passed directly to functions that take a const reference. If the function
@@ -219,11 +226,11 @@ takes ownership of the :cpp:type:`pw::Function`, move the
.. code-block:: c++
- // Accepts the pw::Function by const reference.
- CallTheCallback(my_function_);
+ // Accepts the pw::Function by const reference.
+ CallTheCallback(my_function_);
- // Takes ownership of the pw::Function.
- void StoreTheCallback(std::move(my_function));
+ // Takes ownership of the pw::Function.
+ void StoreTheCallback(std::move(my_function));
``pw::Callback`` for one-shot functions
=======================================
@@ -235,6 +242,11 @@ nullptr.
Invoking ``pw::Function`` from a C-style API
============================================
+.. _trampoline layers: https://en.wikipedia.org/wiki/Trampoline_(computing)
+
+One use case for invoking ``pw_function`` from a C-style API is to automate
+the generation of `trampoline layers`_.
+
.. doxygenfile:: pw_function/pointer.h
:sections: detaileddescription
@@ -247,7 +259,7 @@ Invoking ``pw::Function`` from a C-style API
ScopeGuard
----------
.. doxygenclass:: pw::ScopeGuard
- :members:
+ :members:
------------
Size reports
@@ -271,10 +283,25 @@ be used as a reference when sizing external buffers for ``Function`` objects.
Design
------
:cpp:type:`pw::Function` is an alias of
-`fit::function <https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/lib/fit/include/lib/fit/function.h;drc=f66f54fca0c11a1168d790bcc3d8a5a3d940218d>`_.
+`fit::function_impl <https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/lib/fit/include/lib/fit/function.h>`_.
:cpp:type:`pw::Callback` is an alias of
-`fit::callback <https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/lib/fit/include/lib/fit/function.h;drc=f66f54fca0c11a1168d790bcc3d8a5a3d940218d>`_.
+`fit::callback_impl <https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/lib/fit/include/lib/fit/function.h>`_.
+
+.. _module-pw_function-non-literal:
+
+Why pw::Function is not a literal
+=================================
+The default constructor for ``pw::Function`` is ``constexpr`` but
+``pw::Function`` is not a literal type. Instances can be declared ``constinit``
+but can't be used in ``constexpr`` contexts. There are a few reasons for this:
+
+* ``pw::Function`` supports wrapping any callable type, and the wrapped type
+ might not be a literal type.
+* ``pw::Function`` stores inline callables in a bytes array, which is not
+ ``constexpr``-friendly.
+* ``pw::Function`` optionally uses dynamic allocation, which doesn't work in
+ ``constexpr`` contexts (at least before C++20).
------
Zephyr