Daily bit(e) of C++ | std::span
1 min readFeb 23, 2023
--
Daily bit(e) of C++ #53, The C++20 contiguous range view std::span
When interacting with legacy code or C APIs, passing data around as C arrays might be unavoidable. This brings with it the potential for errors.
C++20 introduced std::span
, a view that can wrap a contiguous memory block and provides a contiguous range interface.
We can use a std::span
to bridge the C and C++ code and to access the underlying byte representation.
#include <cstdint>
#include <span>
#include <vector>
#include <ranges>
char buffer[16];
auto view = std::span(buffer);
// Call C API using a wrapped buffer
size_t cnt = read(view.data(), view.size());
// Process a sub-view based on the number of actually read bytes
for (auto v : view.subspan(0, cnt)) {}
char* buff;
size_t length;
int ret = get_data(&buff, &length);
if (ret != 0) { return ret; }
// Wrap a C buffer into a std::span
auto buffer_view = std::span(buff, length);
// std::span works as any other range, e.g. reverse iteration:
for (auto it = buffer_view.rbegin(); it != buffer_view.rend(); ++it) {}
// or combining with views:
for (auto v : buffer_view | std::views::drop(16)) {}
std::vector<Data> data{{2,3},{1,5},{4,4}};
// Acces the underlying representation:
std::span<std::byte> bytes = std::as_writable_bytes(std::span(data));