make_span overloads for pointer to vector (#7374) (#7435)

* make_span overloads for pointer to vector (#7374)

* findings from the review

Co-authored-by: Derek Bailey <derekbailey@google.com>
This commit is contained in:
Stefan F
2022-08-14 21:21:55 +02:00
committed by GitHub
parent fa1174aa7b
commit 3cc2daa78f
2 changed files with 90 additions and 0 deletions

View File

@@ -327,6 +327,24 @@ FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const uint8_t> make_bytes_span(
return span<const uint8_t>(vec.Data(), vec.size() * sizeof(U)); return span<const uint8_t>(vec.Data(), vec.size() * sizeof(U));
} }
// Convenient helper functions to get a span of any vector, regardless
// of whether it is null or not (the field is not set).
template<class U>
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U> make_span(Vector<U> *ptr)
FLATBUFFERS_NOEXCEPT {
static_assert(Vector<U>::is_span_observable,
"wrong type U, only LE-scalar, or byte types are allowed");
return ptr ? make_span(*ptr) : span<U>();
}
template<class U>
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const U> make_span(
const Vector<U> *ptr) FLATBUFFERS_NOEXCEPT {
static_assert(Vector<U>::is_span_observable,
"wrong type U, only LE-scalar, or byte types are allowed");
return ptr ? make_span(*ptr) : span<const U>();
}
// Represent a vector much like the template above, but in this case we // Represent a vector much like the template above, but in this case we
// don't know what the element types are (used with reflection.h). // don't know what the element types are (used with reflection.h).
class VectorOfAny { class VectorOfAny {

View File

@@ -4572,6 +4572,77 @@ void JsonUnsortedArrayTest()
TEST_NOTNULL(monster->testarrayoftables()->LookupByKey("ccc")); TEST_NOTNULL(monster->testarrayoftables()->LookupByKey("ccc"));
} }
void VectorSpanTest() {
flatbuffers::FlatBufferBuilder builder;
auto mloc =
CreateMonster(builder, nullptr, 0, 0, builder.CreateString("Monster"),
builder.CreateVector<uint8_t>({ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }));
FinishMonsterBuffer(builder, mloc);
auto monster = GetMonster(builder.GetBufferPointer());
auto mutable_monster = GetMutableMonster(builder.GetBufferPointer());
{ // using references
TEST_NOTNULL(monster->inventory());
flatbuffers::span<const uint8_t> const_inventory =
flatbuffers::make_span(*monster->inventory());
TEST_EQ(const_inventory.size(), 10);
TEST_EQ(const_inventory[0], 0);
TEST_EQ(const_inventory[9], 9);
flatbuffers::span<uint8_t> mutable_inventory =
flatbuffers::make_span(*mutable_monster->mutable_inventory());
TEST_EQ(mutable_inventory.size(), 10);
TEST_EQ(mutable_inventory[0], 0);
TEST_EQ(mutable_inventory[9], 9);
mutable_inventory[0] = 42;
TEST_EQ(mutable_inventory[0], 42);
mutable_inventory[0] = 0;
TEST_EQ(mutable_inventory[0], 0);
}
{ // using pointers
TEST_EQ(flatbuffers::VectorLength(monster->inventory()), 10);
flatbuffers::span<const uint8_t> const_inventory =
flatbuffers::make_span(monster->inventory());
TEST_EQ(const_inventory.size(), 10);
TEST_EQ(const_inventory[0], 0);
TEST_EQ(const_inventory[9], 9);
flatbuffers::span<uint8_t> mutable_inventory =
flatbuffers::make_span(mutable_monster->mutable_inventory());
TEST_EQ(mutable_inventory.size(), 10);
TEST_EQ(mutable_inventory[0], 0);
TEST_EQ(mutable_inventory[9], 9);
mutable_inventory[0] = 42;
TEST_EQ(mutable_inventory[0], 42);
mutable_inventory[0] = 0;
TEST_EQ(mutable_inventory[0], 0);
}
{
TEST_ASSERT(nullptr == monster->testnestedflatbuffer());
TEST_EQ(flatbuffers::VectorLength(monster->testnestedflatbuffer()), 0);
flatbuffers::span<const uint8_t> const_nested =
flatbuffers::make_span(monster->testnestedflatbuffer());
TEST_ASSERT(const_nested.empty());
flatbuffers::span<uint8_t> mutable_nested =
flatbuffers::make_span(mutable_monster->mutable_testnestedflatbuffer());
TEST_ASSERT(mutable_nested.empty());
}
}
int FlatBufferTests() { int FlatBufferTests() {
// clang-format off // clang-format off
@@ -4678,6 +4749,7 @@ int FlatBufferTests() {
NestedVerifierTest(); NestedVerifierTest();
PrivateAnnotationsLeaks(); PrivateAnnotationsLeaks();
JsonUnsortedArrayTest(); JsonUnsortedArrayTest();
VectorSpanTest();
return 0; return 0;
} }