Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-08-27 09:30:29

0001 /*
0002  * Copyright 2021 Google Inc. All rights reserved.
0003  *
0004  * Licensed under the Apache License, Version 2.0 (the "License");
0005  * you may not use this file except in compliance with the License.
0006  * You may obtain a copy of the License at
0007  *
0008  *     http://www.apache.org/licenses/LICENSE-2.0
0009  *
0010  * Unless required by applicable law or agreed to in writing, software
0011  * distributed under the License is distributed on an "AS IS" BASIS,
0012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013  * See the License for the specific language governing permissions and
0014  * limitations under the License.
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 // An STL compatible iterator implementation for Vector below, effectively
0029 // calling Get() for every element.
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   // Note: return type is incompatible with the standard
0084   // `reference operator*()`.
0085   IT operator*() const { return IndirectHelper<T>::Read(data_, 0); }
0086 
0087   // Note: return type is incompatible with the standard
0088   // `pointer operator->()`.
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   // Note: return type is incompatible with the standard
0144   // `reference operator*()`.
0145   typename Iterator::value_type operator*() const {
0146     auto tmp = std::reverse_iterator<Iterator>::current;
0147     return *--tmp;
0148   }
0149 
0150   // Note: return type is incompatible with the standard
0151   // `pointer operator->()`.
0152   typename Iterator::value_type operator->() const {
0153     auto tmp = std::reverse_iterator<Iterator>::current;
0154     return *--tmp;
0155   }
0156 };
0157 
0158 // This is used as a helper type for accessing vectors.
0159 // Vector::data() assumes the vector elements start after the length field.
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   // Returns true if the vector is empty.
0179   //
0180   // This just provides another standardized method that is expected of vectors.
0181   bool empty() const { return size() == 0; }
0182 
0183   // Deprecated: use size(). Here for backwards compatibility.
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   // If this is a Vector of enums, T will be its storage type, not the enum
0200   // type. This function makes it convenient to retrieve value with enum
0201   // type E.
0202   template<typename E> E GetEnum(SizeT i) const {
0203     return static_cast<E>(Get(i));
0204   }
0205 
0206   // If this a vector of unions, this does the cast for you. There's no check
0207   // to make sure this is the right type!
0208   template<typename U> const U *GetAs(SizeT i) const {
0209     return reinterpret_cast<const U *>(Get(i));
0210   }
0211 
0212   // If this a vector of unions, this does the cast for you. There's no check
0213   // to make sure this is actually a string!
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   // Change elements if you have a non-const pointer to this object.
0247   // Scalars only. See reflection.h, and the documentation.
0248   void Mutate(SizeT i, const T &val) {
0249     FLATBUFFERS_ASSERT(i < size());
0250     WriteScalar(data() + i, val);
0251   }
0252 
0253   // Change an element of a vector of tables (or strings).
0254   // "val" points to the new table/string, as you can obtain from
0255   // e.g. reflection::AddFlatBuffer().
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   // Get a mutable pointer to tables/strings inside this vector.
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   // The raw data in little endian format. Use with care.
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   // Similarly, but typed, much like std::vector::data
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;  // Key not found.
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   // This class is only used to access pre-existing data. Don't ever
0299   // try to construct these manually.
0300   Vector();
0301 
0302   SizeT length_;
0303 
0304  private:
0305   // This class is a pointer. Copying will therefore create an invalid object.
0306   // Private and unimplemented copy constructor.
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     // std::bsearch compares with the operands transposed, so we negate the
0316     // result here.
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 // Convenient helper functions to get a span of any vector, regardless
0356 // of whether it is null or not (the field is not set).
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 // Represent a vector much like the template above, but in this case we
0374 // don't know what the element types are (used with reflection.h).
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 // Convenient helper function to get the length of any vector, regardless
0407 // of whether it is null or not (the field is not set).
0408 template<typename T> static inline size_t VectorLength(const Vector<T> *v) {
0409   return v ? v->size() : 0;
0410 }
0411 
0412 }  // namespace flatbuffers
0413 
0414 #endif  // FLATBUFFERS_VERIFIER_H_