span_with_nul_from_cstring_view
support for cstring_view
This CL adds a variant to `span_with_nul_from_cstring_view` that supports `basic_cstring_view<T>`. This will dispense of unsafe buffers for usecases where a span instance for a `cstring_view` is needed to preserve the null-terminator. Bug: 364987728 Change-Id: Ic3dbc89c99af68ece054e0c728d2fd87a725fb32 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6063316 Reviewed-by: Peter Kasting <pkasting@chromium.org> Commit-Queue: Claudio DeSouza <cdesouza@chromium.org> Cr-Commit-Position: refs/heads/main@{#1391410}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
5f9894b05b
commit
a9844a51e5
base/containers
@ -28,6 +28,7 @@
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/containers/checked_iterators.h"
|
||||
#include "base/numerics/safe_conversions.h"
|
||||
#include "base/strings/cstring_view.h"
|
||||
#include "base/types/to_address.h"
|
||||
|
||||
// A span is a view of contiguous elements that can be accessed like an array,
|
||||
@ -230,6 +231,8 @@
|
||||
// (non-range) objects to spans.
|
||||
// - For convenience, provides `[byte_]span_[with_nul_]from_cstring()` to
|
||||
// convert `const char[]` literals to spans.
|
||||
// - For convenience, provides `[byte_]span_with_nul_from_cstring_view()` to
|
||||
// convert `basic_cstring_view<T>` to spans, preserving the null terminator.
|
||||
// - For convenience, provides `as_[writable_]byte_span()` to convert
|
||||
// spanifiable objects directly to byte spans.
|
||||
|
||||
@ -1451,6 +1454,17 @@ constexpr auto span_with_nul_from_cstring(
|
||||
return span(str);
|
||||
}
|
||||
|
||||
// Converts a `basic_cstring_view` instance to a `span<const CharT>`, preserving
|
||||
// the trailing '\0'.
|
||||
//
|
||||
// (Not in `std::`; explicitly includes the trailing nul, which would be omitted
|
||||
// by calling the range constructor.)
|
||||
template <typename CharT>
|
||||
constexpr auto span_with_nul_from_cstring_view(basic_cstring_view<CharT> str) {
|
||||
// SAFETY: It is safe to read the guaranteed null-terminator in `str`.
|
||||
return UNSAFE_BUFFERS(span(str.data(), str.size() + 1));
|
||||
}
|
||||
|
||||
// Like `span_from_cstring()`, but returns a byte span.
|
||||
//
|
||||
// (Not in `std::`.)
|
||||
@ -1478,6 +1492,15 @@ constexpr auto byte_span_with_nul_from_cstring(
|
||||
return as_bytes(span(str));
|
||||
}
|
||||
|
||||
// Like `span_with_nul_from_cstring_view()`, but returns a byte span.
|
||||
//
|
||||
// (Not in `std::`.)
|
||||
template <typename CharT>
|
||||
constexpr auto byte_span_with_nul_from_cstring_view(
|
||||
basic_cstring_view<CharT> str) {
|
||||
return as_bytes(span_with_nul_from_cstring_view(str));
|
||||
}
|
||||
|
||||
// Converts an object which can already explicitly convert to some kind of span
|
||||
// directly into a byte span.
|
||||
//
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "base/memory/raw_span.h"
|
||||
#include "base/numerics/byte_conversions.h"
|
||||
#include "base/ranges/algorithm.h"
|
||||
#include "base/strings/cstring_view.h"
|
||||
#include "base/strings/utf_ostream_operators.h"
|
||||
#include "base/test/gtest_util.h"
|
||||
#include "testing/gmock/include/gmock/gmock.h"
|
||||
@ -706,7 +707,16 @@ TEST(SpanTest, FromCString) {
|
||||
EXPECT_EQ(s[4u], 'o');
|
||||
EXPECT_EQ(s.size(), 5u);
|
||||
}
|
||||
// Includes the terminating null, size known at compile time.
|
||||
// No terminating null, size not known at compile time. cstring_view loses
|
||||
// the size, and the null-terminator.
|
||||
{
|
||||
auto s = span(base::cstring_view("hello"));
|
||||
static_assert(std::same_as<decltype(s), span<const char>>);
|
||||
EXPECT_EQ(s[0u], 'h');
|
||||
EXPECT_EQ(s[1u], 'e');
|
||||
EXPECT_EQ(s[4u], 'o');
|
||||
EXPECT_EQ(s.size(), 5u);
|
||||
} // Includes the terminating null, size known at compile time.
|
||||
{
|
||||
auto s = span_with_nul_from_cstring("hello");
|
||||
static_assert(std::same_as<decltype(s), span<const char, 6u>>);
|
||||
@ -716,6 +726,17 @@ TEST(SpanTest, FromCString) {
|
||||
EXPECT_EQ(s[5u], '\0');
|
||||
}
|
||||
|
||||
// Includes the terminating null, from a basic_cstring_view.
|
||||
{
|
||||
cstring_view str = "hello";
|
||||
auto s = span_with_nul_from_cstring_view(str);
|
||||
static_assert(std::same_as<decltype(s), span<const char>>);
|
||||
EXPECT_EQ(s[0u], 'h');
|
||||
EXPECT_EQ(s[1u], 'e');
|
||||
EXPECT_EQ(s[4u], 'o');
|
||||
EXPECT_EQ(s[5u], '\0');
|
||||
}
|
||||
|
||||
// No terminating null, size known at compile time. Converted to a span of
|
||||
// uint8_t bytes.
|
||||
{
|
||||
@ -735,6 +756,17 @@ TEST(SpanTest, FromCString) {
|
||||
EXPECT_EQ(s[4u], 'o');
|
||||
EXPECT_EQ(s[5u], '\0');
|
||||
}
|
||||
// Includes the terminating null, from a basic_cstring_view. Converted to a
|
||||
// span of uint8_t bytes.
|
||||
{
|
||||
cstring_view str = "hello";
|
||||
auto s = byte_span_with_nul_from_cstring_view(str);
|
||||
static_assert(std::same_as<decltype(s), span<const uint8_t>>);
|
||||
EXPECT_EQ(s[0u], 'h');
|
||||
EXPECT_EQ(s[1u], 'e');
|
||||
EXPECT_EQ(s[4u], 'o');
|
||||
EXPECT_EQ(s[5u], '\0');
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SpanTest, FromCStringEmpty) {
|
||||
|
Reference in New Issue
Block a user