pw_span#
std::span for C++17
Stable C++17 C++20
Standardized:
pw::span
matches C++20’s std::span as closely as possible.Zero-cost: If
std::span
is available,pw::span
is simply an alias of it.
#include <span>
// With pw::span, a buffer is passed as a single argument.
// No need to handle pointer and size arguments.
bool ProcessBuffer(pw::span<uint8_t> buffer);
bool DoStuff() {
// ...
ProcessBuffer(c_array);
ProcessBuffer(array_object);
ProcessBuffer(pw::span(data_pointer, data_size));
}
pw::span
is a convenient abstraction that wraps a pointer and a
size. It’s especially useful in APIs. Spans support implicit conversions from
C arrays, std::array
, or any STL-style container, such as
std::string_view
.
Get started#
Add @pigweed//pw_span
to the deps
list in your Bazel target:
cc_library("...") {
# ...
deps = [
# ...
"@pigweed//pw_span",
# ...
]
}
This assumes that your Bazel WORKSPACE
has a repository named @pigweed
that points to the upstream Pigweed repository.
Add $dir_pw_span
to the deps
list in your pw_executable()
build target:
pw_executable("...") {
# ...
deps = [
# ...
"$dir_pw_span",
# ...
]
}
Add pw_span
to your pw_add_library
or similar CMake target:
pw_add_library(my_library STATIC
HEADERS
...
PRIVATE_DEPS
# ...
pw_span
# ...
)
There are two ways to use pw_span
from a Zephyr project:
Depend on
pw_span
in your CMake target (see CMake tab). This is Pigweed Team’s suggested approach since it enables precise CMake dependency analysis.Add
CONFIG_PIGWEED_SPAN=y
to the Zephyr project’s configuration, which causespw_span
to become a global dependency and have the includes exposed to all targets. Pigweed team does not recommend this approach, though it is the typical Zephyr solution.
Guides#
Operating on arrays of bytes#
When operating on an array of bytes you typically need pointer and size arguments:
bool ProcessBuffer(char* buffer, size_t buffer_size);
bool DoStuff() {
ProcessBuffer(c_array, sizeof(c_array));
ProcessBuffer(array_object.data(), array_object.size());
ProcessBuffer(data_pointer, data_size);
}
With pw::span
you can pass the buffer as a single argument instead:
#include <span>
// With pw::span, a buffer is passed as a single argument.
// No need to handle pointer and size arguments.
bool ProcessBuffer(pw::span<uint8_t> buffer);
bool DoStuff() {
// ...
ProcessBuffer(c_array);
ProcessBuffer(array_object);
ProcessBuffer(pw::span(data_pointer, data_size));
}
Working with spans of binary data#
Use pw::span<std::byte>
or pw::span<const std::byte>
to represent
spans of binary data. Convert spans to byte spans with pw::as_bytes
or
pw::as_writable_bytes
.
void ProcessData(pw::span<const std::byte> data);
void DoStuff() {
std::array<AnyType, 7> data = { ... };
ProcessData(pw::as_bytes(pw::span(data)));
}
pw_bytes/span.h
provides ByteSpan
and ConstByteSpan
aliases for
these types.
References#
API reference#
See std::span.
The pw::span
API is designed to match the std::span
API.
Configuration options#
The following configurations can be adjusted via compile-time configuration of this module, see the module documentation for more details.
-
PW_SPAN_ENABLE_ASSERTS#
Controls whether
pw_span
includes asserts for detecting disallowed span operations at runtime.For C++20 and later, this replaces
std::span
with the custom implementation inpw_span
to ensure bounds-checking asserts have been enabled.This defaults to disabled because of the significant increase in code size caused by enabling this feature. It’s strongly recommended to enable this in debug and testing builds.