mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-27 21:28:04 +00:00
[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<VectorIterator>` 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.
This commit is contained in:
committed by
Wouter van Oortmerssen
parent
63d51afd11
commit
c2f40c37b2
@@ -116,6 +116,7 @@ template<typename T, typename IT> struct VectorIterator {
|
|||||||
VectorIterator(const uint8_t *data, uoffset_t i)
|
VectorIterator(const uint8_t *data, uoffset_t i)
|
||||||
: data_(data + IndirectHelper<T>::element_stride * i) {}
|
: data_(data + IndirectHelper<T>::element_stride * i) {}
|
||||||
VectorIterator(const VectorIterator &other) : data_(other.data_) {}
|
VectorIterator(const VectorIterator &other) : data_(other.data_) {}
|
||||||
|
VectorIterator() : data_(nullptr) {}
|
||||||
|
|
||||||
VectorIterator &operator=(const VectorIterator &other) {
|
VectorIterator &operator=(const VectorIterator &other) {
|
||||||
data_ = other.data_;
|
data_ = other.data_;
|
||||||
@@ -183,7 +184,7 @@ template<typename T, typename IT> struct VectorIterator {
|
|||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
VectorIterator operator-(const uoffset_t &offset) {
|
VectorIterator operator-(const uoffset_t &offset) const {
|
||||||
return VectorIterator(data_ - offset * IndirectHelper<T>::element_stride,
|
return VectorIterator(data_ - offset * IndirectHelper<T>::element_stride,
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
@@ -197,6 +198,19 @@ template<typename T, typename IT> struct VectorIterator {
|
|||||||
const uint8_t *data_;
|
const uint8_t *data_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Iterator> struct VectorReverseIterator :
|
||||||
|
public std::reverse_iterator<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;
|
struct String;
|
||||||
|
|
||||||
// This is used as a helper type for accessing vectors.
|
// This is used as a helper type for accessing vectors.
|
||||||
@@ -207,6 +221,8 @@ template<typename T> class Vector {
|
|||||||
iterator;
|
iterator;
|
||||||
typedef VectorIterator<T, typename IndirectHelper<T>::return_type>
|
typedef VectorIterator<T, typename IndirectHelper<T>::return_type>
|
||||||
const_iterator;
|
const_iterator;
|
||||||
|
typedef VectorReverseIterator<iterator> reverse_iterator;
|
||||||
|
typedef VectorReverseIterator<const_iterator> const_reverse_iterator;
|
||||||
|
|
||||||
uoffset_t size() const { return EndianScalar(length_); }
|
uoffset_t size() const { return EndianScalar(length_); }
|
||||||
|
|
||||||
@@ -253,6 +269,20 @@ template<typename T> class Vector {
|
|||||||
iterator end() { return iterator(Data(), size()); }
|
iterator end() { return iterator(Data(), size()); }
|
||||||
const_iterator end() const { return const_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.
|
// Change elements if you have a non-const pointer to this object.
|
||||||
// Scalars only. See reflection.h, and the documentation.
|
// Scalars only. See reflection.h, and the documentation.
|
||||||
void Mutate(uoffset_t i, const T &val) {
|
void Mutate(uoffset_t i, const T &val) {
|
||||||
|
|||||||
@@ -255,6 +255,24 @@ void AccessFlatBufferTest(const uint8_t *flatbuf, size_t length,
|
|||||||
TEST_EQ(*it, inv_data[indx]);
|
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);
|
TEST_EQ(monster->color(), Color_Blue);
|
||||||
|
|
||||||
// Example of accessing a union:
|
// Example of accessing a union:
|
||||||
|
|||||||
Reference in New Issue
Block a user