ONE - On-device Neural Engine
Loading...
Searching...
No Matches
flatbuffer_builder.h
Go to the documentation of this file.
1/*
2 * Copyright 2021 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_FLATBUFFER_BUILDER_H_
18#define FLATBUFFERS_FLATBUFFER_BUILDER_H_
19
20#include <algorithm>
21#include <cstdint>
22#include <functional>
23#include <initializer_list>
24#include <type_traits>
25
27#include "flatbuffers/array.h"
28#include "flatbuffers/base.h"
29#include "flatbuffers/buffer.h"
34#include "flatbuffers/string.h"
35#include "flatbuffers/struct.h"
36#include "flatbuffers/table.h"
37#include "flatbuffers/vector.h"
40
41namespace flatbuffers {
42
43// Converts a Field ID to a virtual table offset.
44inline voffset_t FieldIndexToOffset(voffset_t field_id) {
45 // Should correspond to what EndTable() below builds up.
46 const voffset_t fixed_fields =
47 2 * sizeof(voffset_t); // Vtable size and Object Size.
48 return fixed_fields + field_id * sizeof(voffset_t);
49}
50
51template<typename T, typename Alloc = std::allocator<T>>
52const T *data(const std::vector<T, Alloc> &v) {
53 // Eventually the returned pointer gets passed down to memcpy, so
54 // we need it to be non-null to avoid undefined behavior.
55 static uint8_t t;
56 return v.empty() ? reinterpret_cast<const T *>(&t) : &v.front();
57}
58template<typename T, typename Alloc = std::allocator<T>>
59T *data(std::vector<T, Alloc> &v) {
60 // Eventually the returned pointer gets passed down to memcpy, so
61 // we need it to be non-null to avoid undefined behavior.
62 static uint8_t t;
63 return v.empty() ? reinterpret_cast<T *>(&t) : &v.front();
64}
65
75template<bool Is64Aware = false> class FlatBufferBuilderImpl {
76 public:
77 // This switches the size type of the builder, based on if its 64-bit aware
78 // (uoffset64_t) or not (uoffset_t).
79 typedef
80 typename std::conditional<Is64Aware, uoffset64_t, uoffset_t>::type SizeT;
81
94 size_t initial_size = 1024, Allocator *allocator = nullptr,
95 bool own_allocator = false,
96 size_t buffer_minalign = AlignOf<largest_scalar_t>())
97 : buf_(initial_size, allocator, own_allocator, buffer_minalign,
98 static_cast<SizeT>(Is64Aware ? FLATBUFFERS_MAX_64_BUFFER_SIZE
99 : FLATBUFFERS_MAX_BUFFER_SIZE)),
100 num_field_loc(0),
101 max_voffset_(0),
103 nested(false),
104 finished(false),
105 minalign_(1),
106 force_defaults_(false),
107 dedup_vtables_(true),
108 string_pool(nullptr) {
109 EndianCheck();
110 }
111
114 : buf_(1024, nullptr, false, AlignOf<largest_scalar_t>(),
115 static_cast<SizeT>(Is64Aware ? FLATBUFFERS_MAX_64_BUFFER_SIZE
116 : FLATBUFFERS_MAX_BUFFER_SIZE)),
117 num_field_loc(0),
118 max_voffset_(0),
120 nested(false),
121 finished(false),
122 minalign_(1),
123 force_defaults_(false),
124 dedup_vtables_(true),
125 string_pool(nullptr) {
126 EndianCheck();
127 // Default construct and swap idiom.
128 // Lack of delegating constructors in vs2010 makes it more verbose than
129 // needed.
130 Swap(other);
131 }
132
135 // Move construct a temporary and swap idiom
136 FlatBufferBuilderImpl temp(std::move(other));
137 Swap(temp);
138 return *this;
139 }
140
142 using std::swap;
143 buf_.swap(other.buf_);
144 swap(num_field_loc, other.num_field_loc);
145 swap(max_voffset_, other.max_voffset_);
147 swap(nested, other.nested);
148 swap(finished, other.finished);
149 swap(minalign_, other.minalign_);
150 swap(force_defaults_, other.force_defaults_);
151 swap(dedup_vtables_, other.dedup_vtables_);
152 swap(string_pool, other.string_pool);
153 }
154
158
159 void Reset() {
160 Clear(); // clear builder state
161 buf_.reset(); // deallocate buffer
162 }
163
166 void Clear() {
167 ClearOffsets();
168 buf_.clear();
169 nested = false;
170 finished = false;
171 minalign_ = 1;
173 if (string_pool) string_pool->clear();
174 }
175
178 SizeT GetSize() const { return buf_.size(); }
179
183 template<bool is_64 = Is64Aware>
184 // Only enable this method for the 64-bit builder, as only that builder is
185 // concerned with the 32/64-bit boundary, and should be the one to bare any
186 // run time costs.
187 typename std::enable_if<is_64, uoffset_t>::type GetSizeRelative32BitRegion()
188 const {
189 //[32-bit region][64-bit region]
190 // [XXXXXXXXXXXXXXXXXXX] GetSize()
191 // [YYYYYYYYYYYYY] length_of_64_bit_region_
192 // [ZZZZ] return size
193 return static_cast<uoffset_t>(GetSize() - length_of_64_bit_region_);
194 }
195
196 template<bool is_64 = Is64Aware>
197 // Only enable this method for the 32-bit builder.
198 typename std::enable_if<!is_64, uoffset_t>::type GetSizeRelative32BitRegion()
199 const {
200 return static_cast<uoffset_t>(GetSize());
201 }
202
206 uint8_t *GetBufferPointer() const {
207 Finished();
208 return buf_.data();
209 }
210
214 flatbuffers::span<uint8_t> GetBufferSpan() const {
215 Finished();
216 return flatbuffers::span<uint8_t>(buf_.data(), buf_.size());
217 }
218
221 uint8_t *GetCurrentBufferPointer() const { return buf_.data(); }
222
227 FLATBUFFERS_ATTRIBUTE([[deprecated("use Release() instead")]])
228 DetachedBuffer ReleaseBufferPointer() {
229 Finished();
230 return buf_.release();
231 }
232
236 Finished();
237 return buf_.release();
238 }
239
249 uint8_t *ReleaseRaw(size_t &size, size_t &offset) {
250 Finished();
251 return buf_.release_raw(size, offset);
252 }
253
259 size_t GetBufferMinAlignment() const {
260 Finished();
261 return minalign_;
262 }
263
265 void Finished() const {
266 // If you get this assert, you're attempting to get access a buffer
267 // which hasn't been finished yet. Be sure to call
268 // FlatBufferBuilder::Finish with your root table.
269 // If you really need to access an unfinished buffer, call
270 // GetCurrentBufferPointer instead.
272 }
274
280 void ForceDefaults(bool fd) { force_defaults_ = fd; }
281
284 void DedupVtables(bool dedup) { dedup_vtables_ = dedup; }
285
287 void Pad(size_t num_bytes) { buf_.fill(num_bytes); }
288
289 void TrackMinAlign(size_t elem_size) {
290 if (elem_size > minalign_) minalign_ = elem_size;
291 }
292
293 void Align(size_t elem_size) {
294 TrackMinAlign(elem_size);
295 buf_.fill(PaddingBytes(buf_.size(), elem_size));
296 }
297
298 void PushFlatBuffer(const uint8_t *bytes, size_t size) {
299 PushBytes(bytes, size);
300 finished = true;
301 }
302
303 void PushBytes(const uint8_t *bytes, size_t size) { buf_.push(bytes, size); }
304
305 void PopBytes(size_t amount) { buf_.pop(amount); }
306
307 template<typename T> void AssertScalarT() {
308 // The code assumes power of 2 sizes and endian-swap-ability.
309 static_assert(flatbuffers::is_scalar<T>::value, "T must be a scalar type");
310 }
311
312 // Write a single aligned scalar to the buffer
313 template<typename T, typename ReturnT = uoffset_t>
314 ReturnT PushElement(T element) {
315 AssertScalarT<T>();
316 Align(sizeof(T));
317 buf_.push_small(EndianScalar(element));
318 return CalculateOffset<ReturnT>();
319 }
320
321 template<typename T, template<typename> class OffsetT = Offset>
322 uoffset_t PushElement(OffsetT<T> off) {
323 // Special case for offsets: see ReferTo below.
324 return PushElement(ReferTo(off.o));
325 }
326
327 // When writing fields, we track where they are, so we can create correct
328 // vtables later.
329 void TrackField(voffset_t field, uoffset_t off) {
330 FieldLoc fl = { off, field };
333 if (field > max_voffset_) { max_voffset_ = field; }
334 }
335
336 // Like PushElement, but additionally tracks the field this represents.
337 template<typename T> void AddElement(voffset_t field, T e, T def) {
338 // We don't serialize values equal to the default.
339 if (IsTheSameAs(e, def) && !force_defaults_) return;
340 TrackField(field, PushElement(e));
341 }
342
343 template<typename T> void AddElement(voffset_t field, T e) {
344 TrackField(field, PushElement(e));
345 }
346
347 template<typename T> void AddOffset(voffset_t field, Offset<T> off) {
348 if (off.IsNull()) return; // Don't store.
349 AddElement(field, ReferTo(off.o), static_cast<uoffset_t>(0));
350 }
351
352 template<typename T> void AddOffset(voffset_t field, Offset64<T> off) {
353 if (off.IsNull()) return; // Don't store.
354 AddElement(field, ReferTo(off.o), static_cast<uoffset64_t>(0));
355 }
356
357 template<typename T> void AddStruct(voffset_t field, const T *structptr) {
358 if (!structptr) return; // Default, don't store.
359 Align(AlignOf<T>());
360 buf_.push_small(*structptr);
361 TrackField(field, CalculateOffset<uoffset_t>());
362 }
363
364 void AddStructOffset(voffset_t field, uoffset_t off) {
365 TrackField(field, off);
366 }
367
368 // Offsets initially are relative to the end of the buffer (downwards).
369 // This function converts them to be relative to the current location
370 // in the buffer (when stored here), pointing upwards.
371 uoffset_t ReferTo(uoffset_t off) {
372 // Align to ensure GetSizeRelative32BitRegion() below is correct.
373 Align(sizeof(uoffset_t));
374 // 32-bit offsets are relative to the tail of the 32-bit region of the
375 // buffer. For most cases (without 64-bit entities) this is equivalent to
376 // size of the whole buffer (e.g. GetSize())
377 return ReferTo(off, GetSizeRelative32BitRegion());
378 }
379
380 uoffset64_t ReferTo(uoffset64_t off) {
381 // Align to ensure GetSize() below is correct.
382 Align(sizeof(uoffset64_t));
383 // 64-bit offsets are relative to tail of the whole buffer
384 return ReferTo(off, GetSize());
385 }
386
387 template<typename T, typename T2> T ReferTo(const T off, const T2 size) {
388 FLATBUFFERS_ASSERT(off && off <= size);
389 return size - off + static_cast<T>(sizeof(T));
390 }
391
392 template<typename T> T ReferTo(const T off, const T size) {
393 FLATBUFFERS_ASSERT(off && off <= size);
394 return size - off + static_cast<T>(sizeof(T));
395 }
396
397 void NotNested() {
398 // If you hit this, you're trying to construct a Table/Vector/String
399 // during the construction of its parent table (between the MyTableBuilder
400 // and table.Finish().
401 // Move the creation of these sub-objects to above the MyTableBuilder to
402 // not get this assert.
403 // Ignoring this assert may appear to work in simple cases, but the reason
404 // it is here is that storing objects in-line may cause vtable offsets
405 // to not fit anymore. It also leads to vtable duplication.
407 // If you hit this, fields were added outside the scope of a table.
409 }
410
411 // From generated code (or from the parser), we call StartTable/EndTable
412 // with a sequence of AddElement calls in between.
413 uoffset_t StartTable() {
414 NotNested();
415 nested = true;
417 }
418
419 // This finishes one serialized object by generating the vtable if it's a
420 // table, comparing it against existing vtables, and writing the
421 // resulting vtable offset.
422 uoffset_t EndTable(uoffset_t start) {
423 // If you get this assert, a corresponding StartTable wasn't called.
425 // Write the vtable offset, which is the start of any Table.
426 // We fill its value later.
427 // This is relative to the end of the 32-bit region.
428 const uoffset_t vtable_offset_loc =
429 static_cast<uoffset_t>(PushElement<soffset_t>(0));
430 // Write a vtable, which consists entirely of voffset_t elements.
431 // It starts with the number of offsets, followed by a type id, followed
432 // by the offsets themselves. In reverse:
433 // Include space for the last offset and ensure empty tables have a
434 // minimum size.
436 (std::max)(static_cast<voffset_t>(max_voffset_ + sizeof(voffset_t)),
439 const uoffset_t table_object_size = vtable_offset_loc - start;
440 // Vtable use 16bit offsets.
441 FLATBUFFERS_ASSERT(table_object_size < 0x10000);
442 WriteScalar<voffset_t>(buf_.data() + sizeof(voffset_t),
443 static_cast<voffset_t>(table_object_size));
444 WriteScalar<voffset_t>(buf_.data(), max_voffset_);
445 // Write the offsets into the table
446 for (auto it = buf_.scratch_end() - num_field_loc * sizeof(FieldLoc);
447 it < buf_.scratch_end(); it += sizeof(FieldLoc)) {
448 auto field_location = reinterpret_cast<FieldLoc *>(it);
449 const voffset_t pos =
450 static_cast<voffset_t>(vtable_offset_loc - field_location->off);
451 // If this asserts, it means you've set a field twice.
453 !ReadScalar<voffset_t>(buf_.data() + field_location->id));
454 WriteScalar<voffset_t>(buf_.data() + field_location->id, pos);
455 }
456 ClearOffsets();
457 auto vt1 = reinterpret_cast<voffset_t *>(buf_.data());
458 auto vt1_size = ReadScalar<voffset_t>(vt1);
459 auto vt_use = GetSizeRelative32BitRegion();
460 // See if we already have generated a vtable with this exact same
461 // layout before. If so, make it point to the old one, remove this one.
462 if (dedup_vtables_) {
463 for (auto it = buf_.scratch_data(); it < buf_.scratch_end();
464 it += sizeof(uoffset_t)) {
465 auto vt_offset_ptr = reinterpret_cast<uoffset_t *>(it);
466 auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(*vt_offset_ptr));
467 auto vt2_size = ReadScalar<voffset_t>(vt2);
468 if (vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size)) continue;
469 vt_use = *vt_offset_ptr;
470 buf_.pop(GetSizeRelative32BitRegion() - vtable_offset_loc);
471 break;
472 }
473 }
474 // If this is a new vtable, remember it.
475 if (vt_use == GetSizeRelative32BitRegion()) {
476 buf_.scratch_push_small(vt_use);
477 }
478 // Fill the vtable offset we created above.
479 // The offset points from the beginning of the object to where the vtable is
480 // stored.
481 // Offsets default direction is downward in memory for future format
482 // flexibility (storing all vtables at the start of the file).
483 WriteScalar(buf_.data_at(vtable_offset_loc + length_of_64_bit_region_),
484 static_cast<soffset_t>(vt_use) -
485 static_cast<soffset_t>(vtable_offset_loc));
486 nested = false;
487 return vtable_offset_loc;
488 }
489
490 FLATBUFFERS_ATTRIBUTE([[deprecated("call the version above instead")]])
491 uoffset_t EndTable(uoffset_t start, voffset_t /*numfields*/) {
492 return EndTable(start);
493 }
494
495 // This checks a required field has been set in a given table that has
496 // just been constructed.
497 template<typename T> void Required(Offset<T> table, voffset_t field) {
498 auto table_ptr = reinterpret_cast<const Table *>(buf_.data_at(table.o));
499 bool ok = table_ptr->GetOptionalFieldOffset(field) != 0;
500 // If this fails, the caller will show what field needs to be set.
502 (void)ok;
503 }
504
505 uoffset_t StartStruct(size_t alignment) {
506 Align(alignment);
508 }
509
510 uoffset_t EndStruct() { return GetSizeRelative32BitRegion(); }
511
512 void ClearOffsets() {
513 buf_.scratch_pop(num_field_loc * sizeof(FieldLoc));
514 num_field_loc = 0;
515 max_voffset_ = 0;
516 }
517
518 // Aligns such that when "len" bytes are written, an object can be written
519 // after it (forward in the buffer) with "alignment" without padding.
520 void PreAlign(size_t len, size_t alignment) {
521 if (len == 0) return;
522 TrackMinAlign(alignment);
523 buf_.fill(PaddingBytes(GetSize() + len, alignment));
524 }
525
526 // Aligns such than when "len" bytes are written, an object of type `AlignT`
527 // can be written after it (forward in the buffer) without padding.
528 template<typename AlignT> void PreAlign(size_t len) {
529 AssertScalarT<AlignT>();
530 PreAlign(len, AlignOf<AlignT>());
531 }
533
538 template<template<typename> class OffsetT = Offset>
539 OffsetT<String> CreateString(const char *str, size_t len) {
540 CreateStringImpl(str, len);
541 return OffsetT<String>(
542 CalculateOffset<typename OffsetT<String>::offset_type>());
543 }
544
548 template<template<typename> class OffsetT = Offset>
549 OffsetT<String> CreateString(const char *str) {
550 return CreateString<OffsetT>(str, strlen(str));
551 }
552
556 template<template<typename> class OffsetT = Offset>
557 OffsetT<String> CreateString(char *str) {
558 return CreateString<OffsetT>(str, strlen(str));
559 }
560
564 template<template<typename> class OffsetT = Offset>
565 OffsetT<String> CreateString(const std::string &str) {
566 return CreateString<OffsetT>(str.c_str(), str.length());
567 }
568
569 // clang-format off
570 #ifdef FLATBUFFERS_HAS_STRING_VIEW
574 template<template <typename> class OffsetT = Offset>
575 OffsetT<String>CreateString(flatbuffers::string_view str) {
576 return CreateString<OffsetT>(str.data(), str.size());
577 }
578 #endif // FLATBUFFERS_HAS_STRING_VIEW
579 // clang-format on
580
584 template<template<typename> class OffsetT = Offset>
585 OffsetT<String> CreateString(const String *str) {
586 return str ? CreateString<OffsetT>(str->c_str(), str->size()) : 0;
587 }
588
593 template<template<typename> class OffsetT = Offset,
594 // No need to explicitly declare the T type, let the compiler deduce
595 // it.
596 int &...ExplicitArgumentBarrier, typename T>
597 OffsetT<String> CreateString(const T &str) {
598 return CreateString<OffsetT>(str.c_str(), str.length());
599 }
600
608 Offset<String> CreateSharedString(const char *str, size_t len) {
609 FLATBUFFERS_ASSERT(FLATBUFFERS_GENERAL_HEAP_ALLOC_OK);
610 if (!string_pool) {
612 }
613
614 const size_t size_before_string = buf_.size();
615 // Must first serialize the string, since the set is all offsets into
616 // buffer.
617 const Offset<String> off = CreateString<Offset>(str, len);
618 auto it = string_pool->find(off);
619 // If it exists we reuse existing serialized data!
620 if (it != string_pool->end()) {
621 // We can remove the string we serialized.
622 buf_.pop(buf_.size() - size_before_string);
623 return *it;
624 }
625 // Record this string for future use.
626 string_pool->insert(off);
627 return off;
628 }
629
630#ifdef FLATBUFFERS_HAS_STRING_VIEW
637 Offset<String> CreateSharedString(const flatbuffers::string_view str) {
638 return CreateSharedString(str.data(), str.size());
639 }
640#else
647 Offset<String> CreateSharedString(const char *str) {
648 return CreateSharedString(str, strlen(str));
649 }
650
657 Offset<String> CreateSharedString(const std::string &str) {
658 return CreateSharedString(str.c_str(), str.length());
659 }
660#endif
661
668 Offset<String> CreateSharedString(const String *str) {
669 return str ? CreateSharedString(str->c_str(), str->size()) : 0;
670 }
671
673 template<typename LenT = uoffset_t, typename ReturnT = uoffset_t>
674 ReturnT EndVector(size_t len) {
675 FLATBUFFERS_ASSERT(nested); // Hit if no corresponding StartVector.
676 nested = false;
677 return PushElement<LenT, ReturnT>(static_cast<LenT>(len));
678 }
679
680 template<template<typename> class OffsetT = Offset, typename LenT = uint32_t>
681 void StartVector(size_t len, size_t elemsize, size_t alignment) {
682 NotNested();
683 nested = true;
684 // Align to the Length type of the vector (either 32-bit or 64-bit), so
685 // that the length of the buffer can be added without padding.
686 PreAlign<LenT>(len * elemsize);
687 PreAlign(len * elemsize, alignment); // Just in case elemsize > uoffset_t.
688 }
689
690 template<typename T, template<typename> class OffsetT = Offset,
691 typename LenT = uint32_t>
692 void StartVector(size_t len) {
693 return StartVector<OffsetT, LenT>(len, sizeof(T), AlignOf<T>());
694 }
695
696 // Call this right before StartVector/CreateVector if you want to force the
697 // alignment to be something different than what the element size would
698 // normally dictate.
699 // This is useful when storing a nested_flatbuffer in a vector of bytes,
700 // or when storing SIMD floats, etc.
701 void ForceVectorAlignment(size_t len, size_t elemsize, size_t alignment) {
702 if (len == 0) return;
703 FLATBUFFERS_ASSERT(VerifyAlignmentRequirements(alignment));
704 PreAlign(len * elemsize, alignment);
705 }
706
707 // Similar to ForceVectorAlignment but for String fields.
708 void ForceStringAlignment(size_t len, size_t alignment) {
709 if (len == 0) return;
710 FLATBUFFERS_ASSERT(VerifyAlignmentRequirements(alignment));
711 PreAlign((len + 1) * sizeof(char), alignment);
712 }
713
715
725 template<typename T, template<typename...> class OffsetT = Offset,
726 template<typename...> class VectorT = Vector>
727 OffsetT<VectorT<T>> CreateVector(const T *v, size_t len) {
728 // The type of the length field in the vector.
729 typedef typename VectorT<T>::size_type LenT;
730 typedef typename OffsetT<VectorT<T>>::offset_type offset_type;
731 // If this assert hits, you're specifying a template argument that is
732 // causing the wrong overload to be selected, remove it.
733 AssertScalarT<T>();
734 StartVector<T, OffsetT, LenT>(len);
735 if (len > 0) {
736 // clang-format off
737 #if FLATBUFFERS_LITTLEENDIAN
738 PushBytes(reinterpret_cast<const uint8_t *>(v), len * sizeof(T));
739 #else
740 if (sizeof(T) == 1) {
741 PushBytes(reinterpret_cast<const uint8_t *>(v), len);
742 } else {
743 for (auto i = len; i > 0; ) {
744 PushElement(v[--i]);
745 }
746 }
747 #endif
748 // clang-format on
749 }
750 return OffsetT<VectorT<T>>(EndVector<LenT, offset_type>(len));
751 }
752
760 template<typename T, class C> Offset<Vector<T>> CreateVector(const C &array) {
761 return CreateVector(array.data(), array.size());
762 }
763
769 template<typename T>
770 Offset<Vector<T>> CreateVector(std::initializer_list<T> v) {
771 return CreateVector(v.begin(), v.size());
772 }
773
774 template<typename T>
775 Offset<Vector<Offset<T>>> CreateVector(const Offset<T> *v, size_t len) {
776 StartVector<Offset<T>>(len);
777 for (auto i = len; i > 0;) { PushElement(v[--i]); }
778 return Offset<Vector<Offset<T>>>(EndVector(len));
779 }
780
787 template<typename T, typename Alloc = std::allocator<T>>
788 Offset<Vector<T>> CreateVector(const std::vector<T, Alloc> &v) {
789 return CreateVector(data(v), v.size());
790 }
791
792 template<template<typename...> class VectorT = Vector64,
793 int &...ExplicitArgumentBarrier, typename T>
794 Offset64<VectorT<T>> CreateVector64(const std::vector<T> &v) {
795 return CreateVector<T, Offset64, VectorT>(data(v), v.size());
796 }
797
798 // vector<bool> may be implemented using a bit-set, so we can't access it as
799 // an array. Instead, read elements manually.
800 // Background: https://isocpp.org/blog/2012/11/on-vectorbool
801 Offset<Vector<uint8_t>> CreateVector(const std::vector<bool> &v) {
802 StartVector<uint8_t>(v.size());
803 for (auto i = v.size(); i > 0;) {
804 PushElement(static_cast<uint8_t>(v[--i]));
805 }
806 return Offset<Vector<uint8_t>>(EndVector(v.size()));
807 }
808
816 template<typename T>
817 Offset<Vector<T>> CreateVector(size_t vector_size,
818 const std::function<T(size_t i)> &f) {
819 FLATBUFFERS_ASSERT(FLATBUFFERS_GENERAL_HEAP_ALLOC_OK);
820 std::vector<T> elems(vector_size);
821 for (size_t i = 0; i < vector_size; i++) elems[i] = f(i);
822 return CreateVector(elems);
823 }
824
836 template<typename T, typename F, typename S>
837 Offset<Vector<T>> CreateVector(size_t vector_size, F f, S *state) {
838 FLATBUFFERS_ASSERT(FLATBUFFERS_GENERAL_HEAP_ALLOC_OK);
839 std::vector<T> elems(vector_size);
840 for (size_t i = 0; i < vector_size; i++) elems[i] = f(i, state);
841 return CreateVector(elems);
842 }
843
852 template<typename StringType = std::string,
853 typename Alloc = std::allocator<StringType>>
854 Offset<Vector<Offset<String>>> CreateVectorOfStrings(
855 const std::vector<StringType, Alloc> &v) {
856 return CreateVectorOfStrings(v.cbegin(), v.cend());
857 }
858
865 template<class It>
866 Offset<Vector<Offset<String>>> CreateVectorOfStrings(It begin, It end) {
867 auto size = std::distance(begin, end);
868 auto scratch_buffer_usage = size * sizeof(Offset<String>);
869 // If there is not enough space to store the offsets, there definitely won't
870 // be enough space to store all the strings. So ensuring space for the
871 // scratch region is OK, for if it fails, it would have failed later.
872 buf_.ensure_space(scratch_buffer_usage);
873 for (auto it = begin; it != end; ++it) {
875 }
876 StartVector<Offset<String>>(size);
877 for (auto i = 1; i <= size; i++) {
878 // Note we re-evaluate the buf location each iteration to account for any
879 // underlying buffer resizing that may occur.
880 PushElement(*reinterpret_cast<Offset<String> *>(
881 buf_.scratch_end() - i * sizeof(Offset<String>)));
882 }
883 buf_.scratch_pop(scratch_buffer_usage);
884 return Offset<Vector<Offset<String>>>(EndVector(size));
885 }
886
894 template<typename T, template<typename...> class OffsetT = Offset,
895 template<typename...> class VectorT = Vector>
896 OffsetT<VectorT<const T *>> CreateVectorOfStructs(const T *v, size_t len) {
897 // The type of the length field in the vector.
898 typedef typename VectorT<T>::size_type LenT;
899 typedef typename OffsetT<VectorT<const T *>>::offset_type offset_type;
900
901 StartVector<OffsetT, LenT>(len * sizeof(T) / AlignOf<T>(), sizeof(T),
902 AlignOf<T>());
903 if (len > 0) {
904 PushBytes(reinterpret_cast<const uint8_t *>(v), sizeof(T) * len);
905 }
906 return OffsetT<VectorT<const T *>>(EndVector<LenT, offset_type>(len));
907 }
908
917 template<typename T>
918 Offset<Vector<const T *>> CreateVectorOfStructs(
919 size_t vector_size, const std::function<void(size_t i, T *)> &filler) {
920 T *structs = StartVectorOfStructs<T>(vector_size);
921 for (size_t i = 0; i < vector_size; i++) {
922 filler(i, structs);
923 structs++;
924 }
925 return EndVectorOfStructs<T>(vector_size);
926 }
927
937 template<typename T, typename F, typename S>
938 Offset<Vector<const T *>> CreateVectorOfStructs(size_t vector_size, F f,
939 S *state) {
940 T *structs = StartVectorOfStructs<T>(vector_size);
941 for (size_t i = 0; i < vector_size; i++) {
942 f(i, structs, state);
943 structs++;
944 }
945 return EndVectorOfStructs<T>(vector_size);
946 }
947
954 template<typename T, template<typename...> class OffsetT = Offset,
955 template<typename...> class VectorT = Vector,
956 typename Alloc = std::allocator<T>>
957 OffsetT<VectorT<const T *>> CreateVectorOfStructs(
958 const std::vector<T, Alloc> &v) {
959 return CreateVectorOfStructs<T, OffsetT, VectorT>(data(v), v.size());
960 }
961
962 template<template<typename...> class VectorT = Vector64, int &..., typename T>
963 Offset64<VectorT<const T *>> CreateVectorOfStructs64(
964 const std::vector<T> &v) {
965 return CreateVectorOfStructs<T, Offset64, VectorT>(data(v), v.size());
966 }
967
978 template<typename T, typename S>
979 Offset<Vector<const T *>> CreateVectorOfNativeStructs(
980 const S *v, size_t len, T (*const pack_func)(const S &)) {
981 FLATBUFFERS_ASSERT(pack_func);
982 auto structs = StartVectorOfStructs<T>(len);
983 for (size_t i = 0; i < len; i++) { structs[i] = pack_func(v[i]); }
984 return EndVectorOfStructs<T>(len);
985 }
986
995 template<typename T, typename S>
996 Offset<Vector<const T *>> CreateVectorOfNativeStructs(const S *v,
997 size_t len) {
998 extern T Pack(const S &);
999 return CreateVectorOfNativeStructs(v, len, Pack);
1000 }
1001
1012 template<typename T, typename S, typename Alloc = std::allocator<T>>
1013 Offset<Vector<const T *>> CreateVectorOfNativeStructs(
1014 const std::vector<S, Alloc> &v, T (*const pack_func)(const S &)) {
1015 return CreateVectorOfNativeStructs<T, S>(data(v), v.size(), pack_func);
1016 }
1017
1026 template<typename T, typename S, typename Alloc = std::allocator<S>>
1027 Offset<Vector<const T *>> CreateVectorOfNativeStructs(
1028 const std::vector<S, Alloc> &v) {
1029 return CreateVectorOfNativeStructs<T, S>(data(v), v.size());
1030 }
1031
1033 template<typename T> struct StructKeyComparator {
1034 bool operator()(const T &a, const T &b) const {
1035 return a.KeyCompareLessThan(&b);
1036 }
1037 };
1039
1047 template<typename T, typename Alloc = std::allocator<T>>
1048 Offset<Vector<const T *>> CreateVectorOfSortedStructs(
1049 std::vector<T, Alloc> *v) {
1050 return CreateVectorOfSortedStructs(data(*v), v->size());
1051 }
1052
1061 template<typename T, typename S, typename Alloc = std::allocator<T>>
1062 Offset<Vector<const T *>> CreateVectorOfSortedNativeStructs(
1063 std::vector<S, Alloc> *v) {
1064 return CreateVectorOfSortedNativeStructs<T, S>(data(*v), v->size());
1065 }
1066
1075 template<typename T>
1076 Offset<Vector<const T *>> CreateVectorOfSortedStructs(T *v, size_t len) {
1077 std::stable_sort(v, v + len, StructKeyComparator<T>());
1078 return CreateVectorOfStructs(v, len);
1079 }
1080
1090 template<typename T, typename S>
1091 Offset<Vector<const T *>> CreateVectorOfSortedNativeStructs(S *v,
1092 size_t len) {
1093 extern T Pack(const S &);
1094 auto structs = StartVectorOfStructs<T>(len);
1095 for (size_t i = 0; i < len; i++) { structs[i] = Pack(v[i]); }
1096 std::stable_sort(structs, structs + len, StructKeyComparator<T>());
1097 return EndVectorOfStructs<T>(len);
1098 }
1099
1101 template<typename T> struct TableKeyComparator {
1102 explicit TableKeyComparator(vector_downward<SizeT> &buf) : buf_(buf) {}
1103 TableKeyComparator(const TableKeyComparator &other) : buf_(other.buf_) {}
1104 bool operator()(const Offset<T> &a, const Offset<T> &b) const {
1105 auto table_a = reinterpret_cast<T *>(buf_.data_at(a.o));
1106 auto table_b = reinterpret_cast<T *>(buf_.data_at(b.o));
1107 return table_a->KeyCompareLessThan(table_b);
1108 }
1109 vector_downward<SizeT> &buf_;
1110
1111 private:
1112 FLATBUFFERS_DELETE_FUNC(
1113 TableKeyComparator &operator=(const TableKeyComparator &other));
1114 };
1116
1125 template<typename T>
1126 Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(Offset<T> *v,
1127 size_t len) {
1128 std::stable_sort(v, v + len, TableKeyComparator<T>(buf_));
1129 return CreateVector(v, len);
1130 }
1131
1139 template<typename T, typename Alloc = std::allocator<T>>
1140 Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(
1141 std::vector<Offset<T>, Alloc> *v) {
1142 return CreateVectorOfSortedTables(data(*v), v->size());
1143 }
1144
1152 uoffset_t CreateUninitializedVector(size_t len, size_t elemsize,
1153 size_t alignment, uint8_t **buf) {
1154 NotNested();
1155 StartVector(len, elemsize, alignment);
1156 buf_.make_space(len * elemsize);
1157 const uoffset_t vec_start = GetSizeRelative32BitRegion();
1158 auto vec_end = EndVector(len);
1159 *buf = buf_.data_at(vec_start);
1160 return vec_end;
1161 }
1162
1163 FLATBUFFERS_ATTRIBUTE([[deprecated("call the version above instead")]])
1164 uoffset_t CreateUninitializedVector(size_t len, size_t elemsize,
1165 uint8_t **buf) {
1166 return CreateUninitializedVector(len, elemsize, elemsize, buf);
1167 }
1168
1177 template<typename T>
1178 Offset<Vector<T>> CreateUninitializedVector(size_t len, T **buf) {
1179 AssertScalarT<T>();
1180 return CreateUninitializedVector(len, sizeof(T), AlignOf<T>(),
1181 reinterpret_cast<uint8_t **>(buf));
1182 }
1183
1184 template<typename T>
1185 Offset<Vector<const T *>> CreateUninitializedVectorOfStructs(size_t len,
1186 T **buf) {
1187 return CreateUninitializedVector(len, sizeof(T), AlignOf<T>(),
1188 reinterpret_cast<uint8_t **>(buf));
1189 }
1190
1191 // @brief Create a vector of scalar type T given as input a vector of scalar
1192 // type U, useful with e.g. pre "enum class" enums, or any existing scalar
1193 // data of the wrong type.
1194 template<typename T, typename U>
1195 Offset<Vector<T>> CreateVectorScalarCast(const U *v, size_t len) {
1196 AssertScalarT<T>();
1197 AssertScalarT<U>();
1198 StartVector<T>(len);
1199 for (auto i = len; i > 0;) { PushElement(static_cast<T>(v[--i])); }
1200 return Offset<Vector<T>>(EndVector(len));
1201 }
1202
1204 template<typename T> Offset<const T *> CreateStruct(const T &structobj) {
1205 NotNested();
1206 Align(AlignOf<T>());
1207 buf_.push_small(structobj);
1208 return Offset<const T *>(
1209 CalculateOffset<typename Offset<const T *>::offset_type>());
1210 }
1211
1215 template<typename T>
1216 void Finish(Offset<T> root, const char *file_identifier = nullptr) {
1217 Finish(root.o, file_identifier, false);
1218 }
1219
1227 template<typename T>
1228 void FinishSizePrefixed(Offset<T> root,
1229 const char *file_identifier = nullptr) {
1230 Finish(root.o, file_identifier, true);
1231 }
1232
1236
1238 static const size_t kFileIdentifierLength =
1239 ::flatbuffers::kFileIdentifierLength;
1240
1241 protected:
1242 // You shouldn't really be copying instances of this class.
1245
1246 void Finish(uoffset_t root, const char *file_identifier, bool size_prefix) {
1247 NotNested();
1249
1250 const size_t prefix_size = size_prefix ? sizeof(SizeT) : 0;
1251 // Make sure we track the alignment of the size prefix.
1252 TrackMinAlign(prefix_size);
1253
1254 const size_t root_offset_size = sizeof(uoffset_t);
1255 const size_t file_id_size = file_identifier ? kFileIdentifierLength : 0;
1256
1257 // This will cause the whole buffer to be aligned.
1258 PreAlign(prefix_size + root_offset_size + file_id_size, minalign_);
1259
1260 if (file_identifier) {
1261 FLATBUFFERS_ASSERT(strlen(file_identifier) == kFileIdentifierLength);
1262 PushBytes(reinterpret_cast<const uint8_t *>(file_identifier),
1264 }
1265 PushElement(ReferTo(root)); // Location of root.
1266 if (size_prefix) { PushElement(GetSize()); }
1267 finished = true;
1268 }
1269
1270 struct FieldLoc {
1271 uoffset_t off;
1272 voffset_t id;
1273 };
1274
1276
1277 // Accumulating offsets of table members while it is being built.
1278 // We store these in the scratch pad of buf_, after the vtable offsets.
1279 uoffset_t num_field_loc;
1280 // Track how much of the vtable is in use, so we can output the most compact
1281 // possible vtable.
1282 voffset_t max_voffset_;
1283
1284 // This is the length of the 64-bit region of the buffer. The buffer supports
1285 // 64-bit offsets by forcing serialization of those elements in the "tail"
1286 // region of the buffer (i.e. "64-bit region"). To properly keep track of
1287 // offsets that are referenced from the tail of the buffer to not overflow
1288 // their size (e.g. Offset is a uint32_t type), the boundary of the 32-/64-bit
1289 // regions must be tracked.
1290 //
1291 // [ Complete FlatBuffer ]
1292 // [32-bit region][64-bit region]
1293 // ^ ^
1294 // | Tail of the buffer.
1295 // |
1296 // Tail of the 32-bit region of the buffer.
1297 //
1298 // This keeps track of the size of the 64-bit region so that the tail of the
1299 // 32-bit region can be calculated as `GetSize() - length_of_64_bit_region_`.
1300 //
1301 // This will remain 0 if no 64-bit offset types are added to the buffer.
1303
1304 // Ensure objects are not nested.
1306
1307 // Ensure the buffer is finished before it is being accessed.
1309
1311
1312 bool force_defaults_; // Serialize values equal to their defaults anyway.
1313
1315
1318 : buf_(&buf) {}
1319 bool operator()(const Offset<String> &a, const Offset<String> &b) const {
1320 auto stra = reinterpret_cast<const String *>(buf_->data_at(a.o));
1321 auto strb = reinterpret_cast<const String *>(buf_->data_at(b.o));
1322 return StringLessThan(stra->data(), stra->size(), strb->data(),
1323 strb->size());
1324 }
1326 };
1327
1328 // For use with CreateSharedString. Instantiated on first use only.
1329 typedef std::set<Offset<String>, StringOffsetCompare> StringOffsetMap;
1331
1332 private:
1333 void CanAddOffset64() {
1334 // If you hit this assertion, you are attempting to add a 64-bit offset to
1335 // a 32-bit only builder. This is because the builder has overloads that
1336 // differ only on the offset size returned: e.g.:
1337 //
1338 // FlatBufferBuilder builder;
1339 // Offset64<String> string_offset = builder.CreateString<Offset64>();
1340 //
1341 // Either use a 64-bit aware builder, or don't try to create an Offset64
1342 // return type.
1343 //
1344 // TODO(derekbailey): we can probably do more enable_if to avoid this
1345 // looking like its possible to the user.
1346 static_assert(Is64Aware, "cannot add 64-bit offset to a 32-bit builder");
1347
1348 // If you hit this assertion, you are attempting to add an 64-bit offset
1349 // item after already serializing a 32-bit item. All 64-bit offsets have to
1350 // added to the tail of the buffer before any 32-bit items can be added.
1351 // Otherwise some items might not be addressable due to the maximum range of
1352 // the 32-bit offset.
1354 }
1355
1360 void CreateStringImpl(const char *str, size_t len) {
1361 NotNested();
1362 PreAlign<uoffset_t>(len + 1); // Always 0-terminated.
1363 buf_.fill(1);
1364 PushBytes(reinterpret_cast<const uint8_t *>(str), len);
1365 PushElement(static_cast<uoffset_t>(len));
1366 }
1367
1368 // Allocates space for a vector of structures.
1369 // Must be completed with EndVectorOfStructs().
1370 template<typename T, template<typename> class OffsetT = Offset>
1371 T *StartVectorOfStructs(size_t vector_size) {
1372 StartVector<OffsetT>(vector_size * sizeof(T) / AlignOf<T>(), sizeof(T),
1373 AlignOf<T>());
1374 return reinterpret_cast<T *>(buf_.make_space(vector_size * sizeof(T)));
1375 }
1376
1377 // End the vector of structures in the flatbuffers.
1378 // Vector should have previously be started with StartVectorOfStructs().
1379 template<typename T, template<typename> class OffsetT = Offset>
1380 OffsetT<Vector<const T *>> EndVectorOfStructs(size_t vector_size) {
1381 return OffsetT<Vector<const T *>>(
1382 EndVector<typename Vector<const T *>::size_type,
1383 typename OffsetT<Vector<const T *>>::offset_type>(
1384 vector_size));
1385 }
1386
1387 template<typename T>
1388 typename std::enable_if<std::is_same<T, uoffset_t>::value, T>::type
1389 CalculateOffset() {
1390 // Default to the end of the 32-bit region. This may or may not be the end
1391 // of the buffer, depending on if any 64-bit offsets have been added.
1393 }
1394
1395 // Specializations to handle the 64-bit CalculateOffset, which is relative to
1396 // end of the buffer.
1397 template<typename T>
1398 typename std::enable_if<std::is_same<T, uoffset64_t>::value, T>::type
1399 CalculateOffset() {
1400 // This should never be compiled in when not using a 64-bit builder.
1401 static_assert(Is64Aware, "invalid 64-bit offset in 32-bit builder");
1402
1403 // Store how big the 64-bit region of the buffer is, so we can determine
1404 // where the 32/64 bit boundary is.
1406
1408 }
1409};
1411
1412// Hack to `FlatBufferBuilder` mean `FlatBufferBuilder<false>` or
1413// `FlatBufferBuilder<>`, where the template < > syntax is required.
1416
1417// These are external due to GCC not allowing them in the class.
1418// See: https://stackoverflow.com/q/8061456/868247
1419template<>
1420template<>
1421inline Offset64<String> FlatBufferBuilder64::CreateString(const char *str,
1422 size_t len) {
1423 CanAddOffset64();
1424 CreateStringImpl(str, len);
1425 return Offset64<String>(
1426 CalculateOffset<typename Offset64<String>::offset_type>());
1427}
1428
1429// Used to distinguish from real Offsets.
1430template<typename T = void> struct EmptyOffset {};
1431
1432// TODO(derekbailey): it would be nice to combine these two methods.
1433template<>
1434template<>
1435inline void FlatBufferBuilder64::StartVector<Offset64, uint32_t>(
1436 size_t len, size_t elemsize, size_t alignment) {
1437 CanAddOffset64();
1438 StartVector<EmptyOffset, uint32_t>(len, elemsize, alignment);
1439}
1440
1441template<>
1442template<>
1443inline void FlatBufferBuilder64::StartVector<Offset64, uint64_t>(
1444 size_t len, size_t elemsize, size_t alignment) {
1445 CanAddOffset64();
1446 StartVector<EmptyOffset, uint64_t>(len, elemsize, alignment);
1447}
1448
1452template<typename T>
1454 return reinterpret_cast<T *>(fbb.GetCurrentBufferPointer() + fbb.GetSize() -
1455 offset.o);
1456}
1457
1458template<typename T>
1460 return GetMutableTemporaryPointer<T>(fbb, offset);
1461}
1462
1463} // namespace flatbuffers
1464
1465#endif // FLATBUFFERS_FLATBUFFER_BUILDER_H_
int32_t type
#define S(content)
Definition Subnet.cpp:30
int Offset(const Dims< 4 > &dims, int i0, int i1, int i2, int i3)
Definition Dims.h:64
#define FLATBUFFERS_ASSERT
Definition base.h:21
static const size_t kFileIdentifierLength
The length of a FlatBuffer file header.
uoffset_t CreateUninitializedVector(size_t len, size_t elemsize, size_t alignment, uint8_t **buf)
Specialized version of CreateVector for non-copying use cases. Write the data any time later to the r...
uint8_t * ReleaseRaw(size_t &size, size_t &offset)
Get the released pointer to the serialized buffer.
OffsetT< String > CreateString(char *str)
Store a string in the buffer, which is null-terminated.
Offset< const T * > CreateStruct(const T &structobj)
Write a struct by itself, typically to be part of a union.
FlatBufferBuilderImpl & operator=(FlatBufferBuilderImpl &&other) noexcept
Move assignment operator for FlatBufferBuilder.
FlatBufferBuilderImpl(size_t initial_size=1024, Allocator *allocator=nullptr, bool own_allocator=false, size_t buffer_minalign=AlignOf< largest_scalar_t >())
Default constructor for FlatBufferBuilder.
OffsetT< String > CreateString(const String *str)
Store a string in the buffer, which can contain any binary data.
OffsetT< String > CreateString(const char *str, size_t len)
Store a string in the buffer, which can contain any binary data.
uint8_t * GetCurrentBufferPointer() const
Get a pointer to an unfinished buffer.
size_t GetBufferMinAlignment() const
get the minimum alignment this buffer needs to be accessed properly. This is only known once all elem...
void Finish(uoffset_t root, const char *file_identifier, bool size_prefix)
Offset< String > CreateSharedString(const String *str)
Store a string in the buffer, which can contain any binary data. If a string with this exact contents...
Offset< Vector< const T * > > CreateUninitializedVectorOfStructs(size_t len, T **buf)
std::set< Offset< String >, StringOffsetCompare > StringOffsetMap
Offset< Vector< const T * > > CreateVectorOfNativeStructs(const std::vector< S, Alloc > &v, T(*const pack_func)(const S &))
Serialize a std::vector of native structs into a FlatBuffer vector.
Offset< String > CreateSharedString(const std::string &str)
Store a string in the buffer, which can contain any binary data. If a string with this exact contents...
Offset< Vector< T > > CreateVector(size_t vector_size, F f, S *state)
Serialize values returned by a function into a FlatBuffer vector. This is a convenience function that...
Offset< Vector< Offset< T > > > CreateVectorOfSortedTables(std::vector< Offset< T >, Alloc > *v)
Serialize an array of table offsets as a vector in the buffer in sorted order.
OffsetT< String > CreateString(const T &str)
Store a string in the buffer, which can contain any binary data.
Offset< Vector< T > > CreateVector(size_t vector_size, const std::function< T(size_t i)> &f)
Serialize values returned by a function into a FlatBuffer vector. This is a convenience function that...
Offset< Vector< const T * > > CreateVectorOfStructs(size_t vector_size, const std::function< void(size_t i, T *)> &filler)
Serialize an array of structs into a FlatBuffer vector.
Offset< Vector< T > > CreateVectorScalarCast(const U *v, size_t len)
FlatBufferBuilderImpl(const FlatBufferBuilderImpl &)
std::conditional< Is64Aware, uoffset64_t, uoffset_t >::type SizeT
Offset< Vector< uint8_t > > CreateVector(const std::vector< bool > &v)
Offset< Vector< const T * > > CreateVectorOfSortedNativeStructs(S *v, size_t len)
Serialize an array of native structs into a FlatBuffer vector in sorted order.
Offset< Vector< Offset< T > > > CreateVector(const Offset< T > *v, size_t len)
Offset< String > CreateSharedString(const char *str, size_t len)
Store a string in the buffer, which can contain any binary data. If a string with this exact contents...
Offset< Vector< Offset< String > > > CreateVectorOfStrings(It begin, It end)
Serialize a collection of Strings into a FlatBuffer vector. This is a convenience function for a comm...
void Finish(Offset< T > root, const char *file_identifier=nullptr)
Finish serializing a buffer by writing the root offset.
Offset< Vector< T > > CreateVector(std::initializer_list< T > v)
Serialize an initializer list into a FlatBuffer vector.
Offset< Vector< Offset< String > > > CreateVectorOfStrings(const std::vector< StringType, Alloc > &v)
Serialize a std::vector<StringType> into a FlatBuffer vector. whereas StringType is any type that is ...
OffsetT< String > CreateString(const std::string &str)
Store a string in the buffer, which can contain any binary data.
SizeT GetSize() const
The current size of the serialized buffer, counting from the end.
Offset< Vector< const T * > > CreateVectorOfStructs(size_t vector_size, F f, S *state)
Serialize an array of structs into a FlatBuffer vector.
Offset< Vector< const T * > > CreateVectorOfSortedStructs(std::vector< T, Alloc > *v)
Serialize a std::vector of structs into a FlatBuffer vector in sorted order.
DetachedBuffer Release()
Get the released DetachedBuffer.
std::enable_if<!is_64, uoffset_t >::type GetSizeRelative32BitRegion() const
FLATBUFFERS_ATTRIBUTE() DetachedBuffer ReleaseBufferPointer()
Get the released pointer to the serialized buffer.
Offset< Vector< T > > CreateVector(const std::vector< T, Alloc > &v)
Serialize a std::vector into a FlatBuffer vector.
void Clear()
Reset all the state in this FlatBufferBuilder so it can be reused to construct another buffer.
Offset64< VectorT< const T * > > CreateVectorOfStructs64(const std::vector< T > &v)
OffsetT< VectorT< const T * > > CreateVectorOfStructs(const std::vector< T, Alloc > &v)
Serialize a std::vector of structs into a FlatBuffer vector.
Offset< Vector< const T * > > CreateVectorOfNativeStructs(const std::vector< S, Alloc > &v)
Serialize a std::vector of native structs into a FlatBuffer vector.
void Swap(FlatBufferBuilderImpl &other)
void FinishSizePrefixed(Offset< T > root, const char *file_identifier=nullptr)
Finish a buffer with a 32 bit size field pre-fixed (size of the buffer following the size field)....
Offset< Vector< const T * > > CreateVectorOfSortedNativeStructs(std::vector< S, Alloc > *v)
Serialize a std::vector of native structs into a FlatBuffer vector in sorted order.
Offset64< VectorT< T > > CreateVector64(const std::vector< T > &v)
Offset< String > CreateSharedString(const char *str)
Store a string in the buffer, which null-terminated. If a string with this exact contents has already...
OffsetT< String > CreateString(const char *str)
Store a string in the buffer, which is null-terminated.
FlatBufferBuilderImpl(FlatBufferBuilderImpl &&other) noexcept
Move constructor for FlatBufferBuilder.
void ForceDefaults(bool fd)
In order to save space, fields that are set to their default value don't get serialized into the buff...
OffsetT< VectorT< T > > CreateVector(const T *v, size_t len)
Serialize an array into a FlatBuffer vector.
flatbuffers::span< uint8_t > GetBufferSpan() const
Get the serialized buffer (after you call Finish()) as a span.
void DedupVtables(bool dedup)
By default vtables are deduped in order to save space.
Offset< Vector< const T * > > CreateVectorOfNativeStructs(const S *v, size_t len, T(*const pack_func)(const S &))
Serialize an array of native structs into a FlatBuffer vector.
Offset< Vector< T > > CreateUninitializedVector(size_t len, T **buf)
Specialized version of CreateVector for non-copying use cases. Write the data any time later to the r...
std::enable_if< is_64, uoffset_t >::type GetSizeRelative32BitRegion() const
The current size of the serialized buffer relative to the end of the 32-bit region.
Offset< Vector< Offset< T > > > CreateVectorOfSortedTables(Offset< T > *v, size_t len)
Serialize an array of table offsets as a vector in the buffer in sorted order.
Offset< Vector< const T * > > CreateVectorOfSortedStructs(T *v, size_t len)
Serialize an array of structs into a FlatBuffer vector in sorted order.
Offset< Vector< T > > CreateVector(const C &array)
Serialize an array like object into a FlatBuffer vector.
uint8_t * GetBufferPointer() const
Get the serialized buffer (after you call Finish()).
Offset< Vector< const T * > > CreateVectorOfNativeStructs(const S *v, size_t len)
Serialize an array of native structs into a FlatBuffer vector.
FlatBufferBuilderImpl & operator=(const FlatBufferBuilderImpl &)
OffsetT< VectorT< const T * > > CreateVectorOfStructs(const T *v, size_t len)
Serialize an array of structs into a FlatBuffer vector.
void SwapBufAllocator(FlatBufferBuilderImpl &other)
void scratch_pop(size_t bytes_to_remove)
void fill(size_t zero_pad_bytes)
void push(const uint8_t *bytes, size_t num)
void swap_allocator(vector_downward &other)
uint8_t * make_space(size_t len)
uint8_t * release_raw(size_t &allocated_bytes, size_t &offset)
void swap(vector_downward &other)
void scratch_push_small(const T &t)
void fill_big(size_t zero_pad_bytes)
void push_small(const T &little_endian_t)
void pop(size_t bytes_to_remove)
size_t ensure_space(size_t len)
uint8_t * data_at(size_t offset) const
__global uchar * offset(const Image *img, int x, int y)
Definition helpers.h:540
T * GetMutableTemporaryPointer(FlatBufferBuilder &fbb, Offset< T > offset)
const T * GetTemporaryPointer(FlatBufferBuilder &fbb, Offset< T > offset)
voffset_t FieldIndexToOffset(voffset_t field_id)
Vector< T, uoffset64_t > Vector64
Definition vector.h:304
const T * data(const std::vector< T, Alloc > &v)
int32_t size[5]
Definition Slice.cpp:35
int32_t begin[5]
Definition Slice.cpp:33
src_tensor allocator() -> init(p.src_info< NHWC >())
bool operator()(const Offset< String > &a, const Offset< String > &b) const