flatbuffers.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2014 Google Inc. All rights reserved.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #ifndef FLATBUFFERS_H_
00018 #define FLATBUFFERS_H_
00019 
00020 #include "flatbuffers/base.h"
00021 
00022 namespace flatbuffers {
00023 // Wrapper for uoffset_t to allow safe template specialization.
00024 // Value is allowed to be 0 to indicate a null object (see e.g. AddOffset).
00025 template<typename T> struct Offset {
00026   uoffset_t o;
00027   Offset() : o(0) {}
00028   Offset(uoffset_t _o) : o(_o) {}
00029   Offset<void> Union() const { return Offset<void>(o); }
00030   bool IsNull() const { return !o; }
00031 };
00032 
00033 inline void EndianCheck() {
00034   int endiantest = 1;
00035   // If this fails, see FLATBUFFERS_LITTLEENDIAN above.
00036   FLATBUFFERS_ASSERT(*reinterpret_cast<char *>(&endiantest) ==
00037                      FLATBUFFERS_LITTLEENDIAN);
00038   (void)endiantest;
00039 }
00040 
00041 template<typename T> FLATBUFFERS_CONSTEXPR size_t AlignOf() {
00042   // clang-format off
00043   #ifdef _MSC_VER
00044     return __alignof(T);
00045   #else
00046     #ifndef alignof
00047       return __alignof__(T);
00048     #else
00049       return alignof(T);
00050     #endif
00051   #endif
00052   // clang-format on
00053 }
00054 
00055 // When we read serialized data from memory, in the case of most scalars,
00056 // we want to just read T, but in the case of Offset, we want to actually
00057 // perform the indirection and return a pointer.
00058 // The template specialization below does just that.
00059 // It is wrapped in a struct since function templates can't overload on the
00060 // return type like this.
00061 // The typedef is for the convenience of callers of this function
00062 // (avoiding the need for a trailing return decltype)
00063 template<typename T> struct IndirectHelper {
00064   typedef T return_type;
00065   typedef T mutable_return_type;
00066   static const size_t element_stride = sizeof(T);
00067   static return_type Read(const uint8_t *p, uoffset_t i) {
00068     return EndianScalar((reinterpret_cast<const T *>(p))[i]);
00069   }
00070 };
00071 template<typename T> struct IndirectHelper<Offset<T>> {
00072   typedef const T *return_type;
00073   typedef T *mutable_return_type;
00074   static const size_t element_stride = sizeof(uoffset_t);
00075   static return_type Read(const uint8_t *p, uoffset_t i) {
00076     p += i * sizeof(uoffset_t);
00077     return reinterpret_cast<return_type>(p + ReadScalar<uoffset_t>(p));
00078   }
00079 };
00080 template<typename T> struct IndirectHelper<const T *> {
00081   typedef const T *return_type;
00082   typedef T *mutable_return_type;
00083   static const size_t element_stride = sizeof(T);
00084   static return_type Read(const uint8_t *p, uoffset_t i) {
00085     return reinterpret_cast<const T *>(p + i * sizeof(T));
00086   }
00087 };
00088 
00089 // An STL compatible iterator implementation for Vector below, effectively
00090 // calling Get() for every element.
00091 template<typename T, typename IT> struct VectorIterator {
00092   typedef std::random_access_iterator_tag iterator_category;
00093   typedef IT value_type;
00094   typedef uoffset_t difference_type;
00095   typedef IT *pointer;
00096   typedef IT &reference;
00097 
00098   VectorIterator(const uint8_t *data, uoffset_t i)
00099       : data_(data + IndirectHelper<T>::element_stride * i) {}
00100   VectorIterator(const VectorIterator &other) : data_(other.data_) {}
00101 
00102   VectorIterator &operator=(const VectorIterator &other) {
00103     data_ = other.data_;
00104     return *this;
00105   }
00106 
00107   VectorIterator &operator=(VectorIterator &&other) {
00108     data_ = other.data_;
00109     return *this;
00110   }
00111 
00112   bool operator==(const VectorIterator &other) const {
00113     return data_ == other.data_;
00114   }
00115 
00116   bool operator<(const VectorIterator &other) const {
00117     return data_ < other.data_;
00118   }
00119 
00120   bool operator!=(const VectorIterator &other) const {
00121     return data_ != other.data_;
00122   }
00123 
00124   ptrdiff_t operator-(const VectorIterator &other) const {
00125     return (data_ - other.data_) / IndirectHelper<T>::element_stride;
00126   }
00127 
00128   IT operator*() const { return IndirectHelper<T>::Read(data_, 0); }
00129 
00130   IT operator->() const { return IndirectHelper<T>::Read(data_, 0); }
00131 
00132   VectorIterator &operator++() {
00133     data_ += IndirectHelper<T>::element_stride;
00134     return *this;
00135   }
00136 
00137   VectorIterator operator++(int) {
00138     VectorIterator temp(data_, 0);
00139     data_ += IndirectHelper<T>::element_stride;
00140     return temp;
00141   }
00142 
00143   VectorIterator operator+(const uoffset_t &offset) const {
00144     return VectorIterator(data_ + offset * IndirectHelper<T>::element_stride,
00145                           0);
00146   }
00147 
00148   VectorIterator &operator+=(const uoffset_t &offset) {
00149     data_ += offset * IndirectHelper<T>::element_stride;
00150     return *this;
00151   }
00152 
00153   VectorIterator &operator--() {
00154     data_ -= IndirectHelper<T>::element_stride;
00155     return *this;
00156   }
00157 
00158   VectorIterator operator--(int) {
00159     VectorIterator temp(data_, 0);
00160     data_ -= IndirectHelper<T>::element_stride;
00161     return temp;
00162   }
00163 
00164   VectorIterator operator-(const uoffset_t &offset) {
00165     return VectorIterator(data_ - offset * IndirectHelper<T>::element_stride,
00166                           0);
00167   }
00168 
00169   VectorIterator &operator-=(const uoffset_t &offset) {
00170     data_ -= offset * IndirectHelper<T>::element_stride;
00171     return *this;
00172   }
00173 
00174  private:
00175   const uint8_t *data_;
00176 };
00177 
00178 struct String;
00179 
00180 // This is used as a helper type for accessing vectors.
00181 // Vector::data() assumes the vector elements start after the length field.
00182 template<typename T> class Vector {
00183  public:
00184   typedef VectorIterator<T, typename IndirectHelper<T>::mutable_return_type>
00185       iterator;
00186   typedef VectorIterator<T, typename IndirectHelper<T>::return_type>
00187       const_iterator;
00188 
00189   uoffset_t size() const { return EndianScalar(length_); }
00190 
00191   // Deprecated: use size(). Here for backwards compatibility.
00192   uoffset_t Length() const { return size(); }
00193 
00194   typedef typename IndirectHelper<T>::return_type return_type;
00195   typedef typename IndirectHelper<T>::mutable_return_type mutable_return_type;
00196 
00197   return_type Get(uoffset_t i) const {
00198     FLATBUFFERS_ASSERT(i < size());
00199     return IndirectHelper<T>::Read(Data(), i);
00200   }
00201 
00202   return_type operator[](uoffset_t i) const { return Get(i); }
00203 
00204   // If this is a Vector of enums, T will be its storage type, not the enum
00205   // type. This function makes it convenient to retrieve value with enum
00206   // type E.
00207   template<typename E> E GetEnum(uoffset_t i) const {
00208     return static_cast<E>(Get(i));
00209   }
00210 
00211   // If this a vector of unions, this does the cast for you. There's no check
00212   // to make sure this is the right type!
00213   template<typename U> const U *GetAs(uoffset_t i) const {
00214     return reinterpret_cast<const U *>(Get(i));
00215   }
00216 
00217   // If this a vector of unions, this does the cast for you. There's no check
00218   // to make sure this is actually a string!
00219   const String *GetAsString(uoffset_t i) const {
00220     return reinterpret_cast<const String *>(Get(i));
00221   }
00222 
00223   const void *GetStructFromOffset(size_t o) const {
00224     return reinterpret_cast<const void *>(Data() + o);
00225   }
00226 
00227   iterator begin() { return iterator(Data(), 0); }
00228   const_iterator begin() const { return const_iterator(Data(), 0); }
00229 
00230   iterator end() { return iterator(Data(), size()); }
00231   const_iterator end() const { return const_iterator(Data(), size()); }
00232 
00233   // Change elements if you have a non-const pointer to this object.
00234   // Scalars only. See reflection.h, and the documentation.
00235   void Mutate(uoffset_t i, const T &val) {
00236     FLATBUFFERS_ASSERT(i < size());
00237     WriteScalar(data() + i, val);
00238   }
00239 
00240   // Change an element of a vector of tables (or strings).
00241   // "val" points to the new table/string, as you can obtain from
00242   // e.g. reflection::AddFlatBuffer().
00243   void MutateOffset(uoffset_t i, const uint8_t *val) {
00244     FLATBUFFERS_ASSERT(i < size());
00245     static_assert(sizeof(T) == sizeof(uoffset_t), "Unrelated types");
00246     WriteScalar(data() + i,
00247                 static_cast<uoffset_t>(val - (Data() + i * sizeof(uoffset_t))));
00248   }
00249 
00250   // Get a mutable pointer to tables/strings inside this vector.
00251   mutable_return_type GetMutableObject(uoffset_t i) const {
00252     FLATBUFFERS_ASSERT(i < size());
00253     return const_cast<mutable_return_type>(IndirectHelper<T>::Read(Data(), i));
00254   }
00255 
00256   // The raw data in little endian format. Use with care.
00257   const uint8_t *Data() const {
00258     return reinterpret_cast<const uint8_t *>(&length_ + 1);
00259   }
00260 
00261   uint8_t *Data() { return reinterpret_cast<uint8_t *>(&length_ + 1); }
00262 
00263   // Similarly, but typed, much like std::vector::data
00264   const T *data() const { return reinterpret_cast<const T *>(Data()); }
00265   T *data() { return reinterpret_cast<T *>(Data()); }
00266 
00267   template<typename K> return_type LookupByKey(K key) const {
00268     void *search_result = std::bsearch(
00269         &key, Data(), size(), IndirectHelper<T>::element_stride, KeyCompare<K>);
00270 
00271     if (!search_result) {
00272       return nullptr;  // Key not found.
00273     }
00274 
00275     const uint8_t *element = reinterpret_cast<const uint8_t *>(search_result);
00276 
00277     return IndirectHelper<T>::Read(element, 0);
00278   }
00279 
00280  protected:
00281   // This class is only used to access pre-existing data. Don't ever
00282   // try to construct these manually.
00283   Vector();
00284 
00285   uoffset_t length_;
00286 
00287  private:
00288   // This class is a pointer. Copying will therefore create an invalid object.
00289   // Private and unimplemented copy constructor.
00290   Vector(const Vector &);
00291 
00292   template<typename K> static int KeyCompare(const void *ap, const void *bp) {
00293     const K *key = reinterpret_cast<const K *>(ap);
00294     const uint8_t *data = reinterpret_cast<const uint8_t *>(bp);
00295     auto table = IndirectHelper<T>::Read(data, 0);
00296 
00297     // std::bsearch compares with the operands transposed, so we negate the
00298     // result here.
00299     return -table->KeyCompareWithValue(*key);
00300   }
00301 };
00302 
00303 // Represent a vector much like the template above, but in this case we
00304 // don't know what the element types are (used with reflection.h).
00305 class VectorOfAny {
00306  public:
00307   uoffset_t size() const { return EndianScalar(length_); }
00308 
00309   const uint8_t *Data() const {
00310     return reinterpret_cast<const uint8_t *>(&length_ + 1);
00311   }
00312   uint8_t *Data() { return reinterpret_cast<uint8_t *>(&length_ + 1); }
00313 
00314  protected:
00315   VectorOfAny();
00316 
00317   uoffset_t length_;
00318 
00319  private:
00320   VectorOfAny(const VectorOfAny &);
00321 };
00322 
00323 #ifndef FLATBUFFERS_CPP98_STL
00324 template<typename T, typename U>
00325 Vector<Offset<T>> *VectorCast(Vector<Offset<U>> *ptr) {
00326   static_assert(std::is_base_of<T, U>::value, "Unrelated types");
00327   return reinterpret_cast<Vector<Offset<T>> *>(ptr);
00328 }
00329 
00330 template<typename T, typename U>
00331 const Vector<Offset<T>> *VectorCast(const Vector<Offset<U>> *ptr) {
00332   static_assert(std::is_base_of<T, U>::value, "Unrelated types");
00333   return reinterpret_cast<const Vector<Offset<T>> *>(ptr);
00334 }
00335 #endif
00336 
00337 // Convenient helper function to get the length of any vector, regardless
00338 // of wether it is null or not (the field is not set).
00339 template<typename T> static inline size_t VectorLength(const Vector<T> *v) {
00340   return v ? v->Length() : 0;
00341 }
00342 
00343 struct String : public Vector<char> {
00344   const char *c_str() const { return reinterpret_cast<const char *>(Data()); }
00345   std::string str() const { return std::string(c_str(), Length()); }
00346 
00347   // clang-format off
00348   #ifdef FLATBUFFERS_HAS_STRING_VIEW
00349   flatbuffers::string_view string_view() const {
00350     return flatbuffers::string_view(c_str(), Length());
00351   }
00352   #endif // FLATBUFFERS_HAS_STRING_VIEW
00353   // clang-format on
00354 
00355   bool operator<(const String &o) const {
00356     return strcmp(c_str(), o.c_str()) < 0;
00357   }
00358 };
00359 
00360 // Allocator interface. This is flatbuffers-specific and meant only for
00361 // `vector_downward` usage.
00362 class Allocator {
00363  public:
00364   virtual ~Allocator() {}
00365 
00366   // Allocate `size` bytes of memory.
00367   virtual uint8_t *allocate(size_t size) = 0;
00368 
00369   // Deallocate `size` bytes of memory at `p` allocated by this allocator.
00370   virtual void deallocate(uint8_t *p, size_t size) = 0;
00371 
00372   // Reallocate `new_size` bytes of memory, replacing the old region of size
00373   // `old_size` at `p`. In contrast to a normal realloc, this grows downwards,
00374   // and is intended specifcally for `vector_downward` use.
00375   // `in_use_back` and `in_use_front` indicate how much of `old_size` is
00376   // actually in use at each end, and needs to be copied.
00377   virtual uint8_t *reallocate_downward(uint8_t *old_p, size_t old_size,
00378                                        size_t new_size, size_t in_use_back,
00379                                        size_t in_use_front) {
00380     FLATBUFFERS_ASSERT(new_size > old_size);  // vector_downward only grows
00381     uint8_t *new_p = allocate(new_size);
00382     memcpy_downward(old_p, old_size, new_p, new_size, in_use_back,
00383                     in_use_front);
00384     deallocate(old_p, old_size);
00385     return new_p;
00386   }
00387 
00388  protected:
00389   // Called by `reallocate_downward` to copy memory from `old_p` of `old_size`
00390   // to `new_p` of `new_size`. Only memory of size `in_use_front` and
00391   // `in_use_back` will be copied from the front and back of the old memory
00392   // allocation.
00393   void memcpy_downward(uint8_t *old_p, size_t old_size,
00394                        uint8_t *new_p, size_t new_size,
00395                        size_t in_use_back, size_t in_use_front) {
00396     memcpy(new_p + new_size - in_use_back, old_p + old_size - in_use_back,
00397            in_use_back);
00398     memcpy(new_p, old_p, in_use_front);
00399   }
00400 };
00401 
00402 // DefaultAllocator uses new/delete to allocate memory regions
00403 class DefaultAllocator : public Allocator {
00404  public:
00405   virtual uint8_t *allocate(size_t size) FLATBUFFERS_OVERRIDE {
00406     return new uint8_t[size];
00407   }
00408 
00409   virtual void deallocate(uint8_t *p, size_t) FLATBUFFERS_OVERRIDE {
00410     delete[] p;
00411   }
00412 
00413   static DefaultAllocator &instance() {
00414     static DefaultAllocator inst;
00415     return inst;
00416   }
00417 };
00418 
00419 // DetachedBuffer is a finished flatbuffer memory region, detached from its
00420 // builder. The original memory region and allocator are also stored so that
00421 // the DetachedBuffer can manage the memory lifetime.
00422 class DetachedBuffer {
00423  public:
00424   DetachedBuffer()
00425       : allocator_(nullptr),
00426         own_allocator_(false),
00427         buf_(nullptr),
00428         reserved_(0),
00429         cur_(nullptr),
00430         size_(0) {}
00431 
00432   DetachedBuffer(Allocator *allocator, bool own_allocator, uint8_t *buf,
00433                  size_t reserved, uint8_t *cur, size_t sz)
00434       : allocator_(allocator),
00435         own_allocator_(own_allocator),
00436         buf_(buf),
00437         reserved_(reserved),
00438         cur_(cur),
00439         size_(sz) {
00440     FLATBUFFERS_ASSERT(allocator_);
00441   }
00442 
00443   DetachedBuffer(DetachedBuffer &&other)
00444       : allocator_(other.allocator_),
00445         own_allocator_(other.own_allocator_),
00446         buf_(other.buf_),
00447         reserved_(other.reserved_),
00448         cur_(other.cur_),
00449         size_(other.size_) {
00450     other.reset();
00451   }
00452 
00453   DetachedBuffer &operator=(DetachedBuffer &&other) {
00454     destroy();
00455 
00456     allocator_ = other.allocator_;
00457     own_allocator_ = other.own_allocator_;
00458     buf_ = other.buf_;
00459     reserved_ = other.reserved_;
00460     cur_ = other.cur_;
00461     size_ = other.size_;
00462 
00463     other.reset();
00464 
00465     return *this;
00466   }
00467 
00468   ~DetachedBuffer() { destroy(); }
00469 
00470   const uint8_t *data() const { return cur_; }
00471 
00472   uint8_t *data() { return cur_; }
00473 
00474   size_t size() const { return size_; }
00475 
00476   // clang-format off
00477   #if 0  // disabled for now due to the ordering of classes in this header
00478   template <class T>
00479   bool Verify() const {
00480     Verifier verifier(data(), size());
00481     return verifier.Verify<T>(nullptr);
00482   }
00483 
00484   template <class T>
00485   const T* GetRoot() const {
00486     return flatbuffers::GetRoot<T>(data());
00487   }
00488 
00489   template <class T>
00490   T* GetRoot() {
00491     return flatbuffers::GetRoot<T>(data());
00492   }
00493   #endif
00494   // clang-format on
00495 
00496   // These may change access mode, leave these at end of public section
00497   FLATBUFFERS_DELETE_FUNC(DetachedBuffer(const DetachedBuffer &other))
00498   FLATBUFFERS_DELETE_FUNC(
00499       DetachedBuffer &operator=(const DetachedBuffer &other))
00500 
00501  protected:
00502   Allocator *allocator_;
00503   bool own_allocator_;
00504   uint8_t *buf_;
00505   size_t reserved_;
00506   uint8_t *cur_;
00507   size_t size_;
00508 
00509   inline void destroy() {
00510     if (buf_) {
00511       FLATBUFFERS_ASSERT(allocator_);
00512       allocator_->deallocate(buf_, reserved_);
00513     }
00514     if (own_allocator_ && allocator_) { delete allocator_; }
00515 
00516     reset();
00517   }
00518 
00519   inline void reset() {
00520     allocator_ = nullptr;
00521     own_allocator_ = false;
00522     buf_ = nullptr;
00523     reserved_ = 0;
00524     cur_ = nullptr;
00525     size_ = 0;
00526   }
00527 };
00528 
00529 // This is a minimal replication of std::vector<uint8_t> functionality,
00530 // except growing from higher to lower addresses. i.e push_back() inserts data
00531 // in the lowest address in the vector.
00532 // Since this vector leaves the lower part unused, we support a "scratch-pad"
00533 // that can be stored there for temporary data, to share the allocated space.
00534 // Essentially, this supports 2 std::vectors in a single buffer.
00535 class vector_downward {
00536  public:
00537   explicit vector_downward(size_t initial_size,
00538                            Allocator *allocator,
00539                            bool own_allocator,
00540                            size_t buffer_minalign)
00541       : allocator_(allocator ? allocator : &DefaultAllocator::instance()),
00542         own_allocator_(own_allocator),
00543         initial_size_(initial_size),
00544         buffer_minalign_(buffer_minalign),
00545         reserved_(0),
00546         buf_(nullptr),
00547         cur_(nullptr),
00548         scratch_(nullptr) {
00549     FLATBUFFERS_ASSERT(allocator_);
00550   }
00551 
00552   ~vector_downward() {
00553     if (buf_) {
00554       FLATBUFFERS_ASSERT(allocator_);
00555       allocator_->deallocate(buf_, reserved_);
00556     }
00557     if (own_allocator_ && allocator_) { delete allocator_; }
00558   }
00559 
00560   void reset() {
00561     if (buf_) {
00562       FLATBUFFERS_ASSERT(allocator_);
00563       allocator_->deallocate(buf_, reserved_);
00564       buf_ = nullptr;
00565     }
00566     clear();
00567   }
00568 
00569   void clear() {
00570     if (buf_) {
00571       cur_ = buf_ + reserved_;
00572     } else {
00573       reserved_ = 0;
00574       cur_ = nullptr;
00575     }
00576     clear_scratch();
00577   }
00578 
00579   void clear_scratch() {
00580     scratch_ = buf_;
00581   }
00582 
00583   // Relinquish the pointer to the caller.
00584   DetachedBuffer release() {
00585     DetachedBuffer fb(allocator_, own_allocator_, buf_, reserved_, cur_,
00586                       size());
00587     allocator_ = nullptr;
00588     own_allocator_ = false;
00589     buf_ = nullptr;
00590     clear();
00591     return fb;
00592   }
00593 
00594   size_t ensure_space(size_t len) {
00595     FLATBUFFERS_ASSERT(cur_ >= scratch_ && scratch_ >= buf_);
00596     if (len > static_cast<size_t>(cur_ - scratch_)) { reallocate(len); }
00597     // Beyond this, signed offsets may not have enough range:
00598     // (FlatBuffers > 2GB not supported).
00599     FLATBUFFERS_ASSERT(size() < FLATBUFFERS_MAX_BUFFER_SIZE);
00600     return len;
00601   }
00602 
00603   inline uint8_t *make_space(size_t len) {
00604     cur_ -= ensure_space(len);
00605     return cur_;
00606   }
00607 
00608   Allocator &get_allocator() { return *allocator_; }
00609 
00610   uoffset_t size() const {
00611     return static_cast<uoffset_t>(reserved_ - (cur_ - buf_));
00612   }
00613 
00614   uoffset_t scratch_size() const {
00615     return static_cast<uoffset_t>(scratch_ - buf_);
00616   }
00617 
00618   size_t capacity() const { return reserved_; }
00619 
00620   uint8_t *data() const {
00621     FLATBUFFERS_ASSERT(cur_);
00622     return cur_;
00623   }
00624 
00625   uint8_t *scratch_data() const {
00626     FLATBUFFERS_ASSERT(buf_);
00627     return buf_;
00628   }
00629 
00630   uint8_t *scratch_end() const {
00631     FLATBUFFERS_ASSERT(scratch_);
00632     return scratch_;
00633   }
00634 
00635   uint8_t *data_at(size_t offset) const { return buf_ + reserved_ - offset; }
00636 
00637   void push(const uint8_t *bytes, size_t num) {
00638     memcpy(make_space(num), bytes, num);
00639   }
00640 
00641   // Specialized version of push() that avoids memcpy call for small data.
00642   template<typename T> void push_small(const T &little_endian_t) {
00643     make_space(sizeof(T));
00644     *reinterpret_cast<T *>(cur_) = little_endian_t;
00645   }
00646 
00647   template<typename T> void scratch_push_small(const T &t) {
00648     ensure_space(sizeof(T));
00649     *reinterpret_cast<T *>(scratch_) = t;
00650     scratch_ += sizeof(T);
00651   }
00652 
00653   // fill() is most frequently called with small byte counts (<= 4),
00654   // which is why we're using loops rather than calling memset.
00655   void fill(size_t zero_pad_bytes) {
00656     make_space(zero_pad_bytes);
00657     for (size_t i = 0; i < zero_pad_bytes; i++) cur_[i] = 0;
00658   }
00659 
00660   // Version for when we know the size is larger.
00661   void fill_big(size_t zero_pad_bytes) {
00662     memset(make_space(zero_pad_bytes), 0, zero_pad_bytes);
00663   }
00664 
00665   void pop(size_t bytes_to_remove) { cur_ += bytes_to_remove; }
00666   void scratch_pop(size_t bytes_to_remove) { scratch_ -= bytes_to_remove; }
00667 
00668  private:
00669   // You shouldn't really be copying instances of this class.
00670   FLATBUFFERS_DELETE_FUNC(vector_downward(const vector_downward &))
00671   FLATBUFFERS_DELETE_FUNC(vector_downward &operator=(const vector_downward &))
00672 
00673   Allocator *allocator_;
00674   bool own_allocator_;
00675   size_t initial_size_;
00676   size_t buffer_minalign_;
00677   size_t reserved_;
00678   uint8_t *buf_;
00679   uint8_t *cur_;  // Points at location between empty (below) and used (above).
00680   uint8_t *scratch_;  // Points to the end of the scratchpad in use.
00681 
00682   void reallocate(size_t len) {
00683     FLATBUFFERS_ASSERT(allocator_);
00684     auto old_reserved = reserved_;
00685     auto old_size = size();
00686     auto old_scratch_size = scratch_size();
00687     reserved_ += (std::max)(len,
00688                             old_reserved ? old_reserved / 2 : initial_size_);
00689     reserved_ = (reserved_ + buffer_minalign_ - 1) & ~(buffer_minalign_ - 1);
00690     if (buf_) {
00691       buf_ = allocator_->reallocate_downward(buf_, old_reserved, reserved_,
00692                                              old_size, old_scratch_size);
00693     } else {
00694       buf_ = allocator_->allocate(reserved_);
00695     }
00696     cur_ = buf_ + reserved_ - old_size;
00697     scratch_ = buf_ + old_scratch_size;
00698   }
00699 };
00700 
00701 // Converts a Field ID to a virtual table offset.
00702 inline voffset_t FieldIndexToOffset(voffset_t field_id) {
00703   // Should correspond to what EndTable() below builds up.
00704   const int fixed_fields = 2;  // Vtable size and Object Size.
00705   return static_cast<voffset_t>((field_id + fixed_fields) * sizeof(voffset_t));
00706 }
00707 
00708 template<typename T, typename Alloc>
00709 const T *data(const std::vector<T, Alloc> &v) {
00710   return v.empty() ? nullptr : &v.front();
00711 }
00712 template<typename T, typename Alloc> T *data(std::vector<T, Alloc> &v) {
00713   return v.empty() ? nullptr : &v.front();
00714 }
00715 
00717 
00727 class FlatBufferBuilder {
00728  public:
00740   explicit FlatBufferBuilder(size_t initial_size = 1024,
00741                              Allocator *allocator = nullptr,
00742                              bool own_allocator = false,
00743                              size_t buffer_minalign =
00744                                  AlignOf<largest_scalar_t>())
00745       : buf_(initial_size, allocator, own_allocator, buffer_minalign),
00746         num_field_loc(0),
00747         max_voffset_(0),
00748         nested(false),
00749         finished(false),
00750         minalign_(1),
00751         force_defaults_(false),
00752         dedup_vtables_(true),
00753         string_pool(nullptr) {
00754     EndianCheck();
00755   }
00756 
00757   ~FlatBufferBuilder() {
00758     if (string_pool) delete string_pool;
00759   }
00760 
00761   void Reset() {
00762     Clear();       // clear builder state
00763     buf_.reset();  // deallocate buffer
00764   }
00765 
00768   void Clear() {
00769     ClearOffsets();
00770     buf_.clear();
00771     nested = false;
00772     finished = false;
00773     minalign_ = 1;
00774     if (string_pool) string_pool->clear();
00775   }
00776 
00779   uoffset_t GetSize() const { return buf_.size(); }
00780 
00784   uint8_t *GetBufferPointer() const {
00785     Finished();
00786     return buf_.data();
00787   }
00788 
00791   uint8_t *GetCurrentBufferPointer() const { return buf_.data(); }
00792 
00798   DetachedBuffer ReleaseBufferPointer() {
00799     Finished();
00800     return buf_.release();
00801   }
00802 
00805   DetachedBuffer Release() {
00806     Finished();
00807     return buf_.release();
00808   }
00809 
00815   size_t GetBufferMinAlignment() {
00816     Finished();
00817     return minalign_;
00818   }
00819 
00821   void Finished() const {
00822     // If you get this assert, you're attempting to get access a buffer
00823     // which hasn't been finished yet. Be sure to call
00824     // FlatBufferBuilder::Finish with your root table.
00825     // If you really need to access an unfinished buffer, call
00826     // GetCurrentBufferPointer instead.
00827     FLATBUFFERS_ASSERT(finished);
00828   }
00830 
00834   void ForceDefaults(bool fd) { force_defaults_ = fd; }
00835 
00838   void DedupVtables(bool dedup) { dedup_vtables_ = dedup; }
00839 
00841   void Pad(size_t num_bytes) { buf_.fill(num_bytes); }
00842 
00843   void TrackMinAlign(size_t elem_size) {
00844     if (elem_size > minalign_) minalign_ = elem_size;
00845   }
00846 
00847   void Align(size_t elem_size) {
00848     TrackMinAlign(elem_size);
00849     buf_.fill(PaddingBytes(buf_.size(), elem_size));
00850   }
00851 
00852   void PushFlatBuffer(const uint8_t *bytes, size_t size) {
00853     PushBytes(bytes, size);
00854     finished = true;
00855   }
00856 
00857   void PushBytes(const uint8_t *bytes, size_t size) { buf_.push(bytes, size); }
00858 
00859   void PopBytes(size_t amount) { buf_.pop(amount); }
00860 
00861   template<typename T> void AssertScalarT() {
00862     // The code assumes power of 2 sizes and endian-swap-ability.
00863     static_assert(flatbuffers::is_scalar<T>::value, "T must be a scalar type");
00864   }
00865 
00866   // Write a single aligned scalar to the buffer
00867   template<typename T> uoffset_t PushElement(T element) {
00868     AssertScalarT<T>();
00869     T litle_endian_element = EndianScalar(element);
00870     Align(sizeof(T));
00871     buf_.push_small(litle_endian_element);
00872     return GetSize();
00873   }
00874 
00875   template<typename T> uoffset_t PushElement(Offset<T> off) {
00876     // Special case for offsets: see ReferTo below.
00877     return PushElement(ReferTo(off.o));
00878   }
00879 
00880   // When writing fields, we track where they are, so we can create correct
00881   // vtables later.
00882   void TrackField(voffset_t field, uoffset_t off) {
00883     FieldLoc fl = { off, field };
00884     buf_.scratch_push_small(fl);
00885     num_field_loc++;
00886     max_voffset_ = (std::max)(max_voffset_, field);
00887   }
00888 
00889   // Like PushElement, but additionally tracks the field this represents.
00890   template<typename T> void AddElement(voffset_t field, T e, T def) {
00891     // We don't serialize values equal to the default.
00892     if (e == def && !force_defaults_) return;
00893     auto off = PushElement(e);
00894     TrackField(field, off);
00895   }
00896 
00897   template<typename T> void AddOffset(voffset_t field, Offset<T> off) {
00898     if (off.IsNull()) return;  // Don't store.
00899     AddElement(field, ReferTo(off.o), static_cast<uoffset_t>(0));
00900   }
00901 
00902   template<typename T> void AddStruct(voffset_t field, const T *structptr) {
00903     if (!structptr) return;  // Default, don't store.
00904     Align(AlignOf<T>());
00905     buf_.push_small(*structptr);
00906     TrackField(field, GetSize());
00907   }
00908 
00909   void AddStructOffset(voffset_t field, uoffset_t off) {
00910     TrackField(field, off);
00911   }
00912 
00913   // Offsets initially are relative to the end of the buffer (downwards).
00914   // This function converts them to be relative to the current location
00915   // in the buffer (when stored here), pointing upwards.
00916   uoffset_t ReferTo(uoffset_t off) {
00917     // Align to ensure GetSize() below is correct.
00918     Align(sizeof(uoffset_t));
00919     // Offset must refer to something already in buffer.
00920     FLATBUFFERS_ASSERT(off && off <= GetSize());
00921     return GetSize() - off + static_cast<uoffset_t>(sizeof(uoffset_t));
00922   }
00923 
00924   void NotNested() {
00925     // If you hit this, you're trying to construct a Table/Vector/String
00926     // during the construction of its parent table (between the MyTableBuilder
00927     // and table.Finish().
00928     // Move the creation of these sub-objects to above the MyTableBuilder to
00929     // not get this assert.
00930     // Ignoring this assert may appear to work in simple cases, but the reason
00931     // it is here is that storing objects in-line may cause vtable offsets
00932     // to not fit anymore. It also leads to vtable duplication.
00933     FLATBUFFERS_ASSERT(!nested);
00934     // If you hit this, fields were added outside the scope of a table.
00935     FLATBUFFERS_ASSERT(!num_field_loc);
00936   }
00937 
00938   // From generated code (or from the parser), we call StartTable/EndTable
00939   // with a sequence of AddElement calls in between.
00940   uoffset_t StartTable() {
00941     NotNested();
00942     nested = true;
00943     return GetSize();
00944   }
00945 
00946   // This finishes one serialized object by generating the vtable if it's a
00947   // table, comparing it against existing vtables, and writing the
00948   // resulting vtable offset.
00949   uoffset_t EndTable(uoffset_t start) {
00950     // If you get this assert, a corresponding StartTable wasn't called.
00951     FLATBUFFERS_ASSERT(nested);
00952     // Write the vtable offset, which is the start of any Table.
00953     // We fill it's value later.
00954     auto vtableoffsetloc = PushElement<soffset_t>(0);
00955     // Write a vtable, which consists entirely of voffset_t elements.
00956     // It starts with the number of offsets, followed by a type id, followed
00957     // by the offsets themselves. In reverse:
00958     // Include space for the last offset and ensure empty tables have a
00959     // minimum size.
00960     max_voffset_ =
00961         (std::max)(static_cast<voffset_t>(max_voffset_ + sizeof(voffset_t)),
00962                    FieldIndexToOffset(0));
00963     buf_.fill_big(max_voffset_);
00964     auto table_object_size = vtableoffsetloc - start;
00965     // Vtable use 16bit offsets.
00966     FLATBUFFERS_ASSERT(table_object_size < 0x10000);
00967     WriteScalar<voffset_t>(buf_.data() + sizeof(voffset_t),
00968                            static_cast<voffset_t>(table_object_size));
00969     WriteScalar<voffset_t>(buf_.data(), max_voffset_);
00970     // Write the offsets into the table
00971     for (auto it = buf_.scratch_end() - num_field_loc * sizeof(FieldLoc);
00972          it < buf_.scratch_end(); it += sizeof(FieldLoc)) {
00973       auto field_location = reinterpret_cast<FieldLoc *>(it);
00974       auto pos = static_cast<voffset_t>(vtableoffsetloc - field_location->off);
00975       // If this asserts, it means you've set a field twice.
00976       FLATBUFFERS_ASSERT(
00977           !ReadScalar<voffset_t>(buf_.data() + field_location->id));
00978       WriteScalar<voffset_t>(buf_.data() + field_location->id, pos);
00979     }
00980     ClearOffsets();
00981     auto vt1 = reinterpret_cast<voffset_t *>(buf_.data());
00982     auto vt1_size = ReadScalar<voffset_t>(vt1);
00983     auto vt_use = GetSize();
00984     // See if we already have generated a vtable with this exact same
00985     // layout before. If so, make it point to the old one, remove this one.
00986     if (dedup_vtables_) {
00987       for (auto it = buf_.scratch_data(); it < buf_.scratch_end();
00988            it += sizeof(uoffset_t)) {
00989         auto vt_offset_ptr = reinterpret_cast<uoffset_t *>(it);
00990         auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(*vt_offset_ptr));
00991         auto vt2_size = *vt2;
00992         if (vt1_size != vt2_size || memcmp(vt2, vt1, vt1_size)) continue;
00993         vt_use = *vt_offset_ptr;
00994         buf_.pop(GetSize() - vtableoffsetloc);
00995         break;
00996       }
00997     }
00998     // If this is a new vtable, remember it.
00999     if (vt_use == GetSize()) { buf_.scratch_push_small(vt_use); }
01000     // Fill the vtable offset we created above.
01001     // The offset points from the beginning of the object to where the
01002     // vtable is stored.
01003     // Offsets default direction is downward in memory for future format
01004     // flexibility (storing all vtables at the start of the file).
01005     WriteScalar(buf_.data_at(vtableoffsetloc),
01006                 static_cast<soffset_t>(vt_use) -
01007                     static_cast<soffset_t>(vtableoffsetloc));
01008 
01009     nested = false;
01010     return vtableoffsetloc;
01011   }
01012 
01013   // DEPRECATED: call the version above instead.
01014   uoffset_t EndTable(uoffset_t start, voffset_t /*numfields*/) {
01015     return EndTable(start);
01016   }
01017 
01018   // This checks a required field has been set in a given table that has
01019   // just been constructed.
01020   template<typename T> void Required(Offset<T> table, voffset_t field) {
01021     auto table_ptr = buf_.data_at(table.o);
01022     auto vtable_ptr = table_ptr - ReadScalar<soffset_t>(table_ptr);
01023     bool ok = ReadScalar<voffset_t>(vtable_ptr + field) != 0;
01024     // If this fails, the caller will show what field needs to be set.
01025     FLATBUFFERS_ASSERT(ok);
01026     (void)ok;
01027   }
01028 
01029   uoffset_t StartStruct(size_t alignment) {
01030     Align(alignment);
01031     return GetSize();
01032   }
01033 
01034   uoffset_t EndStruct() { return GetSize(); }
01035 
01036   void ClearOffsets() {
01037     buf_.scratch_pop(num_field_loc * sizeof(FieldLoc));
01038     num_field_loc = 0;
01039     max_voffset_ = 0;
01040   }
01041 
01042   // Aligns such that when "len" bytes are written, an object can be written
01043   // after it with "alignment" without padding.
01044   void PreAlign(size_t len, size_t alignment) {
01045     TrackMinAlign(alignment);
01046     buf_.fill(PaddingBytes(GetSize() + len, alignment));
01047   }
01048   template<typename T> void PreAlign(size_t len) {
01049     AssertScalarT<T>();
01050     PreAlign(len, sizeof(T));
01051   }
01053 
01058   Offset<String> CreateString(const char *str, size_t len) {
01059     NotNested();
01060     PreAlign<uoffset_t>(len + 1);  // Always 0-terminated.
01061     buf_.fill(1);
01062     PushBytes(reinterpret_cast<const uint8_t *>(str), len);
01063     PushElement(static_cast<uoffset_t>(len));
01064     return Offset<String>(GetSize());
01065   }
01066 
01070   Offset<String> CreateString(const char *str) {
01071     return CreateString(str, strlen(str));
01072   }
01073 
01077   Offset<String> CreateString(char *str) {
01078     return CreateString(str, strlen(str));
01079   }
01080 
01084   Offset<String> CreateString(const std::string &str) {
01085     return CreateString(str.c_str(), str.length());
01086   }
01087 
01088   // clang-format off
01089   #ifdef FLATBUFFERS_HAS_STRING_VIEW
01090 
01091 
01092 
01093   Offset<String> CreateString(flatbuffers::string_view str) {
01094     return CreateString(str.data(), str.size());
01095   }
01096   #endif // FLATBUFFERS_HAS_STRING_VIEW
01097   // clang-format on
01098 
01102   Offset<String> CreateString(const String *str) {
01103     return str ? CreateString(str->c_str(), str->Length()) : 0;
01104   }
01105 
01110   template<typename T> Offset<String> CreateString(const T &str) {
01111     return CreateString(str.c_str(), str.length());
01112   }
01113 
01120   Offset<String> CreateSharedString(const char *str, size_t len) {
01121     if (!string_pool)
01122       string_pool = new StringOffsetMap(StringOffsetCompare(buf_));
01123     auto size_before_string = buf_.size();
01124     // Must first serialize the string, since the set is all offsets into
01125     // buffer.
01126     auto off = CreateString(str, len);
01127     auto it = string_pool->find(off);
01128     // If it exists we reuse existing serialized data!
01129     if (it != string_pool->end()) {
01130       // We can remove the string we serialized.
01131       buf_.pop(buf_.size() - size_before_string);
01132       return *it;
01133     }
01134     // Record this string for future use.
01135     string_pool->insert(off);
01136     return off;
01137   }
01138 
01144   Offset<String> CreateSharedString(const char *str) {
01145     return CreateSharedString(str, strlen(str));
01146   }
01147 
01153   Offset<String> CreateSharedString(const std::string &str) {
01154     return CreateSharedString(str.c_str(), str.length());
01155   }
01156 
01162   Offset<String> CreateSharedString(const String *str) {
01163     return CreateSharedString(str->c_str(), str->Length());
01164   }
01165 
01167   uoffset_t EndVector(size_t len) {
01168     FLATBUFFERS_ASSERT(nested);  // Hit if no corresponding StartVector.
01169     nested = false;
01170     return PushElement(static_cast<uoffset_t>(len));
01171   }
01172 
01173   void StartVector(size_t len, size_t elemsize) {
01174     NotNested();
01175     nested = true;
01176     PreAlign<uoffset_t>(len * elemsize);
01177     PreAlign(len * elemsize, elemsize);  // Just in case elemsize > uoffset_t.
01178   }
01179 
01180   // Call this right before StartVector/CreateVector if you want to force the
01181   // alignment to be something different than what the element size would
01182   // normally dictate.
01183   // This is useful when storing a nested_flatbuffer in a vector of bytes,
01184   // or when storing SIMD floats, etc.
01185   void ForceVectorAlignment(size_t len, size_t elemsize, size_t alignment) {
01186     PreAlign(len * elemsize, alignment);
01187   }
01188 
01190 
01198   template<typename T> Offset<Vector<T>> CreateVector(const T *v, size_t len) {
01199     // If this assert hits, you're specifying a template argument that is
01200     // causing the wrong overload to be selected, remove it.
01201     AssertScalarT<T>();
01202     StartVector(len, sizeof(T));
01203     // clang-format off
01204     #if FLATBUFFERS_LITTLEENDIAN
01205       PushBytes(reinterpret_cast<const uint8_t *>(v), len * sizeof(T));
01206     #else
01207       if (sizeof(T) == 1) {
01208         PushBytes(reinterpret_cast<const uint8_t *>(v), len);
01209       } else {
01210         for (auto i = len; i > 0; ) {
01211           PushElement(v[--i]);
01212         }
01213       }
01214     #endif
01215     // clang-format on
01216     return Offset<Vector<T>>(EndVector(len));
01217   }
01218 
01219   template<typename T>
01220   Offset<Vector<Offset<T>>> CreateVector(const Offset<T> *v, size_t len) {
01221     StartVector(len, sizeof(Offset<T>));
01222     for (auto i = len; i > 0;) { PushElement(v[--i]); }
01223     return Offset<Vector<Offset<T>>>(EndVector(len));
01224   }
01225 
01232   template<typename T> Offset<Vector<T>> CreateVector(const std::vector<T> &v) {
01233     return CreateVector(data(v), v.size());
01234   }
01235 
01236   // vector<bool> may be implemented using a bit-set, so we can't access it as
01237   // an array. Instead, read elements manually.
01238   // Background: https://isocpp.org/blog/2012/11/on-vectorbool
01239   Offset<Vector<uint8_t>> CreateVector(const std::vector<bool> &v) {
01240     StartVector(v.size(), sizeof(uint8_t));
01241     for (auto i = v.size(); i > 0;) {
01242       PushElement(static_cast<uint8_t>(v[--i]));
01243     }
01244     return Offset<Vector<uint8_t>>(EndVector(v.size()));
01245   }
01246 
01247   // clang-format off
01248   #ifndef FLATBUFFERS_CPP98_STL
01249 
01250 
01251 
01252 
01253 
01254 
01255 
01256   template<typename T> Offset<Vector<T>> CreateVector(size_t vector_size,
01257       const std::function<T (size_t i)> &f) {
01258     std::vector<T> elems(vector_size);
01259     for (size_t i = 0; i < vector_size; i++) elems[i] = f(i);
01260     return CreateVector(elems);
01261   }
01262   #endif
01263   // clang-format on
01264 
01274   template<typename T, typename F, typename S>
01275   Offset<Vector<T>> CreateVector(size_t vector_size, F f, S *state) {
01276     std::vector<T> elems(vector_size);
01277     for (size_t i = 0; i < vector_size; i++) elems[i] = f(i, state);
01278     return CreateVector(elems);
01279   }
01280 
01287   Offset<Vector<Offset<String>>> CreateVectorOfStrings(
01288       const std::vector<std::string> &v) {
01289     std::vector<Offset<String>> offsets(v.size());
01290     for (size_t i = 0; i < v.size(); i++) offsets[i] = CreateString(v[i]);
01291     return CreateVector(offsets);
01292   }
01293 
01301   template<typename T>
01302   Offset<Vector<const T *>> CreateVectorOfStructs(const T *v, size_t len) {
01303     StartVector(len * sizeof(T) / AlignOf<T>(), AlignOf<T>());
01304     PushBytes(reinterpret_cast<const uint8_t *>(v), sizeof(T) * len);
01305     return Offset<Vector<const T *>>(EndVector(len));
01306   }
01307 
01316   template<typename T, typename S>
01317   Offset<Vector<const T *>> CreateVectorOfNativeStructs(const S *v,
01318                                                         size_t len) {
01319     extern T Pack(const S &);
01320     typedef T (*Pack_t)(const S &);
01321     std::vector<T> vv(len);
01322     std::transform(v, v + len, vv.begin(), *(Pack_t)&Pack);
01323     return CreateVectorOfStructs<T>(vv.data(), vv.size());
01324   }
01325 
01326   // clang-format off
01327   #ifndef FLATBUFFERS_CPP98_STL
01328 
01329 
01330 
01331 
01332 
01333 
01334 
01335 
01336   template<typename T> Offset<Vector<const T *>> CreateVectorOfStructs(
01337       size_t vector_size, const std::function<void(size_t i, T *)> &filler) {
01338     T* structs = StartVectorOfStructs<T>(vector_size);
01339     for (size_t i = 0; i < vector_size; i++) {
01340       filler(i, structs);
01341       structs++;
01342     }
01343     return EndVectorOfStructs<T>(vector_size);
01344   }
01345   #endif
01346   // clang-format on
01347 
01357   template<typename T, typename F, typename S>
01358   Offset<Vector<const T *>> CreateVectorOfStructs(size_t vector_size, F f,
01359                                                   S *state) {
01360     T *structs = StartVectorOfStructs<T>(vector_size);
01361     for (size_t i = 0; i < vector_size; i++) {
01362       f(i, structs, state);
01363       structs++;
01364     }
01365     return EndVectorOfStructs<T>(vector_size);
01366   }
01367 
01374   template<typename T, typename Alloc>
01375   Offset<Vector<const T *>> CreateVectorOfStructs(
01376       const std::vector<T, Alloc> &v) {
01377     return CreateVectorOfStructs(data(v), v.size());
01378   }
01379 
01388   template<typename T, typename S>
01389   Offset<Vector<const T *>> CreateVectorOfNativeStructs(
01390       const std::vector<S> &v) {
01391     return CreateVectorOfNativeStructs<T, S>(data(v), v.size());
01392   }
01393 
01395   template<typename T> struct StructKeyComparator {
01396     bool operator()(const T &a, const T &b) const {
01397       return a.KeyCompareLessThan(&b);
01398     }
01399 
01400    private:
01401     StructKeyComparator &operator=(const StructKeyComparator &);
01402   };
01404 
01412   template<typename T>
01413   Offset<Vector<const T *>> CreateVectorOfSortedStructs(std::vector<T> *v) {
01414     return CreateVectorOfSortedStructs(data(*v), v->size());
01415   }
01416 
01425   template<typename T, typename S>
01426   Offset<Vector<const T *>> CreateVectorOfSortedNativeStructs(
01427       std::vector<S> *v) {
01428     return CreateVectorOfSortedNativeStructs<T, S>(data(*v), v->size());
01429   }
01430 
01439   template<typename T>
01440   Offset<Vector<const T *>> CreateVectorOfSortedStructs(T *v, size_t len) {
01441     std::sort(v, v + len, StructKeyComparator<T>());
01442     return CreateVectorOfStructs(v, len);
01443   }
01444 
01454   template<typename T, typename S>
01455   Offset<Vector<const T *>> CreateVectorOfSortedNativeStructs(S *v,
01456                                                               size_t len) {
01457     extern T Pack(const S &);
01458     typedef T (*Pack_t)(const S &);
01459     std::vector<T> vv(len);
01460     std::transform(v, v + len, vv.begin(), *(Pack_t)&Pack);
01461     return CreateVectorOfSortedStructs<T>(vv, len);
01462   }
01463 
01465   template<typename T> struct TableKeyComparator {
01466     TableKeyComparator(vector_downward &buf) : buf_(buf) {}
01467     bool operator()(const Offset<T> &a, const Offset<T> &b) const {
01468       auto table_a = reinterpret_cast<T *>(buf_.data_at(a.o));
01469       auto table_b = reinterpret_cast<T *>(buf_.data_at(b.o));
01470       return table_a->KeyCompareLessThan(table_b);
01471     }
01472     vector_downward &buf_;
01473 
01474    private:
01475     TableKeyComparator &operator=(const TableKeyComparator &);
01476   };
01478 
01487   template<typename T>
01488   Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(Offset<T> *v,
01489                                                        size_t len) {
01490     std::sort(v, v + len, TableKeyComparator<T>(buf_));
01491     return CreateVector(v, len);
01492   }
01493 
01501   template<typename T>
01502   Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(
01503       std::vector<Offset<T>> *v) {
01504     return CreateVectorOfSortedTables(data(*v), v->size());
01505   }
01506 
01514   uoffset_t CreateUninitializedVector(size_t len, size_t elemsize,
01515                                       uint8_t **buf) {
01516     NotNested();
01517     StartVector(len, elemsize);
01518     buf_.make_space(len * elemsize);
01519     auto vec_start = GetSize();
01520     auto vec_end = EndVector(len);
01521     *buf = buf_.data_at(vec_start);
01522     return vec_end;
01523   }
01524 
01533   template<typename T>
01534   Offset<Vector<T>> CreateUninitializedVector(size_t len, T **buf) {
01535     return CreateUninitializedVector(len, sizeof(T),
01536                                      reinterpret_cast<uint8_t **>(buf));
01537   }
01538 
01540   template<typename T> Offset<const T *> CreateStruct(const T &structobj) {
01541     NotNested();
01542     Align(AlignOf<T>());
01543     buf_.push_small(structobj);
01544     return Offset<const T *>(GetSize());
01545   }
01546 
01548   static const size_t kFileIdentifierLength = 4;
01549 
01553   template<typename T>
01554   void Finish(Offset<T> root, const char *file_identifier = nullptr) {
01555     Finish(root.o, file_identifier, false);
01556   }
01557 
01565   template<typename T>
01566   void FinishSizePrefixed(Offset<T> root,
01567                           const char *file_identifier = nullptr) {
01568     Finish(root.o, file_identifier, true);
01569   }
01570 
01571  protected:
01572   // You shouldn't really be copying instances of this class.
01573   FlatBufferBuilder(const FlatBufferBuilder &);
01574   FlatBufferBuilder &operator=(const FlatBufferBuilder &);
01575 
01576   void Finish(uoffset_t root, const char *file_identifier, bool size_prefix) {
01577     NotNested();
01578     buf_.clear_scratch();
01579     // This will cause the whole buffer to be aligned.
01580     PreAlign((size_prefix ? sizeof(uoffset_t) : 0) + sizeof(uoffset_t) +
01581                  (file_identifier ? kFileIdentifierLength : 0),
01582              minalign_);
01583     if (file_identifier) {
01584       FLATBUFFERS_ASSERT(strlen(file_identifier) == kFileIdentifierLength);
01585       PushBytes(reinterpret_cast<const uint8_t *>(file_identifier),
01586                 kFileIdentifierLength);
01587     }
01588     PushElement(ReferTo(root));  // Location of root.
01589     if (size_prefix) { PushElement(GetSize()); }
01590     finished = true;
01591   }
01592 
01593   struct FieldLoc {
01594     uoffset_t off;
01595     voffset_t id;
01596   };
01597 
01598   vector_downward buf_;
01599 
01600   // Accumulating offsets of table members while it is being built.
01601   // We store these in the scratch pad of buf_, after the vtable offsets.
01602   uoffset_t num_field_loc;
01603   // Track how much of the vtable is in use, so we can output the most compact
01604   // possible vtable.
01605   voffset_t max_voffset_;
01606 
01607   // Ensure objects are not nested.
01608   bool nested;
01609 
01610   // Ensure the buffer is finished before it is being accessed.
01611   bool finished;
01612 
01613   size_t minalign_;
01614 
01615   bool force_defaults_;  // Serialize values equal to their defaults anyway.
01616 
01617   bool dedup_vtables_;
01618 
01619   struct StringOffsetCompare {
01620     StringOffsetCompare(const vector_downward &buf) : buf_(&buf) {}
01621     bool operator()(const Offset<String> &a, const Offset<String> &b) const {
01622       auto stra = reinterpret_cast<const String *>(buf_->data_at(a.o));
01623       auto strb = reinterpret_cast<const String *>(buf_->data_at(b.o));
01624       return strncmp(stra->c_str(), strb->c_str(),
01625                      (std::min)(stra->size(), strb->size()) + 1) < 0;
01626     }
01627     const vector_downward *buf_;
01628   };
01629 
01630   // For use with CreateSharedString. Instantiated on first use only.
01631   typedef std::set<Offset<String>, StringOffsetCompare> StringOffsetMap;
01632   StringOffsetMap *string_pool;
01633 
01634  private:
01635   // Allocates space for a vector of structures.
01636   // Must be completed with EndVectorOfStructs().
01637   template<typename T> T *StartVectorOfStructs(size_t vector_size) {
01638     StartVector(vector_size * sizeof(T) / AlignOf<T>(), AlignOf<T>());
01639     return reinterpret_cast<T *>(buf_.make_space(vector_size * sizeof(T)));
01640   }
01641 
01642   // End the vector of structues in the flatbuffers.
01643   // Vector should have previously be started with StartVectorOfStructs().
01644   template<typename T>
01645   Offset<Vector<const T *>> EndVectorOfStructs(size_t vector_size) {
01646     return Offset<Vector<const T *>>(EndVector(vector_size));
01647   }
01648 };
01650 
01652 // Helpers to get a typed pointer to the root object contained in the buffer.
01653 template<typename T> T *GetMutableRoot(void *buf) {
01654   EndianCheck();
01655   return reinterpret_cast<T *>(
01656       reinterpret_cast<uint8_t *>(buf) +
01657       EndianScalar(*reinterpret_cast<uoffset_t *>(buf)));
01658 }
01659 
01660 template<typename T> const T *GetRoot(const void *buf) {
01661   return GetMutableRoot<T>(const_cast<void *>(buf));
01662 }
01663 
01664 template<typename T> const T *GetSizePrefixedRoot(const void *buf) {
01665   return GetRoot<T>(reinterpret_cast<const uint8_t *>(buf) + sizeof(uoffset_t));
01666 }
01667 
01671 template<typename T>
01672 T *GetMutableTemporaryPointer(FlatBufferBuilder &fbb, Offset<T> offset) {
01673   return reinterpret_cast<T *>(fbb.GetCurrentBufferPointer() + fbb.GetSize() -
01674                                offset.o);
01675 }
01676 
01677 template<typename T>
01678 const T *GetTemporaryPointer(FlatBufferBuilder &fbb, Offset<T> offset) {
01679   return GetMutableTemporaryPointer<T>(fbb, offset);
01680 }
01681 
01689 inline const char *GetBufferIdentifier(const void *buf, bool size_prefixed = false) {
01690   return reinterpret_cast<const char *>(buf) +
01691          ((size_prefixed) ? 2 * sizeof(uoffset_t) : sizeof(uoffset_t));
01692 }
01693 
01694 // Helper to see if the identifier in a buffer has the expected value.
01695 inline bool BufferHasIdentifier(const void *buf, const char *identifier, bool size_prefixed = false) {
01696   return strncmp(GetBufferIdentifier(buf, size_prefixed), identifier,
01697                  FlatBufferBuilder::kFileIdentifierLength) == 0;
01698 }
01699 
01700 // Helper class to verify the integrity of a FlatBuffer
01701 class Verifier FLATBUFFERS_FINAL_CLASS {
01702  public:
01703   Verifier(const uint8_t *buf, size_t buf_len, uoffset_t _max_depth = 64,
01704            uoffset_t _max_tables = 1000000)
01705       : buf_(buf),
01706         end_(buf + buf_len),
01707         depth_(0),
01708         max_depth_(_max_depth),
01709         num_tables_(0),
01710         max_tables_(_max_tables)
01711   // clang-format off
01712     #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
01713         , upper_bound_(buf)
01714     #endif
01715   // clang-format on
01716   {
01717   }
01718 
01719   // Central location where any verification failures register.
01720   bool Check(bool ok) const {
01721     // clang-format off
01722     #ifdef FLATBUFFERS_DEBUG_VERIFICATION_FAILURE
01723       FLATBUFFERS_ASSERT(ok);
01724     #endif
01725     #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
01726       if (!ok)
01727         upper_bound_ = buf_;
01728     #endif
01729     // clang-format on
01730     return ok;
01731   }
01732 
01733   // Verify any range within the buffer.
01734   bool Verify(const void *elem, size_t elem_len) const {
01735     // clang-format off
01736     #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
01737       auto upper_bound = reinterpret_cast<const uint8_t *>(elem) + elem_len;
01738       if (upper_bound_ < upper_bound)
01739         upper_bound_ =  upper_bound;
01740     #endif
01741     // clang-format on
01742     return Check(elem_len <= (size_t)(end_ - buf_) && elem >= buf_ &&
01743                  elem <= end_ - elem_len);
01744   }
01745 
01746   // Verify a range indicated by sizeof(T).
01747   template<typename T> bool Verify(const void *elem) const {
01748     return Verify(elem, sizeof(T));
01749   }
01750 
01751   // Verify a pointer (may be NULL) of a table type.
01752   template<typename T> bool VerifyTable(const T *table) {
01753     return !table || table->Verify(*this);
01754   }
01755 
01756   // Verify a pointer (may be NULL) of any vector type.
01757   template<typename T> bool Verify(const Vector<T> *vec) const {
01758     const uint8_t *end;
01759     return !vec || VerifyVector(reinterpret_cast<const uint8_t *>(vec),
01760                                 sizeof(T), &end);
01761   }
01762 
01763   // Verify a pointer (may be NULL) of a vector to struct.
01764   template<typename T> bool Verify(const Vector<const T *> *vec) const {
01765     return Verify(reinterpret_cast<const Vector<T> *>(vec));
01766   }
01767 
01768   // Verify a pointer (may be NULL) to string.
01769   bool Verify(const String *str) const {
01770     const uint8_t *end;
01771     return !str ||
01772            (VerifyVector(reinterpret_cast<const uint8_t *>(str), 1, &end) &&
01773             Verify(end, 1) &&      // Must have terminator
01774             Check(*end == '\0'));  // Terminating byte must be 0.
01775   }
01776 
01777   // Common code between vectors and strings.
01778   bool VerifyVector(const uint8_t *vec, size_t elem_size,
01779                     const uint8_t **end) const {
01780     // Check we can read the size field.
01781     if (!Verify<uoffset_t>(vec)) return false;
01782     // Check the whole array. If this is a string, the byte past the array
01783     // must be 0.
01784     auto size = ReadScalar<uoffset_t>(vec);
01785     auto max_elems = FLATBUFFERS_MAX_BUFFER_SIZE / elem_size;
01786     if (!Check(size < max_elems))
01787       return false;  // Protect against byte_size overflowing.
01788     auto byte_size = sizeof(size) + elem_size * size;
01789     *end = vec + byte_size;
01790     return Verify(vec, byte_size);
01791   }
01792 
01793   // Special case for string contents, after the above has been called.
01794   bool VerifyVectorOfStrings(const Vector<Offset<String>> *vec) const {
01795     if (vec) {
01796       for (uoffset_t i = 0; i < vec->size(); i++) {
01797         if (!Verify(vec->Get(i))) return false;
01798       }
01799     }
01800     return true;
01801   }
01802 
01803   // Special case for table contents, after the above has been called.
01804   template<typename T> bool VerifyVectorOfTables(const Vector<Offset<T>> *vec) {
01805     if (vec) {
01806       for (uoffset_t i = 0; i < vec->size(); i++) {
01807         if (!vec->Get(i)->Verify(*this)) return false;
01808       }
01809     }
01810     return true;
01811   }
01812 
01813   template<typename T>
01814   bool VerifyBufferFromStart(const char *identifier, const uint8_t *start) {
01815     if (identifier &&
01816         (size_t(end_ - start) < 2 * sizeof(flatbuffers::uoffset_t) ||
01817          !BufferHasIdentifier(start, identifier))) {
01818       return false;
01819     }
01820 
01821     // Call T::Verify, which must be in the generated code for this type.
01822     auto o = VerifyOffset(start);
01823     return o && reinterpret_cast<const T *>(start + o)->Verify(*this)
01824 #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
01825            && GetComputedSize()
01826 #endif
01827         ;
01828   }
01829 
01830   // Verify this whole buffer, starting with root type T.
01831   template<typename T> bool VerifyBuffer() { return VerifyBuffer<T>(nullptr); }
01832 
01833   template<typename T> bool VerifyBuffer(const char *identifier) {
01834     return VerifyBufferFromStart<T>(identifier, buf_);
01835   }
01836 
01837   template<typename T> bool VerifySizePrefixedBuffer(const char *identifier) {
01838     return Verify<uoffset_t>(buf_) &&
01839            ReadScalar<uoffset_t>(buf_) == end_ - buf_ - sizeof(uoffset_t) &&
01840            VerifyBufferFromStart<T>(identifier, buf_ + sizeof(uoffset_t));
01841   }
01842 
01843   uoffset_t VerifyOffset(const uint8_t *start) const {
01844     if (!Verify<uoffset_t>(start)) return false;
01845     auto o = ReadScalar<uoffset_t>(start);
01846     Check(o != 0);
01847     return o;
01848   }
01849 
01850   // Called at the start of a table to increase counters measuring data
01851   // structure depth and amount, and possibly bails out with false if
01852   // limits set by the constructor have been hit. Needs to be balanced
01853   // with EndTable().
01854   bool VerifyComplexity() {
01855     depth_++;
01856     num_tables_++;
01857     return Check(depth_ <= max_depth_ && num_tables_ <= max_tables_);
01858   }
01859 
01860   // Called at the end of a table to pop the depth count.
01861   bool EndTable() {
01862     depth_--;
01863     return true;
01864   }
01865 
01866   // clang-format off
01867   #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
01868   // Returns the message size in bytes
01869   size_t GetComputedSize() const {
01870     uintptr_t size = upper_bound_ - buf_;
01871     // Align the size to uoffset_t
01872     size = (size - 1 + sizeof(uoffset_t)) & ~(sizeof(uoffset_t) - 1);
01873     return (buf_  + size > end_) ?  0 : size;
01874   }
01875   #endif
01876   // clang-format on
01877 
01878  private:
01879   const uint8_t *buf_;
01880   const uint8_t *end_;
01881   uoffset_t depth_;
01882   uoffset_t max_depth_;
01883   uoffset_t num_tables_;
01884   uoffset_t max_tables_;
01885   // clang-format off
01886   #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
01887     mutable const uint8_t *upper_bound_;
01888   #endif
01889   // clang-format on
01890 };
01891 
01892 // Convenient way to bundle a buffer and its length, to pass it around
01893 // typed by its root.
01894 // A BufferRef does not own its buffer.
01895 struct BufferRefBase {};  // for std::is_base_of
01896 template<typename T> struct BufferRef : BufferRefBase {
01897   BufferRef() : buf(nullptr), len(0), must_free(false) {}
01898   BufferRef(uint8_t *_buf, uoffset_t _len)
01899       : buf(_buf), len(_len), must_free(false) {}
01900 
01901   ~BufferRef() {
01902     if (must_free) free(buf);
01903   }
01904 
01905   const T *GetRoot() const { return flatbuffers::GetRoot<T>(buf); }
01906 
01907   bool Verify() {
01908     Verifier verifier(buf, len);
01909     return verifier.VerifyBuffer<T>(nullptr);
01910   }
01911 
01912   uint8_t *buf;
01913   uoffset_t len;
01914   bool must_free;
01915 };
01916 
01917 // "structs" are flat structures that do not have an offset table, thus
01918 // always have all members present and do not support forwards/backwards
01919 // compatible extensions.
01920 
01921 class Struct FLATBUFFERS_FINAL_CLASS {
01922  public:
01923   template<typename T> T GetField(uoffset_t o) const {
01924     return ReadScalar<T>(&data_[o]);
01925   }
01926 
01927   template<typename T> T GetStruct(uoffset_t o) const {
01928     return reinterpret_cast<T>(&data_[o]);
01929   }
01930 
01931   const uint8_t *GetAddressOf(uoffset_t o) const { return &data_[o]; }
01932   uint8_t *GetAddressOf(uoffset_t o) { return &data_[o]; }
01933 
01934  private:
01935   uint8_t data_[1];
01936 };
01937 
01938 // "tables" use an offset table (possibly shared) that allows fields to be
01939 // omitted and added at will, but uses an extra indirection to read.
01940 class Table {
01941  public:
01942   const uint8_t *GetVTable() const {
01943     return data_ - ReadScalar<soffset_t>(data_);
01944   }
01945 
01946   // This gets the field offset for any of the functions below it, or 0
01947   // if the field was not present.
01948   voffset_t GetOptionalFieldOffset(voffset_t field) const {
01949     // The vtable offset is always at the start.
01950     auto vtable = GetVTable();
01951     // The first element is the size of the vtable (fields + type id + itself).
01952     auto vtsize = ReadScalar<voffset_t>(vtable);
01953     // If the field we're accessing is outside the vtable, we're reading older
01954     // data, so it's the same as if the offset was 0 (not present).
01955     return field < vtsize ? ReadScalar<voffset_t>(vtable + field) : 0;
01956   }
01957 
01958   template<typename T> T GetField(voffset_t field, T defaultval) const {
01959     auto field_offset = GetOptionalFieldOffset(field);
01960     return field_offset ? ReadScalar<T>(data_ + field_offset) : defaultval;
01961   }
01962 
01963   template<typename P> P GetPointer(voffset_t field) {
01964     auto field_offset = GetOptionalFieldOffset(field);
01965     auto p = data_ + field_offset;
01966     return field_offset ? reinterpret_cast<P>(p + ReadScalar<uoffset_t>(p))
01967                         : nullptr;
01968   }
01969   template<typename P> P GetPointer(voffset_t field) const {
01970     return const_cast<Table *>(this)->GetPointer<P>(field);
01971   }
01972 
01973   template<typename P> P GetStruct(voffset_t field) const {
01974     auto field_offset = GetOptionalFieldOffset(field);
01975     auto p = const_cast<uint8_t *>(data_ + field_offset);
01976     return field_offset ? reinterpret_cast<P>(p) : nullptr;
01977   }
01978 
01979   template<typename T> bool SetField(voffset_t field, T val, T def) {
01980     auto field_offset = GetOptionalFieldOffset(field);
01981     if (!field_offset) return val == def;
01982     WriteScalar(data_ + field_offset, val);
01983     return true;
01984   }
01985 
01986   bool SetPointer(voffset_t field, const uint8_t *val) {
01987     auto field_offset = GetOptionalFieldOffset(field);
01988     if (!field_offset) return false;
01989     WriteScalar(data_ + field_offset,
01990                 static_cast<uoffset_t>(val - (data_ + field_offset)));
01991     return true;
01992   }
01993 
01994   uint8_t *GetAddressOf(voffset_t field) {
01995     auto field_offset = GetOptionalFieldOffset(field);
01996     return field_offset ? data_ + field_offset : nullptr;
01997   }
01998   const uint8_t *GetAddressOf(voffset_t field) const {
01999     return const_cast<Table *>(this)->GetAddressOf(field);
02000   }
02001 
02002   bool CheckField(voffset_t field) const {
02003     return GetOptionalFieldOffset(field) != 0;
02004   }
02005 
02006   // Verify the vtable of this table.
02007   // Call this once per table, followed by VerifyField once per field.
02008   bool VerifyTableStart(Verifier &verifier) const {
02009     // Check the vtable offset.
02010     if (!verifier.Verify<soffset_t>(data_)) return false;
02011     auto vtable = GetVTable();
02012     // Check the vtable size field, then check vtable fits in its entirety.
02013     return verifier.VerifyComplexity() && verifier.Verify<voffset_t>(vtable) &&
02014            (ReadScalar<voffset_t>(vtable) & (sizeof(voffset_t) - 1)) == 0 &&
02015            verifier.Verify(vtable, ReadScalar<voffset_t>(vtable));
02016   }
02017 
02018   // Verify a particular field.
02019   template<typename T>
02020   bool VerifyField(const Verifier &verifier, voffset_t field) const {
02021     // Calling GetOptionalFieldOffset should be safe now thanks to
02022     // VerifyTable().
02023     auto field_offset = GetOptionalFieldOffset(field);
02024     // Check the actual field.
02025     return !field_offset || verifier.Verify<T>(data_ + field_offset);
02026   }
02027 
02028   // VerifyField for required fields.
02029   template<typename T>
02030   bool VerifyFieldRequired(const Verifier &verifier, voffset_t field) const {
02031     auto field_offset = GetOptionalFieldOffset(field);
02032     return verifier.Check(field_offset != 0) &&
02033            verifier.Verify<T>(data_ + field_offset);
02034   }
02035 
02036   // Versions for offsets.
02037   bool VerifyOffset(const Verifier &verifier, voffset_t field) const {
02038     auto field_offset = GetOptionalFieldOffset(field);
02039     return !field_offset || verifier.VerifyOffset(data_ + field_offset);
02040   }
02041 
02042   bool VerifyOffsetRequired(const Verifier &verifier, voffset_t field) const {
02043     auto field_offset = GetOptionalFieldOffset(field);
02044     return verifier.Check(field_offset != 0) &&
02045            verifier.VerifyOffset(data_ + field_offset);
02046   }
02047 
02048  private:
02049   // private constructor & copy constructor: you obtain instances of this
02050   // class by pointing to existing data only
02051   Table();
02052   Table(const Table &other);
02053 
02054   uint8_t data_[1];
02055 };
02056 
02061 inline const uint8_t *GetBufferStartFromRootPointer(const void *root) {
02062   auto table = reinterpret_cast<const Table *>(root);
02063   auto vtable = table->GetVTable();
02064   // Either the vtable is before the root or after the root.
02065   auto start = (std::min)(vtable, reinterpret_cast<const uint8_t *>(root));
02066   // Align to at least sizeof(uoffset_t).
02067   start = reinterpret_cast<const uint8_t *>(reinterpret_cast<uintptr_t>(start) &
02068                                             ~(sizeof(uoffset_t) - 1));
02069   // Additionally, there may be a file_identifier in the buffer, and the root
02070   // offset. The buffer may have been aligned to any size between
02071   // sizeof(uoffset_t) and FLATBUFFERS_MAX_ALIGNMENT (see "force_align").
02072   // Sadly, the exact alignment is only known when constructing the buffer,
02073   // since it depends on the presence of values with said alignment properties.
02074   // So instead, we simply look at the next uoffset_t values (root,
02075   // file_identifier, and alignment padding) to see which points to the root.
02076   // None of the other values can "impersonate" the root since they will either
02077   // be 0 or four ASCII characters.
02078   static_assert(FlatBufferBuilder::kFileIdentifierLength == sizeof(uoffset_t),
02079                 "file_identifier is assumed to be the same size as uoffset_t");
02080   for (auto possible_roots = FLATBUFFERS_MAX_ALIGNMENT / sizeof(uoffset_t) + 1;
02081        possible_roots; possible_roots--) {
02082     start -= sizeof(uoffset_t);
02083     if (ReadScalar<uoffset_t>(start) + start ==
02084         reinterpret_cast<const uint8_t *>(root))
02085       return start;
02086   }
02087   // We didn't find the root, either the "root" passed isn't really a root,
02088   // or the buffer is corrupt.
02089   // Assert, because calling this function with bad data may cause reads
02090   // outside of buffer boundaries.
02091   FLATBUFFERS_ASSERT(false);
02092   return nullptr;
02093 }
02094 
02096 inline uoffset_t GetPrefixedSize(const uint8_t* buf){ return ReadScalar<uoffset_t>(buf); }
02097 
02098 // Base class for native objects (FlatBuffer data de-serialized into native
02099 // C++ data structures).
02100 // Contains no functionality, purely documentative.
02101 struct NativeTable {};
02102 
02111 typedef uint64_t hash_value_t;
02112 // clang-format off
02113 #ifdef FLATBUFFERS_CPP98_STL
02114   typedef void (*resolver_function_t)(void **pointer_adr, hash_value_t hash);
02115   typedef hash_value_t (*rehasher_function_t)(void *pointer);
02116 #else
02117   typedef std::function<void (void **pointer_adr, hash_value_t hash)>
02118           resolver_function_t;
02119   typedef std::function<hash_value_t (void *pointer)> rehasher_function_t;
02120 #endif
02121 // clang-format on
02122 
02123 // Helper function to test if a field is present, using any of the field
02124 // enums in the generated code.
02125 // `table` must be a generated table type. Since this is a template parameter,
02126 // this is not typechecked to be a subclass of Table, so beware!
02127 // Note: this function will return false for fields equal to the default
02128 // value, since they're not stored in the buffer (unless force_defaults was
02129 // used).
02130 template<typename T> bool IsFieldPresent(const T *table, voffset_t field) {
02131   // Cast, since Table is a private baseclass of any table types.
02132   return reinterpret_cast<const Table *>(table)->CheckField(field);
02133 }
02134 
02135 // Utility function for reverse lookups on the EnumNames*() functions
02136 // (in the generated C++ code)
02137 // names must be NULL terminated.
02138 inline int LookupEnum(const char **names, const char *name) {
02139   for (const char **p = names; *p; p++)
02140     if (!strcmp(*p, name)) return static_cast<int>(p - names);
02141   return -1;
02142 }
02143 
02144 // These macros allow us to layout a struct with a guarantee that they'll end
02145 // up looking the same on different compilers and platforms.
02146 // It does this by disallowing the compiler to do any padding, and then
02147 // does padding itself by inserting extra padding fields that make every
02148 // element aligned to its own size.
02149 // Additionally, it manually sets the alignment of the struct as a whole,
02150 // which is typically its largest element, or a custom size set in the schema
02151 // by the force_align attribute.
02152 // These are used in the generated code only.
02153 
02154 // clang-format off
02155 #if defined(_MSC_VER)
02156   #define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \
02157     __pragma(pack(1)); \
02158     struct __declspec(align(alignment))
02159   #define FLATBUFFERS_STRUCT_END(name, size) \
02160     __pragma(pack()); \
02161     static_assert(sizeof(name) == size, "compiler breaks packing rules")
02162 #elif defined(__GNUC__) || defined(__clang__)
02163   #define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \
02164     _Pragma("pack(1)") \
02165     struct __attribute__((aligned(alignment)))
02166   #define FLATBUFFERS_STRUCT_END(name, size) \
02167     _Pragma("pack()") \
02168     static_assert(sizeof(name) == size, "compiler breaks packing rules")
02169 #else
02170   #error Unknown compiler, please define structure alignment macros
02171 #endif
02172 // clang-format on
02173 
02174 // Minimal reflection via code generation.
02175 // Besides full-fat reflection (see reflection.h) and parsing/printing by
02176 // loading schemas (see idl.h), we can also have code generation for mimimal
02177 // reflection data which allows pretty-printing and other uses without needing
02178 // a schema or a parser.
02179 // Generate code with --reflect-types (types only) or --reflect-names (names
02180 // also) to enable.
02181 // See minireflect.h for utilities using this functionality.
02182 
02183 // These types are organized slightly differently as the ones in idl.h.
02184 enum SequenceType { ST_TABLE, ST_STRUCT, ST_UNION, ST_ENUM };
02185 
02186 // Scalars have the same order as in idl.h
02187 // clang-format off
02188 #define FLATBUFFERS_GEN_ELEMENTARY_TYPES(ET) \
02189   ET(ET_UTYPE) \
02190   ET(ET_BOOL) \
02191   ET(ET_CHAR) \
02192   ET(ET_UCHAR) \
02193   ET(ET_SHORT) \
02194   ET(ET_USHORT) \
02195   ET(ET_INT) \
02196   ET(ET_UINT) \
02197   ET(ET_LONG) \
02198   ET(ET_ULONG) \
02199   ET(ET_FLOAT) \
02200   ET(ET_DOUBLE) \
02201   ET(ET_STRING) \
02202   ET(ET_SEQUENCE)  // See SequenceType.
02203 
02204 enum ElementaryType {
02205   #define FLATBUFFERS_ET(E) E,
02206     FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET)
02207   #undef FLATBUFFERS_ET
02208 };
02209 
02210 inline const char * const *ElementaryTypeNames() {
02211   static const char * const names[] = {
02212     #define FLATBUFFERS_ET(E) #E,
02213       FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET)
02214     #undef FLATBUFFERS_ET
02215   };
02216   return names;
02217 }
02218 // clang-format on
02219 
02220 // Basic type info cost just 16bits per field!
02221 struct TypeCode {
02222   uint16_t base_type : 4;  // ElementaryType
02223   uint16_t is_vector : 1;
02224   int16_t sequence_ref : 11;  // Index into type_refs below, or -1 for none.
02225 };
02226 
02227 static_assert(sizeof(TypeCode) == 2, "TypeCode");
02228 
02229 struct TypeTable;
02230 
02231 // Signature of the static method present in each type.
02232 typedef const TypeTable *(*TypeFunction)();
02233 
02234 struct TypeTable {
02235   SequenceType st;
02236   size_t num_elems;  // of each of the arrays below.
02237   const TypeCode *type_codes;
02238   const TypeFunction *type_refs;
02239   const int32_t *values;  // Only set for non-consecutive enum/union or structs.
02240   const char * const *names;     // Only set if compiled with --reflect-names.
02241 };
02242 
02243 // String which identifies the current version of FlatBuffers.
02244 // flatbuffer_version_string is used by Google developers to identify which
02245 // applications uploaded to Google Play are using this library.  This allows
02246 // the development team at Google to determine the popularity of the library.
02247 // How it works: Applications that are uploaded to the Google Play Store are
02248 // scanned for this version string.  We track which applications are using it
02249 // to measure popularity.  You are free to remove it (of course) but we would
02250 // appreciate if you left it in.
02251 
02252 // Weak linkage is culled by VS & doesn't work on cygwin.
02253 // clang-format off
02254 #if !defined(_WIN32) && !defined(__CYGWIN__)
02255 
02256 extern volatile __attribute__((weak)) const char *flatbuffer_version_string;
02257 volatile __attribute__((weak)) const char *flatbuffer_version_string =
02258   "FlatBuffers "
02259   FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "."
02260   FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR) "."
02261   FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION);
02262 
02263 #endif  // !defined(_WIN32) && !defined(__CYGWIN__)
02264 
02265 #define FLATBUFFERS_DEFINE_BITMASK_OPERATORS(E, T)\
02266     inline E operator | (E lhs, E rhs){\
02267         return E(T(lhs) | T(rhs));\
02268     }\
02269     inline E operator & (E lhs, E rhs){\
02270         return E(T(lhs) & T(rhs));\
02271     }\
02272     inline E operator ^ (E lhs, E rhs){\
02273         return E(T(lhs) ^ T(rhs));\
02274     }\
02275     inline E operator ~ (E lhs){\
02276         return E(~T(lhs));\
02277     }\
02278     inline E operator |= (E &lhs, E rhs){\
02279         lhs = lhs | rhs;\
02280         return lhs;\
02281     }\
02282     inline E operator &= (E &lhs, E rhs){\
02283         lhs = lhs & rhs;\
02284         return lhs;\
02285     }\
02286     inline E operator ^= (E &lhs, E rhs){\
02287         lhs = lhs ^ rhs;\
02288         return lhs;\
02289     }\
02290     inline bool operator !(E rhs) \
02291     {\
02292         return !bool(T(rhs)); \
02293     }
02294 
02295 }  // namespace flatbuffers
02296 
02297 #if defined(_MSC_VER)
02298   #pragma warning(pop)
02299 #endif
02300 // clang-format on
02301 
02302 #endif  // FLATBUFFERS_H_


behaviortree_cpp
Author(s): Michele Colledanchise, Davide Faconti
autogenerated on Sat Feb 2 2019 03:50:10