A span is a value type that represents an array of elements of type T. Since it only consists of a pointer to memory with an associated size, it is very light-weight. It is cheap to construct, copy, move and use spans, so that users are encouraged to use it as a pass-by-value parameter. A span does not own the underlying memory, so care must be taken to ensure that a span does not outlive the backing store.
span is somewhat analogous to StringPiece, but with arbitrary element types, allowing mutation if T is non-const.
span is implicitly convertible from C++ arrays, as well as most [1] container-like types that provide a data() and size() method (such as std::vector<T>). A mutable span<T> can also be implicitly converted to an immutable span<const T>.
Consider using a span for functions that take a data pointer and size parameter: it allows the function to still act on an array-like type, while allowing the caller code to be a bit more concise.
For read-only data access pass a span<const T>: the caller can supply either a span<const T> or a span<T>, while the callee will have a read-only view. For read-write access a mutable span<T> is required.
Without span: Read-Only: // std::string HexEncode(const uint8_t* data, size_t size); std::vector<uint8_t> data_buffer = GenerateData(); std::string r = HexEncode(data_buffer.data(), data_buffer.size());
Mutable: // ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt, Args...); char str_buffer[100]; SafeSNPrintf(str_buffer, sizeof(str_buffer), "Pi ~= %lf", 3.14);
With span: Read-Only: // std::string HexEncode(std::span<const uint8_t> data); std::vector<uint8_t> data_buffer = GenerateData(); std::string r = HexEncode(data_buffer);
Mutable: // ssize_t SafeSNPrintf(std::span<char>, const char* fmt, Args...); char str_buffer[100]; SafeSNPrintf(str_buffer, "Pi ~= %lf", 3.14);
Const and pointers can get confusing. Here are vectors of pointers and their corresponding spans:
const std::vector<int*> => std::span<int* const> std::vector<const int*> => std::span<const int*> const std::vector<const int*> => std::span<const int* const>
http://eel.is/c++draft/views contains the latest C++20 draft of std::span. Chromium tries to follow the draft as close as possible. Differences between the draft and the implementation are documented in subsections below.
Differences from [span.cons]:
Furthermore, all constructors and methods are marked noexcept due to the lack of exceptions in Chromium.
Public Member Functions | |
constexpr | span (T *data, size_t size) noexcept |
constexpr | span (std::nullptr_t data, size_t size)=delete |
template<typename = void> | |
constexpr | span (T *begin, T *end) noexcept |
template<size_t N, typename = pw_span_internal::EnableIfSpanCompatibleArray<T (&)[N], T, Extent>> | |
constexpr | span (T(&array)[N]) noexcept |
template<typename U , size_t N, typename = pw_span_internal:: EnableIfSpanCompatibleArray<std::array<U, N>&, T, Extent>> | |
constexpr | span (std::array< U, N > &array) noexcept |
template<typename U , size_t N, typename = pw_span_internal:: EnableIfSpanCompatibleArray<const std::array<U, N>&, T, Extent>> | |
constexpr | span (const std::array< U, N > &array) noexcept |
template<typename Container , typename = pw_span_internal:: EnableIfSpanCompatibleContainerAndSpanIsDynamic<Container&, T, Extent>> | |
constexpr | span (Container &container) noexcept |
template<typename Container , typename = pw_span_internal:: EnableIfSpanCompatibleContainerAndSpanIsDynamic<const Container&, T, Extent>> | |
constexpr | span (const Container &container) noexcept |
constexpr | span (const span &other) noexcept=default |
template<typename U , size_t OtherExtent, typename = pw_span_internal:: EnableIfLegalSpanConversion<U, OtherExtent, T, Extent>> | |
constexpr | span (const span< U, OtherExtent > &other) |
constexpr span & | operator= (const span &other) noexcept=default |
template<size_t Count> | |
constexpr span< T, Count > | first () const noexcept |
template<size_t Count> | |
constexpr span< T, Count > | last () const noexcept |
template<size_t Offset, size_t Count = dynamic_extent> | |
constexpr span< T,(Count !=dynamic_extent ? Count :(Extent !=dynamic_extent ? Extent - Offset :dynamic_extent))> | subspan () const noexcept |
constexpr span< T, dynamic_extent > | first (size_t count) const noexcept |
constexpr span< T, dynamic_extent > | last (size_t count) const noexcept |
constexpr span< T, dynamic_extent > | subspan (size_t offset, size_t count=dynamic_extent) const noexcept |
constexpr size_t | size () const noexcept |
constexpr size_t | size_bytes () const noexcept |
constexpr bool | empty () const noexcept |
constexpr T & | operator[] (size_t idx) const noexcept |
constexpr T & | front () const noexcept |
constexpr T & | back () const noexcept |
constexpr T * | data () const noexcept |
constexpr iterator | begin () const noexcept |
constexpr iterator | end () const noexcept |
constexpr reverse_iterator | rbegin () const noexcept |
constexpr reverse_iterator | rend () const noexcept |
![]() | |
constexpr | ExtentStorage (size_t) noexcept |
constexpr size_t | size () const noexcept |
Static Public Attributes | |
static constexpr size_t | extent = Extent |