diff --git a/include/flatbuffers/array.h b/include/flatbuffers/array.h index d4b73fc9e17..ec34deea5a4 100644 --- a/include/flatbuffers/array.h +++ b/include/flatbuffers/array.h @@ -35,7 +35,7 @@ template class Array { public: typedef uint16_t size_type; typedef typename IndirectHelper::return_type return_type; - typedef VectorIterator const_iterator; + typedef VectorConstIterator const_iterator; typedef VectorReverseIterator const_reverse_iterator; // If T is a LE-scalar or a struct (!scalar_tag::value). diff --git a/include/flatbuffers/buffer.h b/include/flatbuffers/buffer.h index ca005f7157e..96ae538f3a2 100644 --- a/include/flatbuffers/buffer.h +++ b/include/flatbuffers/buffer.h @@ -76,6 +76,9 @@ template struct IndirectHelper { static return_type Read(const uint8_t *p, uoffset_t i) { return EndianScalar((reinterpret_cast(p))[i]); } + static return_type Read(uint8_t *p, uoffset_t i) { + return Read(const_cast(p), i); + } }; template struct IndirectHelper> { typedef const T *return_type; @@ -85,13 +88,20 @@ template struct IndirectHelper> { p += i * sizeof(uoffset_t); return reinterpret_cast(p + ReadScalar(p)); } + static mutable_return_type Read(uint8_t *p, uoffset_t i) { + p += i * sizeof(uoffset_t); + return reinterpret_cast(p + ReadScalar(p)); + } }; 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)); + return reinterpret_cast(p + i * sizeof(T)); + } + static mutable_return_type Read(uint8_t *p, uoffset_t i) { + return reinterpret_cast(p + i * sizeof(T)); } }; diff --git a/include/flatbuffers/vector.h b/include/flatbuffers/vector.h index 6bcdfe263af..9cb6a2da89c 100644 --- a/include/flatbuffers/vector.h +++ b/include/flatbuffers/vector.h @@ -27,14 +27,15 @@ struct String; // An STL compatible iterator implementation for Vector below, effectively // calling Get() for every element. -template struct VectorIterator { +template +struct VectorIterator { typedef std::random_access_iterator_tag iterator_category; typedef IT value_type; typedef ptrdiff_t difference_type; typedef IT *pointer; typedef IT &reference; - VectorIterator(const uint8_t *data, uoffset_t i) + VectorIterator(Data data, uoffset_t i) : data_(data + IndirectHelper::element_stride * i) {} VectorIterator(const VectorIterator &other) : data_(other.data_) {} VectorIterator() : data_(nullptr) {} @@ -116,9 +117,12 @@ template struct VectorIterator { } private: - const uint8_t *data_; + Data data_; }; +template +using VectorConstIterator = VectorIterator; + template struct VectorReverseIterator : public std::reverse_iterator { explicit VectorReverseIterator(Iterator iter) @@ -145,7 +149,7 @@ template class Vector { public: typedef VectorIterator::mutable_return_type> iterator; - typedef VectorIterator::return_type> + typedef VectorConstIterator::return_type> const_iterator; typedef VectorReverseIterator reverse_iterator; typedef VectorReverseIterator const_reverse_iterator; diff --git a/tests/monster_test.cpp b/tests/monster_test.cpp index 4fc9e143eb3..6e810dd5bf6 100644 --- a/tests/monster_test.cpp +++ b/tests/monster_test.cpp @@ -439,6 +439,16 @@ void MutateFlatBuffersTest(uint8_t *flatbuf, std::size_t length) { TEST_EQ(first->hp(), 0); first->mutate_hp(1000); + // Test for each loop over mutable entries + for (auto item: *tables) + { + TEST_EQ(item->hp(), 1000); + item->mutate_hp(0); + TEST_EQ(item->hp(), 0); + item->mutate_hp(1000); + break; // one iteration is enough, just testing compilation + } + // Mutate via LookupByKey TEST_NOTNULL(tables->MutableLookupByKey("Barney")); TEST_EQ(static_cast(nullptr),