From 3cc2daa78f6d8ea7edfd64482626b3549df1339d Mon Sep 17 00:00:00 2001 From: Stefan F <32997632+stefan301@users.noreply.github.com> Date: Sun, 14 Aug 2022 21:21:55 +0200 Subject: [PATCH] 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 --- include/flatbuffers/vector.h | 18 +++++++++ tests/test.cpp | 72 ++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/include/flatbuffers/vector.h b/include/flatbuffers/vector.h index c227ddd7a..6bcdfe263 100644 --- a/include/flatbuffers/vector.h +++ b/include/flatbuffers/vector.h @@ -327,6 +327,24 @@ FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span make_bytes_span( return span(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 +FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span make_span(Vector *ptr) + FLATBUFFERS_NOEXCEPT { + static_assert(Vector::is_span_observable, + "wrong type U, only LE-scalar, or byte types are allowed"); + return ptr ? make_span(*ptr) : span(); +} + +template +FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span make_span( + const Vector *ptr) FLATBUFFERS_NOEXCEPT { + static_assert(Vector::is_span_observable, + "wrong type U, only LE-scalar, or byte types are allowed"); + return ptr ? make_span(*ptr) : span(); +} + // 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). class VectorOfAny { diff --git a/tests/test.cpp b/tests/test.cpp index fb3925605..e7a906e77 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -4572,6 +4572,77 @@ void JsonUnsortedArrayTest() TEST_NOTNULL(monster->testarrayoftables()->LookupByKey("ccc")); } +void VectorSpanTest() { + flatbuffers::FlatBufferBuilder builder; + + auto mloc = + CreateMonster(builder, nullptr, 0, 0, builder.CreateString("Monster"), + builder.CreateVector({ 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_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 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_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 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_nested = + flatbuffers::make_span(monster->testnestedflatbuffer()); + TEST_ASSERT(const_nested.empty()); + + flatbuffers::span mutable_nested = + flatbuffers::make_span(mutable_monster->mutable_testnestedflatbuffer()); + TEST_ASSERT(mutable_nested.empty()); + } +} + int FlatBufferTests() { // clang-format off @@ -4678,6 +4749,7 @@ int FlatBufferTests() { NestedVerifierTest(); PrivateAnnotationsLeaks(); JsonUnsortedArrayTest(); + VectorSpanTest(); return 0; }