diff --git a/include/flatbuffers/flatbuffers.h b/include/flatbuffers/flatbuffers.h index 0fa31250f..b22aaaa6a 100644 --- a/include/flatbuffers/flatbuffers.h +++ b/include/flatbuffers/flatbuffers.h @@ -207,6 +207,7 @@ template size_t AlignOf() { // (avoiding the need for a trailing return decltype) template struct IndirectHelper { typedef T return_type; + typedef T mutable_return_type; static const size_t element_stride = sizeof(T); static return_type Read(const uint8_t *p, uoffset_t i) { return EndianScalar((reinterpret_cast(p))[i]); @@ -214,6 +215,7 @@ template struct IndirectHelper { }; template struct IndirectHelper> { typedef const T *return_type; + typedef T *mutable_return_type; static const size_t element_stride = sizeof(uoffset_t); static return_type Read(const uint8_t *p, uoffset_t i) { p += i * sizeof(uoffset_t); @@ -222,6 +224,7 @@ template struct IndirectHelper> { }; template struct IndirectHelper { typedef const T *return_type; + typedef T *mutable_return_type; static const size_t element_stride = sizeof(T); static return_type Read(const uint8_t *p, uoffset_t i) { return reinterpret_cast(p + i * sizeof(T)); @@ -306,6 +309,7 @@ public: uoffset_t Length() const { return size(); } typedef typename IndirectHelper::return_type return_type; + typedef typename IndirectHelper::mutable_return_type mutable_return_type; return_type Get(uoffset_t i) const { assert(i < size()); @@ -347,6 +351,12 @@ public: WriteScalar(data() + i, val - (Data() + i * sizeof(uoffset_t))); } + // Get a mutable pointer to tables/strings inside this vector. + mutable_return_type GetMutableObject(uoffset_t i) const { + assert(i < size()); + return const_cast(IndirectHelper::Read(Data(), i)); + } + // The raw data in little endian format. Use with care. const uint8_t *Data() const { return reinterpret_cast(&length_ + 1); diff --git a/tests/test.cpp b/tests/test.cpp index e636f1f3c..73af97133 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -108,6 +108,7 @@ flatbuffers::unique_ptr_t CreateFlatBufferTest(std::string &buffer) { mlocs[0] = mb1.Finish(); MonsterBuilder mb2(builder); mb2.add_name(barney); + mb2.add_hp(1000); mlocs[1] = mb2.Finish(); MonsterBuilder mb3(builder); mb3.add_name(wilma); @@ -203,6 +204,7 @@ void AccessFlatBufferTest(const uint8_t *flatbuf, size_t length) { for (auto it = vecoftables->begin(); it != vecoftables->end(); ++it) TEST_EQ(strlen(it->name()->c_str()) >= 4, true); TEST_EQ_STR(vecoftables->Get(0)->name()->c_str(), "Barney"); + TEST_EQ(vecoftables->Get(0)->hp(), 1000); TEST_EQ_STR(vecoftables->Get(1)->name()->c_str(), "Fred"); TEST_EQ_STR(vecoftables->Get(2)->name()->c_str(), "Wilma"); TEST_NOTNULL(vecoftables->LookupByKey("Barney")); @@ -260,6 +262,13 @@ void MutateFlatBuffersTest(uint8_t *flatbuf, std::size_t length) { TEST_EQ(inventory->Get(9), 100); inventory->Mutate(9, 9); + auto tables = monster->mutable_testarrayoftables(); + auto first = tables->GetMutableObject(0); + TEST_EQ(first->hp(), 1000); + first->mutate_hp(0); + TEST_EQ(first->hp(), 0); + first->mutate_hp(1000); + // Run the verifier and the regular test to make sure we didn't trample on // anything. AccessFlatBufferTest(flatbuf, length);