File indexing completed on 2025-08-27 09:30:29
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef FLATBUFFERS_VECTOR_H_
0018 #define FLATBUFFERS_VECTOR_H_
0019
0020 #include "flatbuffers/base.h"
0021 #include "flatbuffers/buffer.h"
0022 #include "flatbuffers/stl_emulation.h"
0023
0024 namespace flatbuffers {
0025
0026 struct String;
0027
0028
0029
0030 template<typename T, typename IT, typename Data = uint8_t *,
0031 typename SizeT = uoffset_t>
0032 struct VectorIterator {
0033 typedef std::random_access_iterator_tag iterator_category;
0034 typedef IT value_type;
0035 typedef ptrdiff_t difference_type;
0036 typedef IT *pointer;
0037 typedef IT &reference;
0038
0039 static const SizeT element_stride = IndirectHelper<T>::element_stride;
0040
0041 VectorIterator(Data data, SizeT i) : data_(data + element_stride * i) {}
0042 VectorIterator(const VectorIterator &other) : data_(other.data_) {}
0043 VectorIterator() : data_(nullptr) {}
0044
0045 VectorIterator &operator=(const VectorIterator &other) {
0046 data_ = other.data_;
0047 return *this;
0048 }
0049
0050 VectorIterator &operator=(VectorIterator &&other) {
0051 data_ = other.data_;
0052 return *this;
0053 }
0054
0055 bool operator==(const VectorIterator &other) const {
0056 return data_ == other.data_;
0057 }
0058
0059 bool operator!=(const VectorIterator &other) const {
0060 return data_ != other.data_;
0061 }
0062
0063 bool operator<(const VectorIterator &other) const {
0064 return data_ < other.data_;
0065 }
0066
0067 bool operator>(const VectorIterator &other) const {
0068 return data_ > other.data_;
0069 }
0070
0071 bool operator<=(const VectorIterator &other) const {
0072 return !(data_ > other.data_);
0073 }
0074
0075 bool operator>=(const VectorIterator &other) const {
0076 return !(data_ < other.data_);
0077 }
0078
0079 difference_type operator-(const VectorIterator &other) const {
0080 return (data_ - other.data_) / element_stride;
0081 }
0082
0083
0084
0085 IT operator*() const { return IndirectHelper<T>::Read(data_, 0); }
0086
0087
0088
0089 IT operator->() const { return IndirectHelper<T>::Read(data_, 0); }
0090
0091 VectorIterator &operator++() {
0092 data_ += element_stride;
0093 return *this;
0094 }
0095
0096 VectorIterator operator++(int) {
0097 VectorIterator temp(data_, 0);
0098 data_ += element_stride;
0099 return temp;
0100 }
0101
0102 VectorIterator operator+(const SizeT &offset) const {
0103 return VectorIterator(data_ + offset * element_stride, 0);
0104 }
0105
0106 VectorIterator &operator+=(const SizeT &offset) {
0107 data_ += offset * element_stride;
0108 return *this;
0109 }
0110
0111 VectorIterator &operator--() {
0112 data_ -= element_stride;
0113 return *this;
0114 }
0115
0116 VectorIterator operator--(int) {
0117 VectorIterator temp(data_, 0);
0118 data_ -= element_stride;
0119 return temp;
0120 }
0121
0122 VectorIterator operator-(const SizeT &offset) const {
0123 return VectorIterator(data_ - offset * element_stride, 0);
0124 }
0125
0126 VectorIterator &operator-=(const SizeT &offset) {
0127 data_ -= offset * element_stride;
0128 return *this;
0129 }
0130
0131 private:
0132 Data data_;
0133 };
0134
0135 template<typename T, typename IT, typename SizeT = uoffset_t>
0136 using VectorConstIterator = VectorIterator<T, IT, const uint8_t *, SizeT>;
0137
0138 template<typename Iterator>
0139 struct VectorReverseIterator : public std::reverse_iterator<Iterator> {
0140 explicit VectorReverseIterator(Iterator iter)
0141 : std::reverse_iterator<Iterator>(iter) {}
0142
0143
0144
0145 typename Iterator::value_type operator*() const {
0146 auto tmp = std::reverse_iterator<Iterator>::current;
0147 return *--tmp;
0148 }
0149
0150
0151
0152 typename Iterator::value_type operator->() const {
0153 auto tmp = std::reverse_iterator<Iterator>::current;
0154 return *--tmp;
0155 }
0156 };
0157
0158
0159
0160 template<typename T, typename SizeT = uoffset_t> class Vector {
0161 public:
0162 typedef VectorIterator<T, typename IndirectHelper<T>::mutable_return_type,
0163 uint8_t *, SizeT>
0164 iterator;
0165 typedef VectorConstIterator<T, typename IndirectHelper<T>::return_type, SizeT>
0166 const_iterator;
0167 typedef VectorReverseIterator<iterator> reverse_iterator;
0168 typedef VectorReverseIterator<const_iterator> const_reverse_iterator;
0169
0170 typedef typename flatbuffers::bool_constant<flatbuffers::is_scalar<T>::value>
0171 scalar_tag;
0172
0173 static FLATBUFFERS_CONSTEXPR bool is_span_observable =
0174 scalar_tag::value && (FLATBUFFERS_LITTLEENDIAN || sizeof(T) == 1);
0175
0176 SizeT size() const { return EndianScalar(length_); }
0177
0178
0179
0180
0181 bool empty() const { return size() == 0; }
0182
0183
0184 FLATBUFFERS_ATTRIBUTE([[deprecated("use size() instead")]])
0185 SizeT Length() const { return size(); }
0186
0187 typedef SizeT size_type;
0188 typedef typename IndirectHelper<T>::return_type return_type;
0189 typedef typename IndirectHelper<T>::mutable_return_type mutable_return_type;
0190 typedef return_type value_type;
0191
0192 return_type Get(SizeT i) const {
0193 FLATBUFFERS_ASSERT(i < size());
0194 return IndirectHelper<T>::Read(Data(), i);
0195 }
0196
0197 return_type operator[](SizeT i) const { return Get(i); }
0198
0199
0200
0201
0202 template<typename E> E GetEnum(SizeT i) const {
0203 return static_cast<E>(Get(i));
0204 }
0205
0206
0207
0208 template<typename U> const U *GetAs(SizeT i) const {
0209 return reinterpret_cast<const U *>(Get(i));
0210 }
0211
0212
0213
0214 const String *GetAsString(SizeT i) const {
0215 return reinterpret_cast<const String *>(Get(i));
0216 }
0217
0218 const void *GetStructFromOffset(size_t o) const {
0219 return reinterpret_cast<const void *>(Data() + o);
0220 }
0221
0222 iterator begin() { return iterator(Data(), 0); }
0223 const_iterator begin() const { return const_iterator(Data(), 0); }
0224
0225 iterator end() { return iterator(Data(), size()); }
0226 const_iterator end() const { return const_iterator(Data(), size()); }
0227
0228 reverse_iterator rbegin() { return reverse_iterator(end()); }
0229 const_reverse_iterator rbegin() const {
0230 return const_reverse_iterator(end());
0231 }
0232
0233 reverse_iterator rend() { return reverse_iterator(begin()); }
0234 const_reverse_iterator rend() const {
0235 return const_reverse_iterator(begin());
0236 }
0237
0238 const_iterator cbegin() const { return begin(); }
0239
0240 const_iterator cend() const { return end(); }
0241
0242 const_reverse_iterator crbegin() const { return rbegin(); }
0243
0244 const_reverse_iterator crend() const { return rend(); }
0245
0246
0247
0248 void Mutate(SizeT i, const T &val) {
0249 FLATBUFFERS_ASSERT(i < size());
0250 WriteScalar(data() + i, val);
0251 }
0252
0253
0254
0255
0256 void MutateOffset(SizeT i, const uint8_t *val) {
0257 FLATBUFFERS_ASSERT(i < size());
0258 static_assert(sizeof(T) == sizeof(SizeT), "Unrelated types");
0259 WriteScalar(data() + i,
0260 static_cast<SizeT>(val - (Data() + i * sizeof(SizeT))));
0261 }
0262
0263
0264 mutable_return_type GetMutableObject(SizeT i) const {
0265 FLATBUFFERS_ASSERT(i < size());
0266 return const_cast<mutable_return_type>(IndirectHelper<T>::Read(Data(), i));
0267 }
0268
0269
0270 const uint8_t *Data() const {
0271 return reinterpret_cast<const uint8_t *>(&length_ + 1);
0272 }
0273
0274 uint8_t *Data() { return reinterpret_cast<uint8_t *>(&length_ + 1); }
0275
0276
0277 const T *data() const { return reinterpret_cast<const T *>(Data()); }
0278 T *data() { return reinterpret_cast<T *>(Data()); }
0279
0280 template<typename K> return_type LookupByKey(K key) const {
0281 void *search_result = std::bsearch(
0282 &key, Data(), size(), IndirectHelper<T>::element_stride, KeyCompare<K>);
0283
0284 if (!search_result) {
0285 return nullptr;
0286 }
0287
0288 const uint8_t *element = reinterpret_cast<const uint8_t *>(search_result);
0289
0290 return IndirectHelper<T>::Read(element, 0);
0291 }
0292
0293 template<typename K> mutable_return_type MutableLookupByKey(K key) {
0294 return const_cast<mutable_return_type>(LookupByKey(key));
0295 }
0296
0297 protected:
0298
0299
0300 Vector();
0301
0302 SizeT length_;
0303
0304 private:
0305
0306
0307 Vector(const Vector &);
0308 Vector &operator=(const Vector &);
0309
0310 template<typename K> static int KeyCompare(const void *ap, const void *bp) {
0311 const K *key = reinterpret_cast<const K *>(ap);
0312 const uint8_t *data = reinterpret_cast<const uint8_t *>(bp);
0313 auto table = IndirectHelper<T>::Read(data, 0);
0314
0315
0316
0317 return -table->KeyCompareWithValue(*key);
0318 }
0319 };
0320
0321 template<typename T> using Vector64 = Vector<T, uoffset64_t>;
0322
0323 template<class U>
0324 FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U> make_span(Vector<U> &vec)
0325 FLATBUFFERS_NOEXCEPT {
0326 static_assert(Vector<U>::is_span_observable,
0327 "wrong type U, only LE-scalar, or byte types are allowed");
0328 return span<U>(vec.data(), vec.size());
0329 }
0330
0331 template<class U>
0332 FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const U> make_span(
0333 const Vector<U> &vec) FLATBUFFERS_NOEXCEPT {
0334 static_assert(Vector<U>::is_span_observable,
0335 "wrong type U, only LE-scalar, or byte types are allowed");
0336 return span<const U>(vec.data(), vec.size());
0337 }
0338
0339 template<class U>
0340 FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<uint8_t> make_bytes_span(
0341 Vector<U> &vec) FLATBUFFERS_NOEXCEPT {
0342 static_assert(Vector<U>::scalar_tag::value,
0343 "wrong type U, only LE-scalar, or byte types are allowed");
0344 return span<uint8_t>(vec.Data(), vec.size() * sizeof(U));
0345 }
0346
0347 template<class U>
0348 FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const uint8_t> make_bytes_span(
0349 const Vector<U> &vec) FLATBUFFERS_NOEXCEPT {
0350 static_assert(Vector<U>::scalar_tag::value,
0351 "wrong type U, only LE-scalar, or byte types are allowed");
0352 return span<const uint8_t>(vec.Data(), vec.size() * sizeof(U));
0353 }
0354
0355
0356
0357 template<class U>
0358 FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U> make_span(Vector<U> *ptr)
0359 FLATBUFFERS_NOEXCEPT {
0360 static_assert(Vector<U>::is_span_observable,
0361 "wrong type U, only LE-scalar, or byte types are allowed");
0362 return ptr ? make_span(*ptr) : span<U>();
0363 }
0364
0365 template<class U>
0366 FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const U> make_span(
0367 const Vector<U> *ptr) FLATBUFFERS_NOEXCEPT {
0368 static_assert(Vector<U>::is_span_observable,
0369 "wrong type U, only LE-scalar, or byte types are allowed");
0370 return ptr ? make_span(*ptr) : span<const U>();
0371 }
0372
0373
0374
0375 class VectorOfAny {
0376 public:
0377 uoffset_t size() const { return EndianScalar(length_); }
0378
0379 const uint8_t *Data() const {
0380 return reinterpret_cast<const uint8_t *>(&length_ + 1);
0381 }
0382 uint8_t *Data() { return reinterpret_cast<uint8_t *>(&length_ + 1); }
0383
0384 protected:
0385 VectorOfAny();
0386
0387 uoffset_t length_;
0388
0389 private:
0390 VectorOfAny(const VectorOfAny &);
0391 VectorOfAny &operator=(const VectorOfAny &);
0392 };
0393
0394 template<typename T, typename U>
0395 Vector<Offset<T>> *VectorCast(Vector<Offset<U>> *ptr) {
0396 static_assert(std::is_base_of<T, U>::value, "Unrelated types");
0397 return reinterpret_cast<Vector<Offset<T>> *>(ptr);
0398 }
0399
0400 template<typename T, typename U>
0401 const Vector<Offset<T>> *VectorCast(const Vector<Offset<U>> *ptr) {
0402 static_assert(std::is_base_of<T, U>::value, "Unrelated types");
0403 return reinterpret_cast<const Vector<Offset<T>> *>(ptr);
0404 }
0405
0406
0407
0408 template<typename T> static inline size_t VectorLength(const Vector<T> *v) {
0409 return v ? v->size() : 0;
0410 }
0411
0412 }
0413
0414 #endif