Home | History | Annotate | Download | only in flatbuffers
      1 /*
      2  * Copyright 2017 Google Inc. All rights reserved.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef FLATBUFFERS_FLEXBUFFERS_H_
     18 #define FLATBUFFERS_FLEXBUFFERS_H_
     19 
     20 // We use the basic binary writing functions from the regular FlatBuffers.
     21 #include "flatbuffers/flatbuffers.h"
     22 #include "flatbuffers/util.h"
     23 
     24 #ifdef _MSC_VER
     25 #include <intrin.h>
     26 #endif
     27 
     28 namespace flexbuffers {
     29 
     30 class Reference;
     31 class Map;
     32 
     33 // These are used in the lower 2 bits of a type field to determine the size of
     34 // the elements (and or size field) of the item pointed to (e.g. vector).
     35 enum BitWidth {
     36   BIT_WIDTH_8 = 0,
     37   BIT_WIDTH_16 = 1,
     38   BIT_WIDTH_32 = 2,
     39   BIT_WIDTH_64 = 3,
     40 };
     41 
     42 // These are used as the upper 6 bits of a type field to indicate the actual
     43 // type.
     44 enum Type {
     45   TYPE_NULL = 0,
     46   TYPE_INT = 1,
     47   TYPE_UINT = 2,
     48   TYPE_FLOAT = 3,
     49   // Types above stored inline, types below store an offset.
     50   TYPE_KEY = 4,
     51   TYPE_STRING = 5,
     52   TYPE_INDIRECT_INT = 6,
     53   TYPE_INDIRECT_UINT = 7,
     54   TYPE_INDIRECT_FLOAT = 8,
     55   TYPE_MAP = 9,
     56   TYPE_VECTOR = 10,        // Untyped.
     57   TYPE_VECTOR_INT = 11,    // Typed any size (stores no type table).
     58   TYPE_VECTOR_UINT = 12,
     59   TYPE_VECTOR_FLOAT = 13,
     60   TYPE_VECTOR_KEY = 14,
     61   TYPE_VECTOR_STRING = 15,
     62   TYPE_VECTOR_INT2 = 16,   // Typed tuple (no type table, no size field).
     63   TYPE_VECTOR_UINT2 = 17,
     64   TYPE_VECTOR_FLOAT2 = 18,
     65   TYPE_VECTOR_INT3 = 19,   // Typed triple (no type table, no size field).
     66   TYPE_VECTOR_UINT3 = 20,
     67   TYPE_VECTOR_FLOAT3 = 21,
     68   TYPE_VECTOR_INT4 = 22,   // Typed quad (no type table, no size field).
     69   TYPE_VECTOR_UINT4 = 23,
     70   TYPE_VECTOR_FLOAT4 = 24,
     71   TYPE_BLOB = 25,
     72 };
     73 
     74 inline bool IsInline(Type t) { return t <= TYPE_FLOAT; }
     75 
     76 inline bool IsTypedVectorElementType(Type t) {
     77   return t >= TYPE_INT && t <= TYPE_STRING;
     78 }
     79 
     80 inline bool IsTypedVector(Type t) {
     81   return t >= TYPE_VECTOR_INT && t <= TYPE_VECTOR_STRING;
     82 }
     83 
     84 inline bool IsFixedTypedVector(Type t) {
     85   return t >= TYPE_VECTOR_INT2 && t <= TYPE_VECTOR_FLOAT4;
     86 }
     87 
     88 inline Type ToTypedVector(Type t, int fixed_len = 0) {
     89   assert(IsTypedVectorElementType(t));
     90   switch (fixed_len) {
     91     case 0: return static_cast<Type>(t - TYPE_INT + TYPE_VECTOR_INT);
     92     case 2: return static_cast<Type>(t - TYPE_INT + TYPE_VECTOR_INT2);
     93     case 3: return static_cast<Type>(t - TYPE_INT + TYPE_VECTOR_INT3);
     94     case 4: return static_cast<Type>(t - TYPE_INT + TYPE_VECTOR_INT4);
     95     default: assert(0); return TYPE_NULL;
     96   }
     97 }
     98 
     99 inline Type ToTypedVectorElementType(Type t) {
    100   assert(IsTypedVector(t));
    101   return static_cast<Type>(t - TYPE_VECTOR_INT + TYPE_INT);
    102 }
    103 
    104 inline Type ToFixedTypedVectorElementType(Type t, uint8_t *len) {
    105   assert(IsFixedTypedVector(t));
    106   auto fixed_type = t - TYPE_VECTOR_INT2;
    107   *len = fixed_type / 3 + 2;  // 3 types each, starting from length 2.
    108   return static_cast<Type>(fixed_type % 3 + TYPE_INT);
    109 }
    110 
    111 // TODO: implement proper support for 8/16bit floats, or decide not to
    112 // support them.
    113 typedef int16_t half;
    114 typedef int8_t quarter;
    115 
    116 // TODO: can we do this without conditionals using intrinsics or inline asm
    117 // on some platforms? Given branch prediction the method below should be
    118 // decently quick, but it is the most frequently executed function.
    119 // We could do an (unaligned) 64-bit read if we ifdef out the platforms for
    120 // which that doesn't work (or where we'd read into un-owned memory).
    121 template <typename R, typename T1, typename T2, typename T4, typename T8>
    122 R ReadSizedScalar(const uint8_t *data, uint8_t byte_width) {
    123   return byte_width < 4
    124     ? (byte_width < 2 ? static_cast<R>(flatbuffers::ReadScalar<T1>(data))
    125                       : static_cast<R>(flatbuffers::ReadScalar<T2>(data)))
    126     : (byte_width < 8 ? static_cast<R>(flatbuffers::ReadScalar<T4>(data))
    127                       : static_cast<R>(flatbuffers::ReadScalar<T8>(data)));
    128 }
    129 
    130 
    131 inline int64_t ReadInt64(const uint8_t *data, uint8_t byte_width) {
    132   return ReadSizedScalar<int64_t, int8_t, int16_t, int32_t, int64_t>(data,
    133            byte_width);
    134 }
    135 
    136 inline uint64_t ReadUInt64(const uint8_t *data, uint8_t byte_width) {
    137   // This is the "hottest" function (all offset lookups use this), so worth
    138   // optimizing if possible.
    139   // TODO: GCC apparently replaces memcpy by a rep movsb, but only if count is a
    140   // constant, which here it isn't. Test if memcpy is still faster than
    141   // the conditionals in ReadSizedScalar. Can also use inline asm.
    142   #ifdef _MSC_VER
    143     uint64_t u = 0;
    144     __movsb(reinterpret_cast<uint8_t *>(&u),
    145             reinterpret_cast<const uint8_t *>(data), byte_width);
    146     return flatbuffers::EndianScalar(u);
    147   #else
    148     return ReadSizedScalar<uint64_t, uint8_t, uint16_t, uint32_t, uint64_t>(
    149              data, byte_width);
    150   #endif
    151 }
    152 
    153 inline double ReadDouble(const uint8_t *data, uint8_t byte_width) {
    154   return ReadSizedScalar<double, quarter, half, float, double>(data,
    155            byte_width);
    156 }
    157 
    158 const uint8_t *Indirect(const uint8_t *offset, uint8_t byte_width) {
    159   return offset - ReadUInt64(offset, byte_width);
    160 }
    161 
    162 template<typename T> const uint8_t *Indirect(const uint8_t *offset) {
    163   return offset - flatbuffers::ReadScalar<T>(offset);
    164 }
    165 
    166 static BitWidth WidthU(uint64_t u) {
    167   #define FLATBUFFERS_GET_FIELD_BIT_WIDTH(value, width) { \
    168     if (!((u) & ~((1ULL << (width)) - 1ULL))) return BIT_WIDTH_##width; \
    169   }
    170   FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 8);
    171   FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 16);
    172   FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 32);
    173   #undef FLATBUFFERS_GET_FIELD_BIT_WIDTH
    174   return BIT_WIDTH_64;
    175 }
    176 
    177 static BitWidth WidthI(int64_t i) {
    178   auto u = static_cast<uint64_t>(i) << 1;
    179   return WidthU(i >= 0 ? u : ~u);
    180 }
    181 
    182 static BitWidth WidthF(double f) {
    183   return static_cast<double>(static_cast<float>(f)) == f ? BIT_WIDTH_32
    184                                                          : BIT_WIDTH_64;
    185 }
    186 
    187 // Base class of all types below.
    188 // Points into the data buffer and allows access to one type.
    189 class Object {
    190  public:
    191   Object(const uint8_t *data, uint8_t byte_width)
    192     : data_(data), byte_width_(byte_width) {}
    193 
    194  protected:
    195   const uint8_t *data_;
    196   uint8_t byte_width_;
    197 };
    198 
    199 // Stores size in `byte_width_` bytes before data_ pointer.
    200 class Sized : public Object {
    201  public:
    202   Sized(const uint8_t *data, uint8_t byte_width) : Object(data, byte_width) {}
    203   size_t size() const {
    204     return static_cast<size_t>(ReadUInt64(data_ - byte_width_, byte_width_));
    205   }
    206 };
    207 
    208 class String : public Sized {
    209  public:
    210   String(const uint8_t *data, uint8_t byte_width)
    211     : Sized(data, byte_width) {}
    212 
    213   size_t length() const { return size(); }
    214   const char *c_str() const { return reinterpret_cast<const char *>(data_); }
    215 
    216   static String EmptyString() {
    217     static const uint8_t empty_string[] = { 0/*len*/, 0/*terminator*/ };
    218     return String(empty_string + 1, 1);
    219   }
    220   bool IsTheEmptyString() const { return data_ == EmptyString().data_; }
    221 };
    222 
    223 class Blob : public Sized {
    224  public:
    225   Blob(const uint8_t *data, uint8_t byte_width)
    226     : Sized(data, byte_width) {}
    227 
    228   static Blob EmptyBlob() {
    229     static const uint8_t empty_blob[] = { 0/*len*/ };
    230     return Blob(empty_blob + 1, 1);
    231   }
    232   bool IsTheEmptyBlob() const { return data_ == EmptyBlob().data_; }
    233 };
    234 
    235 class Vector : public Sized {
    236  public:
    237   Vector(const uint8_t *data, uint8_t byte_width)
    238     : Sized(data, byte_width) {}
    239 
    240   Reference operator[](size_t i) const;
    241 
    242   static Vector EmptyVector() {
    243     static const uint8_t empty_vector[] = { 0/*len*/ };
    244     return Vector(empty_vector + 1, 1);
    245   }
    246   bool IsTheEmptyVector() const { return data_ == EmptyVector().data_; }
    247 };
    248 
    249 class TypedVector : public Sized {
    250  public:
    251   TypedVector(const uint8_t *data, uint8_t byte_width, Type element_type)
    252     : Sized(data, byte_width), type_(element_type) {}
    253 
    254   Reference operator[](size_t i) const;
    255 
    256   static TypedVector EmptyTypedVector() {
    257     static const uint8_t empty_typed_vector[] = { 0/*len*/ };
    258     return TypedVector(empty_typed_vector + 1, 1, TYPE_INT);
    259   }
    260   bool IsTheEmptyVector() const {
    261     return data_ == TypedVector::EmptyTypedVector().data_;
    262   }
    263 
    264   Type ElementType() { return type_; }
    265 
    266  private:
    267   Type type_;
    268 
    269   friend Map;
    270 };
    271 
    272 class FixedTypedVector : public Object {
    273  public:
    274   FixedTypedVector(const uint8_t *data, uint8_t byte_width, Type element_type,
    275                    uint8_t len)
    276     : Object(data, byte_width), type_(element_type), len_(len) {}
    277 
    278   Reference operator[](size_t i) const;
    279 
    280   static FixedTypedVector EmptyFixedTypedVector() {
    281     static const uint8_t fixed_empty_vector[] = { 0/* unused */ };
    282     return FixedTypedVector(fixed_empty_vector, 1, TYPE_INT, 0);
    283   }
    284   bool IsTheEmptyFixedTypedVector() const {
    285     return data_ == FixedTypedVector::EmptyFixedTypedVector().data_;
    286   }
    287 
    288   Type ElementType() { return type_; }
    289   uint8_t size() { return len_; }
    290 
    291  private:
    292   Type type_;
    293   uint8_t len_;
    294 };
    295 
    296 class Map : public Vector {
    297  public:
    298   Map(const uint8_t *data, uint8_t byte_width)
    299     : Vector(data, byte_width) {}
    300 
    301   Reference operator[](const char *key) const;
    302   Reference operator[](const std::string &key) const;
    303 
    304   Vector Values() const { return Vector(data_, byte_width_); }
    305 
    306   TypedVector Keys() const {
    307     const size_t num_prefixed_fields = 3;
    308     auto keys_offset = data_ - byte_width_ * num_prefixed_fields;
    309     return TypedVector(Indirect(keys_offset, byte_width_),
    310                        static_cast<uint8_t>(
    311                          ReadUInt64(keys_offset + byte_width_, byte_width_)),
    312                        TYPE_KEY);
    313   }
    314 
    315   static Map EmptyMap() {
    316     static const uint8_t empty_map[] = {
    317       0/*keys_len*/, 0/*keys_offset*/, 1/*keys_width*/, 0/*len*/
    318     };
    319     return Map(empty_map + 4, 1);
    320   }
    321 
    322   bool IsTheEmptyMap() const {
    323     return data_ == EmptyMap().data_;
    324   }
    325 };
    326 
    327 class Reference {
    328  public:
    329   Reference(const uint8_t *data, uint8_t parent_width, uint8_t byte_width,
    330             Type type)
    331     : data_(data), parent_width_(parent_width), byte_width_(byte_width),
    332       type_(type) {}
    333 
    334   Reference(const uint8_t *data, uint8_t parent_width, uint8_t packed_type)
    335     : data_(data), parent_width_(parent_width) {
    336     byte_width_ = 1U << static_cast<BitWidth>(packed_type & 3);
    337     type_ = static_cast<Type>(packed_type >> 2);
    338   }
    339 
    340   Type GetType() const { return type_; }
    341 
    342   bool IsNull() const { return type_ == TYPE_NULL; }
    343   bool IsInt() const { return type_ == TYPE_INT ||
    344                               type_ == TYPE_INDIRECT_INT; }
    345   bool IsUInt() const { return type_ == TYPE_UINT||
    346                                type_ == TYPE_INDIRECT_UINT;; }
    347   bool IsIntOrUint() const { return IsInt() || IsUInt(); }
    348   bool IsFloat() const { return type_ == TYPE_FLOAT ||
    349                                 type_ == TYPE_INDIRECT_FLOAT; }
    350   bool IsNumeric() const { return IsIntOrUint() || IsFloat(); }
    351   bool IsString() const { return type_ == TYPE_STRING; }
    352   bool IsKey() const { return type_ == TYPE_KEY; }
    353   bool IsVector() const { return type_ == TYPE_VECTOR || type_ == TYPE_MAP; }
    354   bool IsMap() const { return type_ == TYPE_MAP; }
    355 
    356   // Reads any type as a int64_t. Never fails, does most sensible conversion.
    357   // Truncates floats, strings are attempted to be parsed for a number,
    358   // vectors/maps return their size. Returns 0 if all else fails.
    359   int64_t AsInt64() const {
    360     if (type_ == TYPE_INT) {
    361       // A fast path for the common case.
    362       return ReadInt64(data_, parent_width_);
    363     } else switch (type_) {
    364       case TYPE_INDIRECT_INT: return ReadInt64(Indirect(), byte_width_);
    365       case TYPE_UINT: return ReadUInt64(data_, parent_width_);
    366       case TYPE_INDIRECT_UINT: return ReadUInt64(Indirect(), byte_width_);
    367       case TYPE_FLOAT: return static_cast<int64_t>(
    368                                 ReadDouble(data_, parent_width_));
    369       case TYPE_INDIRECT_FLOAT: return static_cast<int64_t>(
    370                                          ReadDouble(Indirect(), byte_width_));
    371       case TYPE_NULL: return 0;
    372       case TYPE_STRING: return flatbuffers::StringToInt(AsString().c_str());
    373       case TYPE_VECTOR: return static_cast<int64_t>(AsVector().size());
    374       default:
    375       // Convert other things to int.
    376       return 0;
    377     }
    378   }
    379 
    380   // TODO: could specialize these to not use AsInt64() if that saves
    381   // extension ops in generated code, and use a faster op than ReadInt64.
    382   int32_t AsInt32() const { return static_cast<int32_t>(AsInt64()); }
    383   int16_t AsInt16() const { return static_cast<int16_t>(AsInt64()); }
    384   int8_t  AsInt8()  const { return static_cast<int8_t> (AsInt64()); }
    385 
    386   uint64_t AsUInt64() const {
    387     if (type_ == TYPE_UINT) {
    388       // A fast path for the common case.
    389       return ReadUInt64(data_, parent_width_);
    390     } else switch (type_) {
    391       case TYPE_INDIRECT_UINT: return ReadUInt64(Indirect(), byte_width_);
    392       case TYPE_INT: return ReadInt64(data_, parent_width_);
    393       case TYPE_INDIRECT_INT: return ReadInt64(Indirect(), byte_width_);
    394       case TYPE_FLOAT: return static_cast<uint64_t>(
    395                                 ReadDouble(data_, parent_width_));
    396       case TYPE_INDIRECT_FLOAT: return static_cast<uint64_t>(
    397                                   ReadDouble(Indirect(), byte_width_));
    398       case TYPE_NULL: return 0;
    399       case TYPE_STRING: return flatbuffers::StringToUInt(AsString().c_str());
    400       case TYPE_VECTOR: return static_cast<uint64_t>(AsVector().size());
    401       default:
    402       // Convert other things to uint.
    403       return 0;
    404     }
    405   }
    406 
    407   uint32_t AsUInt32() const { return static_cast<uint32_t>(AsUInt64()); }
    408   uint16_t AsUInt16() const { return static_cast<uint16_t>(AsUInt64()); }
    409   uint8_t  AsUInt8()  const { return static_cast<uint8_t> (AsUInt64()); }
    410 
    411   double AsDouble() const {
    412     if (type_ == TYPE_FLOAT) {
    413       // A fast path for the common case.
    414       return ReadDouble(data_, parent_width_);
    415     } else switch (type_) {
    416       case TYPE_INDIRECT_FLOAT: return ReadDouble(Indirect(), byte_width_);
    417       case TYPE_INT: return static_cast<double>(
    418                               ReadInt64(data_, parent_width_));
    419       case TYPE_UINT: return static_cast<double>(
    420                                ReadUInt64(data_, parent_width_));
    421       case TYPE_INDIRECT_INT: return static_cast<double>(
    422                                        ReadInt64(Indirect(), byte_width_));
    423       case TYPE_INDIRECT_UINT: return static_cast<double>(
    424                                         ReadUInt64(Indirect(), byte_width_));
    425       case TYPE_NULL: return 0.0;
    426       case TYPE_STRING: return strtod(AsString().c_str(), nullptr);
    427       case TYPE_VECTOR: return static_cast<double>(AsVector().size());
    428       default:
    429       // Convert strings and other things to float.
    430       return 0;
    431     }
    432   }
    433 
    434   float AsFloat() const { return static_cast<float>(AsDouble()); }
    435 
    436   const char *AsKey() const {
    437     if (type_ == TYPE_KEY) {
    438       return reinterpret_cast<const char *>(Indirect());
    439     } else {
    440       return "";
    441     }
    442   }
    443 
    444   // This function returns the empty string if you try to read a not-string.
    445   String AsString() const {
    446     if (type_ == TYPE_STRING) {
    447       return String(Indirect(), byte_width_);
    448     } else {
    449       return String::EmptyString();
    450     }
    451   }
    452 
    453   // Unlike AsString(), this will convert any type to a std::string.
    454   std::string ToString() const {
    455     if (type_ == TYPE_STRING) {
    456       return String(Indirect(), byte_width_).c_str();
    457     } else if (IsKey()) {
    458       return AsKey();
    459     } else if (IsInt()) {
    460       return flatbuffers::NumToString(AsInt64());
    461     } else if (IsUInt()) {
    462       return flatbuffers::NumToString(AsUInt64());
    463     } else if (IsFloat()) {
    464       return flatbuffers::NumToString(AsDouble());
    465     } else if (IsNull()) {
    466       return "null";
    467     } else if (IsMap()) {
    468       return "{..}";  // TODO: show elements.
    469     } else if (IsVector()) {
    470       return "[..]";  // TODO: show elements.
    471     } else {
    472       return "(?)";
    473     }
    474   }
    475 
    476   // This function returns the empty blob if you try to read a not-blob.
    477   // Strings can be viewed as blobs too.
    478   Blob AsBlob() const {
    479     if (type_ == TYPE_BLOB || type_ == TYPE_STRING) {
    480       return Blob(Indirect(), byte_width_);
    481     } else {
    482       return Blob::EmptyBlob();
    483     }
    484   }
    485 
    486   // This function returns the empty vector if you try to read a not-vector.
    487   // Maps can be viewed as vectors too.
    488   Vector AsVector() const {
    489     if (type_ == TYPE_VECTOR || type_ == TYPE_MAP) {
    490       return Vector(Indirect(), byte_width_);
    491     } else {
    492       return Vector::EmptyVector();
    493     }
    494   }
    495 
    496   TypedVector AsTypedVector() const {
    497     if (IsTypedVector(type_)) {
    498       return TypedVector(Indirect(), byte_width_,
    499                          ToTypedVectorElementType(type_));
    500     } else {
    501       return TypedVector::EmptyTypedVector();
    502     }
    503   }
    504 
    505   FixedTypedVector AsFixedTypedVector() const {
    506     if (IsFixedTypedVector(type_)) {
    507       uint8_t len = 0;
    508       auto vtype = ToFixedTypedVectorElementType(type_, &len);
    509       return FixedTypedVector(Indirect(), byte_width_, vtype, len);
    510     } else {
    511       return FixedTypedVector::EmptyFixedTypedVector();
    512     }
    513   }
    514 
    515   Map AsMap() const {
    516     if (type_ == TYPE_MAP) {
    517       return Map(Indirect(), byte_width_);
    518     } else {
    519       return Map::EmptyMap();
    520     }
    521   }
    522 
    523   // Experimental: Mutation functions.
    524   // These allow scalars in an already created buffer to be updated in-place.
    525   // Since by default scalars are stored in the smallest possible space,
    526   // the new value may not fit, in which case these functions return false.
    527   // To avoid this, you can construct the values you intend to mutate using
    528   // Builder::ForceMinimumBitWidth.
    529   bool MutateInt(int64_t i) {
    530     if (type_ == TYPE_INT) {
    531       return Mutate(data_, i, parent_width_, WidthI(i));
    532     } else if (type_ == TYPE_INDIRECT_INT) {
    533       return Mutate(Indirect(), i, byte_width_, WidthI(i));
    534     } else if (type_ == TYPE_UINT) {
    535       auto u = static_cast<uint64_t>(i);
    536       return Mutate(data_, u, parent_width_, WidthU(u));
    537     } else if (type_ == TYPE_INDIRECT_UINT) {
    538       auto u = static_cast<uint64_t>(i);
    539       return Mutate(Indirect(), u, byte_width_, WidthU(u));
    540     } else {
    541       return false;
    542     }
    543   }
    544 
    545   bool MutateUInt(uint64_t u) {
    546     if (type_ == TYPE_UINT) {
    547       return Mutate(data_, u, parent_width_, WidthU(u));
    548     } else if (type_ == TYPE_INDIRECT_UINT) {
    549       return Mutate(Indirect(), u, byte_width_, WidthU(u));
    550     } else if (type_ == TYPE_INT) {
    551       auto i = static_cast<int64_t>(u);
    552       return Mutate(data_, i, parent_width_, WidthI(i));
    553     } else if (type_ == TYPE_INDIRECT_INT) {
    554       auto i = static_cast<int64_t>(u);
    555       return Mutate(Indirect(), i, byte_width_, WidthI(i));
    556     } else {
    557       return false;
    558     }
    559   }
    560 
    561   bool MutateFloat(float f) {
    562     if (type_ == TYPE_FLOAT) {
    563       return MutateF(data_, f, parent_width_, BIT_WIDTH_32);
    564     } else if (type_ == TYPE_INDIRECT_FLOAT) {
    565       return MutateF(Indirect(), f, byte_width_, BIT_WIDTH_32);
    566     } else {
    567       return false;
    568     }
    569   }
    570 
    571   bool MutateFloat(double d) {
    572     if (type_ == TYPE_FLOAT) {
    573       return MutateF(data_, d, parent_width_, WidthF(d));
    574     } else if (type_ == TYPE_INDIRECT_FLOAT) {
    575       return MutateF(Indirect(), d, byte_width_, WidthF(d));
    576     } else {
    577       return false;
    578     }
    579   }
    580 
    581   bool MutateString(const char *str, size_t len) {
    582     auto s = AsString();
    583     if (s.IsTheEmptyString()) return false;
    584     // This is very strict, could allow shorter strings, but that creates
    585     // garbage.
    586     if (s.length() != len) return false;
    587     memcpy(const_cast<char *>(s.c_str()), str, len);
    588     return true;
    589   }
    590   bool MutateString(const char *str) {
    591     return MutateString(str, strlen(str));
    592   }
    593   bool MutateString(const std::string &str) {
    594     return MutateString(str.data(), str.length());
    595   }
    596 
    597  private:
    598   const uint8_t *Indirect() const {
    599     return flexbuffers::Indirect(data_, parent_width_);
    600   }
    601 
    602   template<typename T> bool Mutate(const uint8_t *dest, T t, size_t byte_width,
    603                                    BitWidth value_width) {
    604     auto fits = (1U << value_width) <= byte_width;
    605     if (fits) {
    606       t = flatbuffers::EndianScalar(t);
    607       memcpy(const_cast<uint8_t *>(dest), &t, byte_width);
    608     }
    609     return fits;
    610   }
    611 
    612   template<typename T> bool MutateF(const uint8_t *dest, T t, size_t byte_width,
    613                                     BitWidth value_width) {
    614     if (byte_width == sizeof(double))
    615       return Mutate(dest, static_cast<double>(t), byte_width, value_width);
    616     if (byte_width == sizeof(float))
    617       return Mutate(dest, static_cast<float>(t), byte_width, value_width);
    618     assert(false);
    619     return false;
    620   }
    621 
    622   const uint8_t *data_;
    623   uint8_t parent_width_;
    624   uint8_t byte_width_;
    625   Type type_;
    626 };
    627 
    628 inline uint8_t PackedType(BitWidth bit_width, Type type) {
    629   return static_cast<uint8_t>(bit_width | (type << 2));
    630 }
    631 
    632 inline uint8_t NullPackedType() {
    633   return PackedType(BIT_WIDTH_8, TYPE_NULL);
    634 }
    635 
    636 // Vector accessors.
    637 // Note: if you try to access outside of bounds, you get a Null value back
    638 // instead. Normally this would be an assert, but since this is "dynamically
    639 // typed" data, you may not want that (someone sends you a 2d vector and you
    640 // wanted 3d).
    641 // The Null converts seamlessly into a default value for any other type.
    642 // TODO(wvo): Could introduce an #ifdef that makes this into an assert?
    643 inline Reference Vector::operator[](size_t i) const  {
    644   auto len = size();
    645   if (i >= len) return Reference(nullptr, 1, NullPackedType());
    646   auto packed_type = (data_ + len * byte_width_)[i];
    647   auto elem = data_ + i * byte_width_;
    648   return Reference(elem, byte_width_, packed_type);
    649 }
    650 
    651 inline Reference TypedVector::operator[](size_t i) const  {
    652   auto len = size();
    653   if (i >= len) return Reference(nullptr, 1, NullPackedType());
    654   auto elem = data_ + i * byte_width_;
    655   return Reference(elem, byte_width_, 1, type_);
    656 }
    657 
    658 inline Reference FixedTypedVector::operator[](size_t i) const  {
    659   if (i >= len_) return Reference(nullptr, 1, NullPackedType());
    660   auto elem = data_ + i * byte_width_;
    661   return Reference(elem, byte_width_, 1, type_);
    662 }
    663 
    664 template<typename T> int KeyCompare(const void *key, const void *elem) {
    665   auto str_elem = reinterpret_cast<const char *>(
    666                     Indirect<T>(reinterpret_cast<const uint8_t *>(elem)));
    667   auto skey = reinterpret_cast<const char *>(key);
    668   return strcmp(skey, str_elem);
    669 }
    670 
    671 inline Reference Map::operator[](const char *key) const {
    672   auto keys = Keys();
    673   // We can't pass keys.byte_width_ to the comparison function, so we have
    674   // to pick the right one ahead of time.
    675   int (*comp)(const void *, const void *) = nullptr;
    676   switch (keys.byte_width_) {
    677     case 1: comp = KeyCompare<uint8_t>; break;
    678     case 2: comp = KeyCompare<uint16_t>; break;
    679     case 4: comp = KeyCompare<uint32_t>; break;
    680     case 8: comp = KeyCompare<uint64_t>; break;
    681   }
    682   auto res = std::bsearch(key, keys.data_, keys.size(), keys.byte_width_, comp);
    683   if (!res)
    684     return Reference(nullptr, 1, NullPackedType());
    685   auto i = (reinterpret_cast<uint8_t *>(res) - keys.data_) / keys.byte_width_;
    686   return (*static_cast<const Vector *>(this))[i];
    687 }
    688 
    689 inline Reference Map::operator[](const std::string &key) const {
    690   return (*this)[key.c_str()];
    691 }
    692 
    693 inline Reference GetRoot(const uint8_t *buffer, size_t size) {
    694   // See Finish() below for the serialization counterpart of this.
    695   // The root starts at the end of the buffer, so we parse backwards from there.
    696   auto end = buffer + size;
    697   auto byte_width = *--end;
    698   auto packed_type = *--end;
    699   end -= byte_width;  // The root data item.
    700   return Reference(end, byte_width, packed_type);
    701 }
    702 
    703 inline Reference GetRoot(const std::vector<uint8_t> &buffer) {
    704   return GetRoot(buffer.data(), buffer.size());
    705 }
    706 
    707 // Flags that configure how the Builder behaves.
    708 // The "Share" flags determine if the Builder automatically tries to pool
    709 // this type. Pooling can reduce the size of serialized data if there are
    710 // multiple maps of the same kind, at the expense of slightly slower
    711 // serialization (the cost of lookups) and more memory use (std::set).
    712 // By default this is on for keys, but off for strings.
    713 // Turn keys off if you have e.g. only one map.
    714 // Turn strings on if you expect many non-unique string values.
    715 // Additionally, sharing key vectors can save space if you have maps with
    716 // identical field populations.
    717 enum BuilderFlag {
    718   BUILDER_FLAG_NONE = 0,
    719   BUILDER_FLAG_SHARE_KEYS = 1,
    720   BUILDER_FLAG_SHARE_STRINGS = 2,
    721   BUILDER_FLAG_SHARE_KEYS_AND_STRINGS = 3,
    722   BUILDER_FLAG_SHARE_KEY_VECTORS = 4,
    723   BUILDER_FLAG_SHARE_ALL = 7,
    724 };
    725 
    726 class Builder FLATBUFFERS_FINAL_CLASS {
    727  public:
    728   Builder(size_t initial_size = 256,
    729           BuilderFlag flags = BUILDER_FLAG_SHARE_KEYS)
    730       : buf_(initial_size), finished_(false), flags_(flags),
    731         force_min_bit_width_(BIT_WIDTH_8), key_pool(KeyOffsetCompare(buf_)),
    732         string_pool(StringOffsetCompare(buf_)) {
    733     buf_.clear();
    734   }
    735 
    736   /// @brief Get the serialized buffer (after you call `Finish()`).
    737   /// @return Returns a vector owned by this class.
    738   const std::vector<uint8_t> &GetBuffer() const {
    739     Finished();
    740     return buf_;
    741   }
    742 
    743   // All value constructing functions below have two versions: one that
    744   // takes a key (for placement inside a map) and one that doesn't (for inside
    745   // vectors and elsewhere).
    746 
    747   void Null() { stack_.push_back(Value()); }
    748   void Null(const char *key) { Key(key); Null(); }
    749 
    750   void Int(int64_t i) { stack_.push_back(Value(i, TYPE_INT, WidthI(i))); }
    751   void Int(const char *key, int64_t i) { Key(key); Int(i); }
    752 
    753   void UInt(uint64_t u) { stack_.push_back(Value(u, TYPE_UINT, WidthU(u))); }
    754   void UInt(const char *key, uint64_t u) { Key(key); Int(u); }
    755 
    756   void Float(float f) { stack_.push_back(Value(f)); }
    757   void Float(const char *key, float f) { Key(key); Float(f); }
    758 
    759   void Double(double f) { stack_.push_back(Value(f)); }
    760   void Double(const char *key, double d) { Key(key); Double(d); }
    761 
    762   void Bool(bool b) { Int(static_cast<int64_t>(b)); }
    763   void Bool(const char *key, bool b) { Key(key); Bool(b); }
    764 
    765   void IndirectInt(int64_t i) {
    766     PushIndirect(i, TYPE_INDIRECT_INT, WidthI(i));
    767   }
    768   void IndirectInt(const char *key, int64_t i) {
    769     Key(key);
    770     IndirectInt(i);
    771   }
    772 
    773   void IndirectUInt(uint64_t u) {
    774     PushIndirect(u, TYPE_INDIRECT_UINT, WidthU(u));
    775   }
    776   void IndirectUInt(const char *key, uint64_t u) {
    777     Key(key);
    778     IndirectUInt(u);
    779   }
    780 
    781   void IndirectFloat(float f) {
    782     PushIndirect(f, TYPE_INDIRECT_FLOAT, BIT_WIDTH_32);
    783   }
    784   void IndirectFloat(const char *key, float f) {
    785     Key(key);
    786     IndirectFloat(f);
    787   }
    788 
    789   void IndirectDouble(double f) {
    790     PushIndirect(f, TYPE_INDIRECT_FLOAT, WidthF(f));
    791   }
    792   void IndirectDouble(const char *key, double d) {
    793     Key(key);
    794     IndirectDouble(d);
    795   }
    796 
    797   size_t Key(const char *str, size_t len) {
    798     auto sloc = buf_.size();
    799     WriteBytes(str, len + 1);
    800     if (flags_ & BUILDER_FLAG_SHARE_KEYS) {
    801       auto it = key_pool.find(sloc);
    802       if (it != key_pool.end()) {
    803         // Already in the buffer. Remove key we just serialized, and use
    804         // existing offset instead.
    805         buf_.resize(sloc);
    806         sloc = *it;
    807       } else {
    808         key_pool.insert(sloc);
    809       }
    810     }
    811     stack_.push_back(Value(static_cast<uint64_t>(sloc), TYPE_KEY, BIT_WIDTH_8));
    812     return sloc;
    813   }
    814 
    815   size_t Key(const char *str) { return Key(str, strlen(str)); }
    816   size_t Key(const std::string &str) { return Key(str.c_str(), str.size()); }
    817 
    818   size_t String(const char *str, size_t len) {
    819     auto reset_to = buf_.size();
    820     auto sloc = CreateBlob(str, len, 1, TYPE_STRING);
    821     if (flags_ & BUILDER_FLAG_SHARE_STRINGS) {
    822       StringOffset so(sloc, len);
    823       auto it = string_pool.find(so);
    824       if (it != string_pool.end()) {
    825         // Already in the buffer. Remove string we just serialized, and use
    826         // existing offset instead.
    827         buf_.resize(reset_to);
    828         sloc = it->first;
    829         stack_.back().u_ = sloc;
    830       } else {
    831         string_pool.insert(so);
    832       }
    833     }
    834     return sloc;
    835   }
    836   size_t String(const char *str) {
    837     return String(str, strlen(str));
    838   }
    839   size_t String(const std::string &str) {
    840     return String(str.c_str(), str.size());
    841   }
    842   void String(const flexbuffers::String &str) {
    843     String(str.c_str(), str.length());
    844   }
    845 
    846   void String(const char *key, const char *str) {
    847     Key(key);
    848     String(str);
    849   }
    850   void String(const char *key, const std::string &str) {
    851     Key(key);
    852     String(str);
    853   }
    854   void String(const char *key, const flexbuffers::String &str) {
    855     Key(key);
    856     String(str);
    857   }
    858 
    859   size_t Blob(const void *data, size_t len) {
    860     return CreateBlob(data, len, 0, TYPE_BLOB);
    861   }
    862   size_t Blob(const std::vector<uint8_t> &v) {
    863     return CreateBlob(v.data(), v.size(), 0, TYPE_BLOB);
    864   }
    865 
    866   // TODO(wvo): support all the FlexBuffer types (like flexbuffers::String),
    867   // e.g. Vector etc. Also in overloaded versions.
    868   // Also some FlatBuffers types?
    869 
    870   size_t StartVector() { return stack_.size(); }
    871   size_t StartVector(const char *key) { Key(key); return stack_.size(); }
    872   size_t StartMap() { return stack_.size(); }
    873   size_t StartMap(const char *key) { Key(key); return stack_.size(); }
    874 
    875   // TODO(wvo): allow this to specify an aligment greater than the natural
    876   // alignment.
    877   size_t EndVector(size_t start, bool typed, bool fixed) {
    878     auto vec = CreateVector(start, stack_.size() - start, 1, typed, fixed);
    879     // Remove temp elements and return vector.
    880     stack_.resize(start);
    881     stack_.push_back(vec);
    882     return static_cast<size_t>(vec.u_);
    883   }
    884 
    885   size_t EndMap(size_t start) {
    886     // We should have interleaved keys and values on the stack.
    887     // Make sure it is an even number:
    888     auto len = stack_.size() - start;
    889     assert(!(len & 1));
    890     len /= 2;
    891     // Make sure keys are all strings:
    892     for (auto key = start; key < stack_.size(); key += 2) {
    893       assert(stack_[key].type_ == TYPE_KEY);
    894     }
    895     // Now sort values, so later we can do a binary seach lookup.
    896     // We want to sort 2 array elements at a time.
    897     struct TwoValue { Value key; Value val; };
    898     // TODO(wvo): strict aliasing?
    899     // TODO(wvo): allow the caller to indicate the data is already sorted
    900     // for maximum efficiency? With an assert to check sortedness to make sure
    901     // we're not breaking binary search.
    902     // Or, we can track if the map is sorted as keys are added which would be
    903     // be quite cheap (cheaper than checking it here), so we can skip this
    904     // step automatically when appliccable, and encourage people to write in
    905     // sorted fashion.
    906     // std::sort is typically already a lot faster on sorted data though.
    907     auto dict = reinterpret_cast<TwoValue *>(stack_.data() + start);
    908     std::sort(dict, dict + len,
    909               [&](const TwoValue &a, const TwoValue &b) -> bool {
    910       auto as = reinterpret_cast<const char *>(buf_.data() + a.key.u_);
    911       auto bs = reinterpret_cast<const char *>(buf_.data() + b.key.u_);
    912       auto comp = strcmp(as, bs);
    913       // If this assertion hits, you've added two keys with the same value to
    914       // this map.
    915       // TODO: Have to check for pointer equality, as some sort implementation
    916       // apparently call this function with the same element?? Why?
    917       assert(comp || &a == &b);
    918       return comp < 0;
    919     });
    920     // First create a vector out of all keys.
    921     // TODO(wvo): if kBuilderFlagShareKeyVectors is true, see if we can share
    922     // the first vector.
    923     auto keys = CreateVector(start, len, 2, true, false);
    924     auto vec = CreateVector(start + 1, len, 2, false, false, &keys);
    925     // Remove temp elements and return map.
    926     stack_.resize(start);
    927     stack_.push_back(vec);
    928     return static_cast<size_t>(vec.u_);
    929   }
    930 
    931   template<typename F> size_t Vector(F f) {
    932     auto start = StartVector();
    933     f();
    934     return EndVector(start, false, false);
    935   }
    936   template<typename F> size_t Vector(const char *key, F f) {
    937     auto start = StartVector(key);
    938     f();
    939     return EndVector(start, false, false);
    940   }
    941   template<typename T> void Vector(const T *elems, size_t len) {
    942     if (std::is_scalar<T>::value) {
    943       // This path should be a lot quicker and use less space.
    944       ScalarVector(elems, len, false);
    945     } else {
    946       auto start = StartVector();
    947       for (size_t i = 0; i < len; i++) Add(elems[i]);
    948       EndVector(start, false, false);
    949     }
    950   }
    951   template<typename T> void Vector(const char *key, const T *elems,
    952                                    size_t len) {
    953     Key(key);
    954     Vector(elems, len);
    955   }
    956   template<typename T> void Vector(const std::vector<T> &vec) {
    957     Vector(vec.data(), vec.size());
    958   }
    959 
    960   template<typename F> size_t TypedVector(F f) {
    961     auto start = StartVector();
    962     f();
    963     return EndVector(start, true, false);
    964   }
    965   template<typename F> size_t TypedVector(const char *key, F f) {
    966     auto start = StartVector(key);
    967     f();
    968     return EndVector(start, true, false);
    969   }
    970 
    971   template<typename T> size_t FixedTypedVector(const T *elems, size_t len) {
    972     // We only support a few fixed vector lengths. Anything bigger use a
    973     // regular typed vector.
    974     assert(len >= 2 && len <= 4);
    975     // And only scalar values.
    976     assert(std::is_scalar<T>::value);
    977     return ScalarVector(elems, len, true);
    978   }
    979 
    980   template<typename T> size_t FixedTypedVector(const char *key, const T *elems,
    981                                                size_t len) {
    982     Key(key);
    983     return FixedTypedVector(elems, len);
    984   }
    985 
    986   template<typename F> size_t Map(F f) {
    987     auto start = StartMap();
    988     f();
    989     return EndMap(start);
    990   }
    991   template<typename F> size_t Map(const char *key, F f) {
    992     auto start = StartMap(key);
    993     f();
    994     return EndMap(start);
    995   }
    996   template<typename T> void Map(const std::map<std::string, T> &map) {
    997     auto start = StartMap();
    998     for (auto it = map.begin(); it != map.end(); ++it)
    999       Add(it->first.c_str(), it->second);
   1000     EndMap(start);
   1001   }
   1002 
   1003   // Overloaded Add that tries to call the correct function above.
   1004   void Add(int8_t i) { Int(i); }
   1005   void Add(int16_t i) { Int(i); }
   1006   void Add(int32_t i) { Int(i); }
   1007   void Add(int64_t i) { Int(i); }
   1008   void Add(uint8_t u) { UInt(u); }
   1009   void Add(uint16_t u) { UInt(u); }
   1010   void Add(uint32_t u) { UInt(u); }
   1011   void Add(uint64_t u) { UInt(u); }
   1012   void Add(float f) { Float(f); }
   1013   void Add(double d) { Double(d); }
   1014   void Add(bool b) { Bool(b); }
   1015   void Add(const char *str) { String(str); }
   1016   void Add(const std::string &str) { String(str); }
   1017   void Add(const flexbuffers::String &str) { String(str); }
   1018 
   1019   template<typename T> void Add(const std::vector<T> &vec) {
   1020     Vector(vec);
   1021   }
   1022 
   1023   template<typename T> void Add(const char *key, const T &t) {
   1024     Key(key);
   1025     Add(t);
   1026   }
   1027 
   1028   template<typename T> void Add(const std::map<std::string, T> &map) {
   1029     Map(map);
   1030   }
   1031 
   1032   template<typename T> void operator+=(const T &t) {
   1033     Add(t);
   1034   }
   1035 
   1036   // This function is useful in combination with the Mutate* functions above.
   1037   // It forces elements of vectors and maps to have a minimum size, such that
   1038   // they can later be updated without failing.
   1039   // Call with no arguments to reset.
   1040   void ForceMinimumBitWidth(BitWidth bw = BIT_WIDTH_8) {
   1041     force_min_bit_width_ = bw;
   1042   }
   1043 
   1044   void Finish() {
   1045     // If you hit this assert, you likely have objects that were never included
   1046     // in a parent. You need to have exactly one root to finish a buffer.
   1047     // Check your Start/End calls are matched, and all objects are inside
   1048     // some other object.
   1049     assert(stack_.size() == 1);
   1050 
   1051     // Write root value.
   1052     auto byte_width = Align(stack_[0].ElemWidth(buf_.size(), 0));
   1053     WriteAny(stack_[0], byte_width);
   1054     // Write root type.
   1055     Write(stack_[0].StoredPackedType(), 1);
   1056     // Write root size. Normally determined by parent, but root has no parent :)
   1057     Write(byte_width, 1);
   1058 
   1059     finished_ = true;
   1060   }
   1061 
   1062  private:
   1063   void Finished() const {
   1064     // If you get this assert, you're attempting to get access a buffer
   1065     // which hasn't been finished yet. Be sure to call
   1066     // Builder::Finish with your root object.
   1067     assert(finished_);
   1068   }
   1069 
   1070   // Align to prepare for writing a scalar with a certain size.
   1071   uint8_t Align(BitWidth alignment) {
   1072     auto byte_width = 1U << alignment;
   1073     buf_.insert(buf_.end(), flatbuffers::PaddingBytes(buf_.size(), byte_width),
   1074                 0);
   1075     return byte_width;
   1076   }
   1077 
   1078   void WriteBytes(const void *val, size_t size) {
   1079     buf_.insert(buf_.end(),
   1080                 reinterpret_cast<const uint8_t *>(val),
   1081                 reinterpret_cast<const uint8_t *>(val) + size);
   1082   }
   1083 
   1084   // For values T >= byte_width
   1085   template<typename T> void Write(T val, uint8_t byte_width) {
   1086     val = flatbuffers::EndianScalar(val);
   1087     WriteBytes(&val, byte_width);
   1088   }
   1089 
   1090   void WriteDouble(double f, uint8_t byte_width) {
   1091     switch (byte_width) {
   1092       case 8: Write(f, byte_width); break;
   1093       case 4: Write(static_cast<float>(f), byte_width); break;
   1094       //case 2: Write(static_cast<half>(f), byte_width); break;
   1095       //case 1: Write(static_cast<quarter>(f), byte_width); break;
   1096       default: assert(0);
   1097     }
   1098   }
   1099 
   1100   void WriteOffset(uint64_t o, uint8_t byte_width) {
   1101     auto reloff = buf_.size() - o;
   1102     assert(reloff < 1ULL << (byte_width * 8) || byte_width == 8);
   1103     Write(reloff, byte_width);
   1104   }
   1105 
   1106   template<typename T> void PushIndirect(T val, Type type, BitWidth bit_width) {
   1107     auto byte_width = Align(bit_width);
   1108     auto iloc = buf_.size();
   1109     Write(val, byte_width);
   1110     stack_.push_back(Value(static_cast<uint64_t>(iloc), type, bit_width));
   1111   }
   1112 
   1113   static BitWidth WidthB(size_t byte_width) {
   1114     switch (byte_width) {
   1115       case 1: return BIT_WIDTH_8;
   1116       case 2: return BIT_WIDTH_16;
   1117       case 4: return BIT_WIDTH_32;
   1118       case 8: return BIT_WIDTH_64;
   1119       default: assert(false); return BIT_WIDTH_64;
   1120     }
   1121   }
   1122 
   1123   template<typename T> static Type GetScalarType() {
   1124     assert(std::is_scalar<T>::value);
   1125     return std::is_floating_point<T>::value
   1126         ? TYPE_FLOAT
   1127         : (std::is_unsigned<T>::value ? TYPE_UINT : TYPE_INT);
   1128   }
   1129 
   1130   struct Value {
   1131     union {
   1132       int64_t i_;
   1133       uint64_t u_;
   1134       double f_;
   1135     };
   1136 
   1137     Type type_;
   1138 
   1139     // For scalars: of itself, for vector: of its elements, for string: length.
   1140     BitWidth min_bit_width_;
   1141 
   1142     Value() : i_(0), type_(TYPE_NULL), min_bit_width_(BIT_WIDTH_8) {}
   1143 
   1144     Value(int64_t i, Type t, BitWidth bw)
   1145       : i_(i), type_(t), min_bit_width_(bw) {}
   1146     Value(uint64_t u, Type t, BitWidth bw)
   1147       : u_(u), type_(t), min_bit_width_(bw) {}
   1148 
   1149     Value(float f)
   1150       : f_(f), type_(TYPE_FLOAT), min_bit_width_(BIT_WIDTH_32) {}
   1151     Value(double f)
   1152       : f_(f), type_(TYPE_FLOAT), min_bit_width_(WidthF(f)) {}
   1153 
   1154     uint8_t StoredPackedType(BitWidth parent_bit_width_= BIT_WIDTH_8) const {
   1155       return PackedType(StoredWidth(parent_bit_width_), type_);
   1156     }
   1157 
   1158     BitWidth ElemWidth(size_t buf_size, size_t elem_index) const {
   1159       if (IsInline(type_)) {
   1160         return min_bit_width_;
   1161       } else {
   1162         // We have an absolute offset, but want to store a relative offset
   1163         // elem_index elements beyond the current buffer end. Since whether
   1164         // the relative offset fits in a certain byte_width depends on
   1165         // the size of the elements before it (and their alignment), we have
   1166         // to test for each size in turn.
   1167         for (size_t byte_width = 1;
   1168              byte_width <= sizeof(flatbuffers::largest_scalar_t);
   1169              byte_width *= 2) {
   1170           // Where are we going to write this offset?
   1171           auto offset_loc =
   1172             buf_size +
   1173             flatbuffers::PaddingBytes(buf_size, byte_width) +
   1174             elem_index * byte_width;
   1175           // Compute relative offset.
   1176           auto offset = offset_loc - u_;
   1177           // Does it fit?
   1178           auto bit_width = WidthU(offset);
   1179           if (1U << bit_width == byte_width) return bit_width;
   1180         }
   1181         assert(false);  // Must match one of the sizes above.
   1182         return BIT_WIDTH_64;
   1183       }
   1184     }
   1185 
   1186     BitWidth StoredWidth(BitWidth parent_bit_width_ = BIT_WIDTH_8) const {
   1187       if (IsInline(type_)) {
   1188           return std::max(min_bit_width_, parent_bit_width_);
   1189       } else {
   1190           return min_bit_width_;
   1191       }
   1192     }
   1193   };
   1194 
   1195   void WriteAny(const Value &val, uint8_t byte_width) {
   1196     switch (val.type_) {
   1197       case TYPE_NULL:
   1198       case TYPE_INT:
   1199         Write(val.i_, byte_width);
   1200         break;
   1201       case TYPE_UINT:
   1202         Write(val.u_, byte_width);
   1203         break;
   1204       case TYPE_FLOAT:
   1205         WriteDouble(val.f_, byte_width);
   1206         break;
   1207       default:
   1208         WriteOffset(val.u_, byte_width);
   1209         break;
   1210     }
   1211   }
   1212 
   1213   size_t CreateBlob(const void *data, size_t len, size_t trailing, Type type) {
   1214     auto bit_width = WidthU(len);
   1215     auto byte_width = Align(bit_width);
   1216     Write<uint64_t>(len, byte_width);
   1217     auto sloc = buf_.size();
   1218     WriteBytes(data, len + trailing);
   1219     stack_.push_back(Value(static_cast<uint64_t>(sloc), type, bit_width));
   1220     return sloc;
   1221   }
   1222 
   1223   template<typename T> size_t ScalarVector(const T *elems, size_t len,
   1224                                            bool fixed) {
   1225     auto vector_type = GetScalarType<T>();
   1226     auto byte_width = sizeof(T);
   1227     auto bit_width = WidthB(byte_width);
   1228     // If you get this assert, you're trying to write a vector with a size
   1229     // field that is bigger than the scalars you're trying to write (e.g. a
   1230     // byte vector > 255 elements). For such types, write a "blob" instead.
   1231     // TODO: instead of asserting, could write vector with larger elements
   1232     // instead, though that would be wasteful.
   1233     assert(WidthU(len) <= bit_width);
   1234     if (!fixed) Write(len, byte_width);
   1235     auto vloc = buf_.size();
   1236     for (size_t i = 0; i < len; i++) Write(elems[i], byte_width);
   1237     stack_.push_back(Value(static_cast<uint64_t>(vloc),
   1238                            ToTypedVector(vector_type, fixed ? len : 0),
   1239                            bit_width));
   1240     return vloc;
   1241   }
   1242 
   1243   Value CreateVector(size_t start, size_t vec_len, size_t step, bool typed,
   1244                      bool fixed, const Value *keys = nullptr) {
   1245     // Figure out smallest bit width we can store this vector with.
   1246     auto bit_width = std::max(force_min_bit_width_, WidthU(vec_len));
   1247     auto prefix_elems = 1;
   1248     if (keys) {
   1249       // If this vector is part of a map, we will pre-fix an offset to the keys
   1250       // to this vector.
   1251       bit_width = std::max(bit_width, keys->ElemWidth(buf_.size(), 0));
   1252       prefix_elems += 2;
   1253     }
   1254     Type vector_type = TYPE_KEY;
   1255     // Check bit widths and types for all elements.
   1256     for (size_t i = start; i < stack_.size(); i += step) {
   1257       auto elem_width = stack_[i].ElemWidth(buf_.size(), i + prefix_elems);
   1258       bit_width = std::max(bit_width, elem_width);
   1259       if (typed) {
   1260         if (i == start) {
   1261           vector_type = stack_[i].type_;
   1262         } else {
   1263           // If you get this assert, you are writing a typed vector with
   1264           // elements that are not all the same type.
   1265           assert(vector_type == stack_[i].type_);
   1266         }
   1267       }
   1268     }
   1269     // If you get this assert, your fixed types are not one of:
   1270     // Int / UInt / Float / Key.
   1271     assert(IsTypedVectorElementType(vector_type));
   1272     auto byte_width = Align(bit_width);
   1273     // Write vector. First the keys width/offset if available, and size.
   1274     if (keys) {
   1275       WriteOffset(keys->u_, byte_width);
   1276       Write(1U << keys->min_bit_width_, byte_width);
   1277     }
   1278     if (!fixed) Write(vec_len, byte_width);
   1279     // Then the actual data.
   1280     auto vloc = buf_.size();
   1281     for (size_t i = start; i < stack_.size(); i += step) {
   1282       WriteAny(stack_[i], byte_width);
   1283     }
   1284     // Then the types.
   1285     if (!typed) {
   1286       for (size_t i = start; i < stack_.size(); i += step) {
   1287         buf_.push_back(stack_[i].StoredPackedType(bit_width));
   1288       }
   1289     }
   1290     return Value(static_cast<uint64_t>(vloc), keys
   1291                          ? TYPE_MAP
   1292                          : (typed
   1293                             ? ToTypedVector(vector_type, fixed ? vec_len : 0)
   1294                             : TYPE_VECTOR),
   1295                        bit_width);
   1296   }
   1297 
   1298   // You shouldn't really be copying instances of this class.
   1299   Builder(const Builder &);
   1300   Builder &operator=(const Builder &);
   1301 
   1302   std::vector<uint8_t> buf_;
   1303   std::vector<Value> stack_;
   1304 
   1305   bool finished_;
   1306 
   1307   BuilderFlag flags_;
   1308 
   1309   BitWidth force_min_bit_width_;
   1310 
   1311   struct KeyOffsetCompare {
   1312     KeyOffsetCompare(const std::vector<uint8_t> &buf) : buf_(&buf) {}
   1313     bool operator() (size_t a, size_t b) const {
   1314       auto stra = reinterpret_cast<const char *>(buf_->data() + a);
   1315       auto strb = reinterpret_cast<const char *>(buf_->data() + b);
   1316       return strcmp(stra, strb) < 0;
   1317     }
   1318     const std::vector<uint8_t> *buf_;
   1319   };
   1320 
   1321   typedef std::pair<size_t, size_t> StringOffset;
   1322   struct StringOffsetCompare {
   1323     StringOffsetCompare(const std::vector<uint8_t> &buf) : buf_(&buf) {}
   1324     bool operator() (const StringOffset &a, const StringOffset &b) const {
   1325       auto stra = reinterpret_cast<const char *>(buf_->data() + a.first);
   1326       auto strb = reinterpret_cast<const char *>(buf_->data() + b.first);
   1327       return strncmp(stra, strb, std::min(a.second, b.second) + 1) < 0;
   1328     }
   1329     const std::vector<uint8_t> *buf_;
   1330   };
   1331 
   1332   typedef std::set<size_t, KeyOffsetCompare> KeyOffsetMap;
   1333   typedef std::set<StringOffset, StringOffsetCompare> StringOffsetMap;
   1334 
   1335   KeyOffsetMap key_pool;
   1336   StringOffsetMap string_pool;
   1337 };
   1338 
   1339 }  // namespace flexbuffers
   1340 
   1341 #endif  // FLATBUFFERS_FLEXBUFFERS_H_
   1342