Wyatt Hepler | f9fb90f | 2020-09-30 18:59:33 -0700 | [diff] [blame] | 1 | .. _module-pw_span: |
Wyatt Hepler | ee3e02f | 2019-12-05 10:52:31 -0800 | [diff] [blame] | 2 | |
| 3 | ------- |
| 4 | pw_span |
| 5 | ------- |
Armando Montanez | 0054a9b | 2020-03-13 13:06:24 -0700 | [diff] [blame] | 6 | The ``pw_span`` module provides an implementation of C++20's |
Wyatt Hepler | ee3e02f | 2019-12-05 10:52:31 -0800 | [diff] [blame] | 7 | `std::span <https://en.cppreference.com/w/cpp/container/span>`_, which is a |
Wyatt Hepler | 69a5190 | 2020-06-22 10:42:53 -0700 | [diff] [blame] | 8 | non-owning view of an array of values. The intent is for this implementation of |
| 9 | ``std::span`` is to exactly match the C++20 standard. |
Wyatt Hepler | ee3e02f | 2019-12-05 10:52:31 -0800 | [diff] [blame] | 10 | |
Wyatt Hepler | 9f39234 | 2020-07-08 10:11:33 -0700 | [diff] [blame] | 11 | The only header provided by the ``pw_span`` module is ``<span>``. It is included |
| 12 | as if it were coming from the C++ Standard Library. If the C++ library provides |
| 13 | ``<span>``, the library's version of ``std::span`` is used in place of |
Wyatt Hepler | 69a5190 | 2020-06-22 10:42:53 -0700 | [diff] [blame] | 14 | ``pw_span``'s. |
| 15 | |
| 16 | ``pw_span`` requires two include paths -- ``public/`` and ``public_overrides/``. |
| 17 | The internal implementation header is in ``public/``, and the ``<span>`` header |
| 18 | that mimics the C++ Standard Library is in ``public_overrides/``. |
| 19 | |
Wyatt Hepler | 69a5190 | 2020-06-22 10:42:53 -0700 | [diff] [blame] | 20 | Using std::span |
| 21 | =============== |
| 22 | ``std::span`` is a convenient abstraction that wraps a pointer and a size. |
| 23 | ``std::span`` is especially useful in APIs. Spans support implicit conversions |
Alexei Frolov | 44d5473 | 2020-01-10 14:45:43 -0800 | [diff] [blame] | 24 | from C arrays, ``std::array``, or any STL-style container, such as |
Wyatt Hepler | ee3e02f | 2019-12-05 10:52:31 -0800 | [diff] [blame] | 25 | ``std::string_view``. |
| 26 | |
| 27 | Functions operating on an array of bytes typically accept pointer and size |
| 28 | arguments: |
| 29 | |
| 30 | .. code-block:: cpp |
| 31 | |
| 32 | bool ProcessBuffer(char* buffer, size_t buffer_size); |
| 33 | |
| 34 | bool DoStuff() { |
| 35 | ProcessBuffer(c_array, sizeof(c_array)); |
| 36 | ProcessBuffer(array_object.data(), array_object.size()); |
| 37 | ProcessBuffer(data_pointer, data_size); |
| 38 | } |
| 39 | |
Wyatt Hepler | 69a5190 | 2020-06-22 10:42:53 -0700 | [diff] [blame] | 40 | Pointer and size arguments can be replaced with a ``std::span``: |
Wyatt Hepler | ee3e02f | 2019-12-05 10:52:31 -0800 | [diff] [blame] | 41 | |
| 42 | .. code-block:: cpp |
| 43 | |
Wyatt Hepler | 69a5190 | 2020-06-22 10:42:53 -0700 | [diff] [blame] | 44 | #include <span> |
| 45 | |
| 46 | // With std::span, the buffer is passed as a single argument. |
| 47 | bool ProcessBuffer(std::span<uint8_t> buffer); |
Wyatt Hepler | ee3e02f | 2019-12-05 10:52:31 -0800 | [diff] [blame] | 48 | |
| 49 | bool DoStuff() { |
| 50 | ProcessBuffer(c_array); |
| 51 | ProcessBuffer(array_object); |
Wyatt Hepler | 69a5190 | 2020-06-22 10:42:53 -0700 | [diff] [blame] | 52 | ProcessBuffer(std::span(data_pointer, data_size)); |
Wyatt Hepler | ee3e02f | 2019-12-05 10:52:31 -0800 | [diff] [blame] | 53 | } |
| 54 | |
| 55 | .. tip:: |
Wyatt Hepler | 69a5190 | 2020-06-22 10:42:53 -0700 | [diff] [blame] | 56 | Use ``std::span<std::byte>`` or ``std::span<const std::byte>`` to represent |
| 57 | spans of binary data. Use ``std::as_bytes`` or ``std::as_writeable_bytes`` |
Wyatt Hepler | 867d42d | 2019-12-09 18:54:31 -0800 | [diff] [blame] | 58 | to convert any span to a byte span. |
Wyatt Hepler | ee3e02f | 2019-12-05 10:52:31 -0800 | [diff] [blame] | 59 | |
| 60 | .. code-block:: cpp |
| 61 | |
Wyatt Hepler | 69a5190 | 2020-06-22 10:42:53 -0700 | [diff] [blame] | 62 | void ProcessData(std::span<const std::byte> data); |
Wyatt Hepler | ee3e02f | 2019-12-05 10:52:31 -0800 | [diff] [blame] | 63 | |
| 64 | void DoStuff() { |
| 65 | std::array<AnyType, 7> data = { ... }; |
Wyatt Hepler | 69a5190 | 2020-06-22 10:42:53 -0700 | [diff] [blame] | 66 | ProcessData(std::as_bytes(std::span(data))); |
Wyatt Hepler | ee3e02f | 2019-12-05 10:52:31 -0800 | [diff] [blame] | 67 | } |
| 68 | |
| 69 | Compatibility |
| 70 | ============= |
Wyatt Hepler | 0132da5 | 2021-10-11 16:20:11 -0700 | [diff] [blame] | 71 | Works with C++14, but some features require C++17. |
Yuval Peress | b8f3ad2 | 2021-10-26 22:55:27 -0600 | [diff] [blame] | 72 | |
| 73 | Zephyr |
| 74 | ====== |
| 75 | To enable ``pw_span`` for Zephyr add ``CONFIG_PIGWEED_SPAN=y`` to the project's |
| 76 | configuration. |