From c2f40c37b2c0cf2c7fbb82b4b760276771abe7a1 Mon Sep 17 00:00:00 2001 From: Henry Lee Date: Fri, 25 Jan 2019 08:24:01 +1100 Subject: [PATCH] [C++]Support reverse iterator in Vector (#5128) * Add `const` keyword to the `operator-(const uoffset_t &)` function in `VectorIterator` * Support reverse iterator in Vector Introduced a new VectorReverseIterator type. We cannot directly use `std::reverse_iterator` because the signature of `operator*` and `operator->` in the VectorIterator class are not standard signatures. Also added `rbegin()`, `rend()`, `cbegin()`, `cend()`, `crbegin()` and `crend()` in the Vector class. --- include/flatbuffers/flatbuffers.h | 32 ++++++++++++++++++++++++++++++- tests/test.cpp | 18 +++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/include/flatbuffers/flatbuffers.h b/include/flatbuffers/flatbuffers.h index 3f7cbbebe..4a292f1dc 100644 --- a/include/flatbuffers/flatbuffers.h +++ b/include/flatbuffers/flatbuffers.h @@ -116,6 +116,7 @@ template struct VectorIterator { VectorIterator(const uint8_t *data, uoffset_t i) : data_(data + IndirectHelper::element_stride * i) {} VectorIterator(const VectorIterator &other) : data_(other.data_) {} + VectorIterator() : data_(nullptr) {} VectorIterator &operator=(const VectorIterator &other) { data_ = other.data_; @@ -183,7 +184,7 @@ template struct VectorIterator { return temp; } - VectorIterator operator-(const uoffset_t &offset) { + VectorIterator operator-(const uoffset_t &offset) const { return VectorIterator(data_ - offset * IndirectHelper::element_stride, 0); } @@ -197,6 +198,19 @@ template struct VectorIterator { const uint8_t *data_; }; +template struct VectorReverseIterator : + public std::reverse_iterator { + + explicit VectorReverseIterator(Iterator iter) : iter_(iter) {} + + typename Iterator::value_type operator*() const { return *(iter_ - 1); } + + typename Iterator::value_type operator->() const { return *(iter_ - 1); } + + private: + Iterator iter_; +}; + struct String; // This is used as a helper type for accessing vectors. @@ -207,6 +221,8 @@ template class Vector { iterator; typedef VectorIterator::return_type> const_iterator; + typedef VectorReverseIterator reverse_iterator; + typedef VectorReverseIterator const_reverse_iterator; uoffset_t size() const { return EndianScalar(length_); } @@ -253,6 +269,20 @@ template class Vector { iterator end() { return iterator(Data(), size()); } const_iterator end() const { return const_iterator(Data(), size()); } + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } + + reverse_iterator rend() { return reverse_iterator(end()); } + const_reverse_iterator rend() const { return const_reverse_iterator(end()); } + + const_iterator cbegin() const { return begin(); } + + const_iterator cend() const { return end(); } + + const_reverse_iterator crbegin() const { return rbegin(); } + + const_reverse_iterator crend() const { return rend(); } + // Change elements if you have a non-const pointer to this object. // Scalars only. See reflection.h, and the documentation. void Mutate(uoffset_t i, const T &val) { diff --git a/tests/test.cpp b/tests/test.cpp index 744846674..8fe66ad07 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -255,6 +255,24 @@ void AccessFlatBufferTest(const uint8_t *flatbuf, size_t length, TEST_EQ(*it, inv_data[indx]); } + for (auto it = inventory->cbegin(); it != inventory->cend(); ++it) { + auto indx = it - inventory->cbegin(); + TEST_EQ(*it, inv_vec.at(indx)); // Use bounds-check. + TEST_EQ(*it, inv_data[indx]); + } + + for (auto it = inventory->rbegin(); it != inventory->rend(); ++it) { + auto indx = inventory->rend() - it; + TEST_EQ(*it, inv_vec.at(indx)); // Use bounds-check. + TEST_EQ(*it, inv_data[indx]); + } + + for (auto it = inventory->crbegin(); it != inventory->crend(); ++it) { + auto indx = inventory->crend() - it; + TEST_EQ(*it, inv_vec.at(indx)); // Use bounds-check. + TEST_EQ(*it, inv_data[indx]); + } + TEST_EQ(monster->color(), Color_Blue); // Example of accessing a union: