nvfuser-cu121-torch25 0.2.25.dev20250201__cp312-cp312-manylinux_2_28_x86_64.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (242) hide show
  1. nvfuser/_C.cpython-312-x86_64-linux-gnu.so +0 -0
  2. nvfuser/__init__.py +618 -0
  3. nvfuser/__init__.pyi +4 -0
  4. nvfuser/contrib/__init__.py +9 -0
  5. nvfuser/contrib/nn/__init__.py +13 -0
  6. nvfuser/contrib/nn/normalization.py +725 -0
  7. nvfuser/include/nvfuser/alias_analysis.h +116 -0
  8. nvfuser/include/nvfuser/bfs.h +929 -0
  9. nvfuser/include/nvfuser/codegen.h +26 -0
  10. nvfuser/include/nvfuser/compute_at.h +28 -0
  11. nvfuser/include/nvfuser/compute_at_map.h +394 -0
  12. nvfuser/include/nvfuser/contiguity.h +351 -0
  13. nvfuser/include/nvfuser/cuda_utils.h +50 -0
  14. nvfuser/include/nvfuser/debug.h +50 -0
  15. nvfuser/include/nvfuser/device_lower/analysis/bank_conflict.h +53 -0
  16. nvfuser/include/nvfuser/device_lower/analysis/circular_buffer.h +109 -0
  17. nvfuser/include/nvfuser/device_lower/analysis/device_version.h +65 -0
  18. nvfuser/include/nvfuser/device_lower/analysis/divisible_split.h +28 -0
  19. nvfuser/include/nvfuser/device_lower/analysis/fused_reduction.h +36 -0
  20. nvfuser/include/nvfuser/device_lower/analysis/index_compute.h +322 -0
  21. nvfuser/include/nvfuser/device_lower/analysis/predicate_elimination.h +71 -0
  22. nvfuser/include/nvfuser/device_lower/analysis/sync_information.h +47 -0
  23. nvfuser/include/nvfuser/device_lower/analysis/tensor_memory.h +65 -0
  24. nvfuser/include/nvfuser/device_lower/analysis/thread_predicate.h +158 -0
  25. nvfuser/include/nvfuser/device_lower/analysis/tma.h +93 -0
  26. nvfuser/include/nvfuser/device_lower/analysis/trivial_broadcast.h +75 -0
  27. nvfuser/include/nvfuser/device_lower/id_model_options.h +135 -0
  28. nvfuser/include/nvfuser/device_lower/lower2device.h +391 -0
  29. nvfuser/include/nvfuser/device_lower/pass/alias_memory.h +37 -0
  30. nvfuser/include/nvfuser/device_lower/pass/allocation.h +32 -0
  31. nvfuser/include/nvfuser/device_lower/pass/circular_buffer.h +191 -0
  32. nvfuser/include/nvfuser/device_lower/pass/expr_sort.h +17 -0
  33. nvfuser/include/nvfuser/device_lower/pass/fusion_simplifier.h +21 -0
  34. nvfuser/include/nvfuser/device_lower/pass/grid_serialization.h +26 -0
  35. nvfuser/include/nvfuser/device_lower/pass/index.h +200 -0
  36. nvfuser/include/nvfuser/device_lower/pass/inline_ptx.h +16 -0
  37. nvfuser/include/nvfuser/device_lower/pass/insert_syncs.h +39 -0
  38. nvfuser/include/nvfuser/device_lower/pass/instrument.h +24 -0
  39. nvfuser/include/nvfuser/device_lower/pass/loop_rotation.h +150 -0
  40. nvfuser/include/nvfuser/device_lower/pass/loops.h +68 -0
  41. nvfuser/include/nvfuser/device_lower/pass/magic_zero.h +86 -0
  42. nvfuser/include/nvfuser/device_lower/pass/misaligned_vectorization.h +118 -0
  43. nvfuser/include/nvfuser/device_lower/pass/predicate.h +23 -0
  44. nvfuser/include/nvfuser/device_lower/pass/replace_size.h +24 -0
  45. nvfuser/include/nvfuser/device_lower/pass/scalar_hoist.h +115 -0
  46. nvfuser/include/nvfuser/device_lower/pass/unroll.h +98 -0
  47. nvfuser/include/nvfuser/device_lower/pass/vectorize_welford.h +45 -0
  48. nvfuser/include/nvfuser/device_lower/pass/warp_reduce.h +23 -0
  49. nvfuser/include/nvfuser/device_lower/utils.h +382 -0
  50. nvfuser/include/nvfuser/device_lower/validation.h +74 -0
  51. nvfuser/include/nvfuser/disjoint_set.h +556 -0
  52. nvfuser/include/nvfuser/dispatch.h +334 -0
  53. nvfuser/include/nvfuser/driver_api.h +49 -0
  54. nvfuser/include/nvfuser/dynamic_transform.h +316 -0
  55. nvfuser/include/nvfuser/dynamic_type/C++20/type_traits +37 -0
  56. nvfuser/include/nvfuser/dynamic_type/dynamic_type.h +969 -0
  57. nvfuser/include/nvfuser/dynamic_type/error.h +24 -0
  58. nvfuser/include/nvfuser/dynamic_type/type_traits.h +703 -0
  59. nvfuser/include/nvfuser/evaluator_common.h +295 -0
  60. nvfuser/include/nvfuser/exceptions.h +283 -0
  61. nvfuser/include/nvfuser/expr_evaluator.h +125 -0
  62. nvfuser/include/nvfuser/expr_simplifier.h +218 -0
  63. nvfuser/include/nvfuser/flatbuffers/allocator.h +68 -0
  64. nvfuser/include/nvfuser/flatbuffers/array.h +253 -0
  65. nvfuser/include/nvfuser/flatbuffers/base.h +486 -0
  66. nvfuser/include/nvfuser/flatbuffers/buffer.h +154 -0
  67. nvfuser/include/nvfuser/flatbuffers/buffer_ref.h +53 -0
  68. nvfuser/include/nvfuser/flatbuffers/code_generator.h +80 -0
  69. nvfuser/include/nvfuser/flatbuffers/code_generators.h +234 -0
  70. nvfuser/include/nvfuser/flatbuffers/default_allocator.h +64 -0
  71. nvfuser/include/nvfuser/flatbuffers/detached_buffer.h +114 -0
  72. nvfuser/include/nvfuser/flatbuffers/flatbuffer_builder.h +1225 -0
  73. nvfuser/include/nvfuser/flatbuffers/flatbuffers.h +272 -0
  74. nvfuser/include/nvfuser/flatbuffers/flatc.h +130 -0
  75. nvfuser/include/nvfuser/flatbuffers/flex_flat_util.h +36 -0
  76. nvfuser/include/nvfuser/flatbuffers/flexbuffers.h +1889 -0
  77. nvfuser/include/nvfuser/flatbuffers/grpc.h +300 -0
  78. nvfuser/include/nvfuser/flatbuffers/hash.h +127 -0
  79. nvfuser/include/nvfuser/flatbuffers/idl.h +1359 -0
  80. nvfuser/include/nvfuser/flatbuffers/minireflect.h +420 -0
  81. nvfuser/include/nvfuser/flatbuffers/reflection.h +522 -0
  82. nvfuser/include/nvfuser/flatbuffers/reflection_generated.h +1471 -0
  83. nvfuser/include/nvfuser/flatbuffers/registry.h +128 -0
  84. nvfuser/include/nvfuser/flatbuffers/stl_emulation.h +513 -0
  85. nvfuser/include/nvfuser/flatbuffers/string.h +64 -0
  86. nvfuser/include/nvfuser/flatbuffers/struct.h +53 -0
  87. nvfuser/include/nvfuser/flatbuffers/table.h +168 -0
  88. nvfuser/include/nvfuser/flatbuffers/util.h +731 -0
  89. nvfuser/include/nvfuser/flatbuffers/vector.h +393 -0
  90. nvfuser/include/nvfuser/flatbuffers/vector_downward.h +273 -0
  91. nvfuser/include/nvfuser/flatbuffers/verifier.h +317 -0
  92. nvfuser/include/nvfuser/fusion.h +511 -0
  93. nvfuser/include/nvfuser/fusion_guard.h +37 -0
  94. nvfuser/include/nvfuser/fusion_profiler.h +311 -0
  95. nvfuser/include/nvfuser/fusion_segmenter.h +751 -0
  96. nvfuser/include/nvfuser/global_allocator.h +27 -0
  97. nvfuser/include/nvfuser/grouped_reduction.h +47 -0
  98. nvfuser/include/nvfuser/host_ir/container.h +60 -0
  99. nvfuser/include/nvfuser/host_ir/executor.h +152 -0
  100. nvfuser/include/nvfuser/host_ir/host_ir.h +320 -0
  101. nvfuser/include/nvfuser/host_ir/lower.h +35 -0
  102. nvfuser/include/nvfuser/id_model/circular_buffer_indexing.h +56 -0
  103. nvfuser/include/nvfuser/id_model/contiguity.h +166 -0
  104. nvfuser/include/nvfuser/id_model/id_model.h +359 -0
  105. nvfuser/include/nvfuser/id_model/id_model_index_compute.h +81 -0
  106. nvfuser/include/nvfuser/id_model/indexing.h +208 -0
  107. nvfuser/include/nvfuser/id_model/indexing_traversal.h +72 -0
  108. nvfuser/include/nvfuser/id_model/indexing_utils.h +62 -0
  109. nvfuser/include/nvfuser/id_model/loop_promotion.h +180 -0
  110. nvfuser/include/nvfuser/id_model/predicate_indexing.h +104 -0
  111. nvfuser/include/nvfuser/id_model/schedule.h +54 -0
  112. nvfuser/include/nvfuser/id_model/to_string.h +87 -0
  113. nvfuser/include/nvfuser/id_model/transform_replay.h +58 -0
  114. nvfuser/include/nvfuser/id_model/utils.h +176 -0
  115. nvfuser/include/nvfuser/id_model/validation_utils.h +55 -0
  116. nvfuser/include/nvfuser/index_compute.h +651 -0
  117. nvfuser/include/nvfuser/instrumentation.h +107 -0
  118. nvfuser/include/nvfuser/ir/all_nodes.h +14 -0
  119. nvfuser/include/nvfuser/ir/base_nodes.h +687 -0
  120. nvfuser/include/nvfuser/ir/builder.h +215 -0
  121. nvfuser/include/nvfuser/ir/builder_passkey.h +29 -0
  122. nvfuser/include/nvfuser/ir/cloner.h +185 -0
  123. nvfuser/include/nvfuser/ir/container.h +226 -0
  124. nvfuser/include/nvfuser/ir/graphviz.h +119 -0
  125. nvfuser/include/nvfuser/ir/interface_nodes.h +957 -0
  126. nvfuser/include/nvfuser/ir/internal_base_nodes.h +744 -0
  127. nvfuser/include/nvfuser/ir/internal_nodes.h +2792 -0
  128. nvfuser/include/nvfuser/ir/iostream.h +98 -0
  129. nvfuser/include/nvfuser/ir/printer.h +57 -0
  130. nvfuser/include/nvfuser/ir/utils.h +801 -0
  131. nvfuser/include/nvfuser/iter_visitor.h +661 -0
  132. nvfuser/include/nvfuser/kernel.h +299 -0
  133. nvfuser/include/nvfuser/kernel_db/kernel_db.h +109 -0
  134. nvfuser/include/nvfuser/kernel_db/utils.h +37 -0
  135. nvfuser/include/nvfuser/kernel_ir.h +1457 -0
  136. nvfuser/include/nvfuser/kernel_ir_dispatch.h +147 -0
  137. nvfuser/include/nvfuser/linked_hash_map.h +97 -0
  138. nvfuser/include/nvfuser/logical_domain_map.h +577 -0
  139. nvfuser/include/nvfuser/macros.h +23 -0
  140. nvfuser/include/nvfuser/mma_type.h +257 -0
  141. nvfuser/include/nvfuser/multidevice/c10d_mock.h +175 -0
  142. nvfuser/include/nvfuser/multidevice/communication.h +232 -0
  143. nvfuser/include/nvfuser/multidevice/communicator.h +179 -0
  144. nvfuser/include/nvfuser/multidevice/device_mesh.h +95 -0
  145. nvfuser/include/nvfuser/multidevice/executor.h +107 -0
  146. nvfuser/include/nvfuser/multidevice/multidevice.h +18 -0
  147. nvfuser/include/nvfuser/multidevice/utils.h +187 -0
  148. nvfuser/include/nvfuser/non_divisible_split.h +86 -0
  149. nvfuser/include/nvfuser/opaque_type.h +129 -0
  150. nvfuser/include/nvfuser/ops/alias.h +192 -0
  151. nvfuser/include/nvfuser/ops/all_ops.h +13 -0
  152. nvfuser/include/nvfuser/ops/arith.h +712 -0
  153. nvfuser/include/nvfuser/ops/composite.h +130 -0
  154. nvfuser/include/nvfuser/ops/indexing.h +55 -0
  155. nvfuser/include/nvfuser/ops/normalization.h +263 -0
  156. nvfuser/include/nvfuser/ops/utils.h +127 -0
  157. nvfuser/include/nvfuser/options.h +313 -0
  158. nvfuser/include/nvfuser/parallel_dimension_map.h +95 -0
  159. nvfuser/include/nvfuser/parallel_type_bitmap.h +365 -0
  160. nvfuser/include/nvfuser/polymorphic_value.h +432 -0
  161. nvfuser/include/nvfuser/predicate_compute.h +213 -0
  162. nvfuser/include/nvfuser/python_frontend/distributed_tensor.h +50 -0
  163. nvfuser/include/nvfuser/python_frontend/fusion_cache.h +298 -0
  164. nvfuser/include/nvfuser/python_frontend/fusion_definition.h +372 -0
  165. nvfuser/include/nvfuser/python_frontend/fusion_record.h +3124 -0
  166. nvfuser/include/nvfuser/python_frontend/fusion_state.h +143 -0
  167. nvfuser/include/nvfuser/python_frontend/python_bindings.h +27 -0
  168. nvfuser/include/nvfuser/python_frontend/segmentation.h +246 -0
  169. nvfuser/include/nvfuser/python_frontend/translation.h +20 -0
  170. nvfuser/include/nvfuser/python_frontend/translation_utils.h +308 -0
  171. nvfuser/include/nvfuser/scheduler/all_schedulers.h +17 -0
  172. nvfuser/include/nvfuser/scheduler/ampere_multi_matmul.h +206 -0
  173. nvfuser/include/nvfuser/scheduler/cache_policy_refiner.h +19 -0
  174. nvfuser/include/nvfuser/scheduler/compile_time_info.h +322 -0
  175. nvfuser/include/nvfuser/scheduler/debug_utils.h +68 -0
  176. nvfuser/include/nvfuser/scheduler/expr_eval_sched.h +45 -0
  177. nvfuser/include/nvfuser/scheduler/heuristic.h +113 -0
  178. nvfuser/include/nvfuser/scheduler/hopper_multi_matmul.h +204 -0
  179. nvfuser/include/nvfuser/scheduler/mark_aliases.h +19 -0
  180. nvfuser/include/nvfuser/scheduler/matmul.h +40 -0
  181. nvfuser/include/nvfuser/scheduler/matmul_heuristic.h +293 -0
  182. nvfuser/include/nvfuser/scheduler/matmul_heuristic_plugin.h +65 -0
  183. nvfuser/include/nvfuser/scheduler/matmul_heuristic_plugin_api.h +99 -0
  184. nvfuser/include/nvfuser/scheduler/matmul_utils.h +54 -0
  185. nvfuser/include/nvfuser/scheduler/mma_utils.h +500 -0
  186. nvfuser/include/nvfuser/scheduler/multi_matmul.h +74 -0
  187. nvfuser/include/nvfuser/scheduler/no_op.h +48 -0
  188. nvfuser/include/nvfuser/scheduler/normalization_inner.h +49 -0
  189. nvfuser/include/nvfuser/scheduler/normalization_inner_outer.h +51 -0
  190. nvfuser/include/nvfuser/scheduler/normalization_outer.h +48 -0
  191. nvfuser/include/nvfuser/scheduler/normalization_utils.h +379 -0
  192. nvfuser/include/nvfuser/scheduler/pointwise.h +183 -0
  193. nvfuser/include/nvfuser/scheduler/pointwise_heuristic.h +118 -0
  194. nvfuser/include/nvfuser/scheduler/pointwise_utils.h +24 -0
  195. nvfuser/include/nvfuser/scheduler/reduction.h +43 -0
  196. nvfuser/include/nvfuser/scheduler/reduction_heuristic.h +339 -0
  197. nvfuser/include/nvfuser/scheduler/reduction_utils.h +159 -0
  198. nvfuser/include/nvfuser/scheduler/registry.h +97 -0
  199. nvfuser/include/nvfuser/scheduler/registry_utils.h +111 -0
  200. nvfuser/include/nvfuser/scheduler/resize.h +41 -0
  201. nvfuser/include/nvfuser/scheduler/resize_heuristic.h +67 -0
  202. nvfuser/include/nvfuser/scheduler/runtime_info.h +166 -0
  203. nvfuser/include/nvfuser/scheduler/scheduler_types.h +80 -0
  204. nvfuser/include/nvfuser/scheduler/transpose.h +114 -0
  205. nvfuser/include/nvfuser/scheduler/transpose_heuristic.h +164 -0
  206. nvfuser/include/nvfuser/scheduler/utils.h +771 -0
  207. nvfuser/include/nvfuser/scheduler/vectorize_helper.h +349 -0
  208. nvfuser/include/nvfuser/serde/factory.h +55 -0
  209. nvfuser/include/nvfuser/serde/fusion_cache_generated.h +4319 -0
  210. nvfuser/include/nvfuser/serde/fusion_record.h +124 -0
  211. nvfuser/include/nvfuser/serde/polymorphic_value.h +52 -0
  212. nvfuser/include/nvfuser/serde/utils.h +34 -0
  213. nvfuser/include/nvfuser/struct.inl +127 -0
  214. nvfuser/include/nvfuser/swizzle.h +54 -0
  215. nvfuser/include/nvfuser/sys_utils.h +40 -0
  216. nvfuser/include/nvfuser/tensor_metadata.h +118 -0
  217. nvfuser/include/nvfuser/tma.h +124 -0
  218. nvfuser/include/nvfuser/transform_iter.h +522 -0
  219. nvfuser/include/nvfuser/transform_replay.h +297 -0
  220. nvfuser/include/nvfuser/transform_rfactor.h +33 -0
  221. nvfuser/include/nvfuser/transform_view.h +136 -0
  222. nvfuser/include/nvfuser/type.h +1125 -0
  223. nvfuser/include/nvfuser/type_promotion.h +61 -0
  224. nvfuser/include/nvfuser/utils.h +619 -0
  225. nvfuser/include/nvfuser/val_graph.h +446 -0
  226. nvfuser/include/nvfuser/val_graph_visitor.h +259 -0
  227. nvfuser/include/nvfuser/validator_utils.h +92 -0
  228. nvfuser/include/nvfuser/vectorization_info.h +31 -0
  229. nvfuser/include/nvfuser/visibility.h +21 -0
  230. nvfuser/lib/libnvfuser_codegen.so +0 -0
  231. nvfuser/nvfuser_version.py +69 -0
  232. nvfuser/pytorch_utils.py +184 -0
  233. nvfuser/share/cmake/nvfuser/NvfuserConfig-release.cmake +20 -0
  234. nvfuser/share/cmake/nvfuser/NvfuserConfig.cmake +106 -0
  235. nvfuser/utils.py +18 -0
  236. nvfuser/version.py +1 -0
  237. nvfuser_cu121_torch25-0.2.25.dev20250201.dist-info/LICENSE +976 -0
  238. nvfuser_cu121_torch25-0.2.25.dev20250201.dist-info/METADATA +16 -0
  239. nvfuser_cu121_torch25-0.2.25.dev20250201.dist-info/RECORD +242 -0
  240. nvfuser_cu121_torch25-0.2.25.dev20250201.dist-info/WHEEL +5 -0
  241. nvfuser_cu121_torch25-0.2.25.dev20250201.dist-info/top_level.txt +1 -0
  242. nvfuser_cu121_torch25.libs/libnvToolsExt-847d78f2.so.1.0.0 +0 -0
@@ -0,0 +1,1225 @@
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 <functional>
22
+ #include <initializer_list>
23
+
24
+ #include "flatbuffers/allocator.h"
25
+ #include "flatbuffers/array.h"
26
+ #include "flatbuffers/base.h"
27
+ #include "flatbuffers/buffer_ref.h"
28
+ #include "flatbuffers/default_allocator.h"
29
+ #include "flatbuffers/detached_buffer.h"
30
+ #include "flatbuffers/stl_emulation.h"
31
+ #include "flatbuffers/string.h"
32
+ #include "flatbuffers/struct.h"
33
+ #include "flatbuffers/table.h"
34
+ #include "flatbuffers/vector.h"
35
+ #include "flatbuffers/vector_downward.h"
36
+ #include "flatbuffers/verifier.h"
37
+
38
+ namespace flatbuffers {
39
+
40
+ // Converts a Field ID to a virtual table offset.
41
+ inline voffset_t FieldIndexToOffset(voffset_t field_id) {
42
+ // Should correspond to what EndTable() below builds up.
43
+ const int fixed_fields = 2; // Vtable size and Object Size.
44
+ return static_cast<voffset_t>((field_id + fixed_fields) * sizeof(voffset_t));
45
+ }
46
+
47
+ template<typename T, typename Alloc = std::allocator<T>>
48
+ const T *data(const std::vector<T, Alloc> &v) {
49
+ // Eventually the returned pointer gets passed down to memcpy, so
50
+ // we need it to be non-null to avoid undefined behavior.
51
+ static uint8_t t;
52
+ return v.empty() ? reinterpret_cast<const T *>(&t) : &v.front();
53
+ }
54
+ template<typename T, typename Alloc = std::allocator<T>>
55
+ T *data(std::vector<T, Alloc> &v) {
56
+ // Eventually the returned pointer gets passed down to memcpy, so
57
+ // we need it to be non-null to avoid undefined behavior.
58
+ static uint8_t t;
59
+ return v.empty() ? reinterpret_cast<T *>(&t) : &v.front();
60
+ }
61
+
62
+ /// @addtogroup flatbuffers_cpp_api
63
+ /// @{
64
+ /// @class FlatBufferBuilder
65
+ /// @brief Helper class to hold data needed in creation of a FlatBuffer.
66
+ /// To serialize data, you typically call one of the `Create*()` functions in
67
+ /// the generated code, which in turn call a sequence of `StartTable`/
68
+ /// `PushElement`/`AddElement`/`EndTable`, or the builtin `CreateString`/
69
+ /// `CreateVector` functions. Do this is depth-first order to build up a tree to
70
+ /// the root. `Finish()` wraps up the buffer ready for transport.
71
+ class FlatBufferBuilder {
72
+ public:
73
+ /// @brief Default constructor for FlatBufferBuilder.
74
+ /// @param[in] initial_size The initial size of the buffer, in bytes. Defaults
75
+ /// to `1024`.
76
+ /// @param[in] allocator An `Allocator` to use. If null will use
77
+ /// `DefaultAllocator`.
78
+ /// @param[in] own_allocator Whether the builder/vector should own the
79
+ /// allocator. Defaults to / `false`.
80
+ /// @param[in] buffer_minalign Force the buffer to be aligned to the given
81
+ /// minimum alignment upon reallocation. Only needed if you intend to store
82
+ /// types with custom alignment AND you wish to read the buffer in-place
83
+ /// directly after creation.
84
+ explicit FlatBufferBuilder(
85
+ size_t initial_size = 1024, Allocator *allocator = nullptr,
86
+ bool own_allocator = false,
87
+ size_t buffer_minalign = AlignOf<largest_scalar_t>())
88
+ : buf_(initial_size, allocator, own_allocator, buffer_minalign),
89
+ num_field_loc(0),
90
+ max_voffset_(0),
91
+ nested(false),
92
+ finished(false),
93
+ minalign_(1),
94
+ force_defaults_(false),
95
+ dedup_vtables_(true),
96
+ string_pool(nullptr) {
97
+ EndianCheck();
98
+ }
99
+
100
+ /// @brief Move constructor for FlatBufferBuilder.
101
+ FlatBufferBuilder(FlatBufferBuilder &&other) noexcept
102
+ : buf_(1024, nullptr, false, AlignOf<largest_scalar_t>()),
103
+ num_field_loc(0),
104
+ max_voffset_(0),
105
+ nested(false),
106
+ finished(false),
107
+ minalign_(1),
108
+ force_defaults_(false),
109
+ dedup_vtables_(true),
110
+ string_pool(nullptr) {
111
+ EndianCheck();
112
+ // Default construct and swap idiom.
113
+ // Lack of delegating constructors in vs2010 makes it more verbose than
114
+ // needed.
115
+ Swap(other);
116
+ }
117
+
118
+ /// @brief Move assignment operator for FlatBufferBuilder.
119
+ FlatBufferBuilder &operator=(FlatBufferBuilder &&other) noexcept {
120
+ // Move construct a temporary and swap idiom
121
+ FlatBufferBuilder temp(std::move(other));
122
+ Swap(temp);
123
+ return *this;
124
+ }
125
+
126
+ void Swap(FlatBufferBuilder &other) {
127
+ using std::swap;
128
+ buf_.swap(other.buf_);
129
+ swap(num_field_loc, other.num_field_loc);
130
+ swap(max_voffset_, other.max_voffset_);
131
+ swap(nested, other.nested);
132
+ swap(finished, other.finished);
133
+ swap(minalign_, other.minalign_);
134
+ swap(force_defaults_, other.force_defaults_);
135
+ swap(dedup_vtables_, other.dedup_vtables_);
136
+ swap(string_pool, other.string_pool);
137
+ }
138
+
139
+ ~FlatBufferBuilder() {
140
+ if (string_pool) delete string_pool;
141
+ }
142
+
143
+ void Reset() {
144
+ Clear(); // clear builder state
145
+ buf_.reset(); // deallocate buffer
146
+ }
147
+
148
+ /// @brief Reset all the state in this FlatBufferBuilder so it can be reused
149
+ /// to construct another buffer.
150
+ void Clear() {
151
+ ClearOffsets();
152
+ buf_.clear();
153
+ nested = false;
154
+ finished = false;
155
+ minalign_ = 1;
156
+ if (string_pool) string_pool->clear();
157
+ }
158
+
159
+ /// @brief The current size of the serialized buffer, counting from the end.
160
+ /// @return Returns an `uoffset_t` with the current size of the buffer.
161
+ uoffset_t GetSize() const { return buf_.size(); }
162
+
163
+ /// @brief Get the serialized buffer (after you call `Finish()`).
164
+ /// @return Returns an `uint8_t` pointer to the FlatBuffer data inside the
165
+ /// buffer.
166
+ uint8_t *GetBufferPointer() const {
167
+ Finished();
168
+ return buf_.data();
169
+ }
170
+
171
+ /// @brief Get the serialized buffer (after you call `Finish()`) as a span.
172
+ /// @return Returns a constructed flatbuffers::span that is a view over the
173
+ /// FlatBuffer data inside the buffer.
174
+ flatbuffers::span<uint8_t> GetBufferSpan() const {
175
+ Finished();
176
+ return flatbuffers::span<uint8_t>(buf_.data(), buf_.size());
177
+ }
178
+
179
+ /// @brief Get a pointer to an unfinished buffer.
180
+ /// @return Returns a `uint8_t` pointer to the unfinished buffer.
181
+ uint8_t *GetCurrentBufferPointer() const { return buf_.data(); }
182
+
183
+ /// @brief Get the released pointer to the serialized buffer.
184
+ /// @warning Do NOT attempt to use this FlatBufferBuilder afterwards!
185
+ /// @return A `FlatBuffer` that owns the buffer and its allocator and
186
+ /// behaves similar to a `unique_ptr` with a deleter.
187
+ FLATBUFFERS_ATTRIBUTE([[deprecated("use Release() instead")]])
188
+ DetachedBuffer ReleaseBufferPointer() {
189
+ Finished();
190
+ return buf_.release();
191
+ }
192
+
193
+ /// @brief Get the released DetachedBuffer.
194
+ /// @return A `DetachedBuffer` that owns the buffer and its allocator.
195
+ DetachedBuffer Release() {
196
+ Finished();
197
+ return buf_.release();
198
+ }
199
+
200
+ /// @brief Get the released pointer to the serialized buffer.
201
+ /// @param size The size of the memory block containing
202
+ /// the serialized `FlatBuffer`.
203
+ /// @param offset The offset from the released pointer where the finished
204
+ /// `FlatBuffer` starts.
205
+ /// @return A raw pointer to the start of the memory block containing
206
+ /// the serialized `FlatBuffer`.
207
+ /// @remark If the allocator is owned, it gets deleted when the destructor is
208
+ /// called..
209
+ uint8_t *ReleaseRaw(size_t &size, size_t &offset) {
210
+ Finished();
211
+ return buf_.release_raw(size, offset);
212
+ }
213
+
214
+ /// @brief get the minimum alignment this buffer needs to be accessed
215
+ /// properly. This is only known once all elements have been written (after
216
+ /// you call Finish()). You can use this information if you need to embed
217
+ /// a FlatBuffer in some other buffer, such that you can later read it
218
+ /// without first having to copy it into its own buffer.
219
+ size_t GetBufferMinAlignment() const {
220
+ Finished();
221
+ return minalign_;
222
+ }
223
+
224
+ /// @cond FLATBUFFERS_INTERNAL
225
+ void Finished() const {
226
+ // If you get this assert, you're attempting to get access a buffer
227
+ // which hasn't been finished yet. Be sure to call
228
+ // FlatBufferBuilder::Finish with your root table.
229
+ // If you really need to access an unfinished buffer, call
230
+ // GetCurrentBufferPointer instead.
231
+ FLATBUFFERS_ASSERT(finished);
232
+ }
233
+ /// @endcond
234
+
235
+ /// @brief In order to save space, fields that are set to their default value
236
+ /// don't get serialized into the buffer.
237
+ /// @param[in] fd When set to `true`, always serializes default values that
238
+ /// are set. Optional fields which are not set explicitly, will still not be
239
+ /// serialized.
240
+ void ForceDefaults(bool fd) { force_defaults_ = fd; }
241
+
242
+ /// @brief By default vtables are deduped in order to save space.
243
+ /// @param[in] dedup When set to `true`, dedup vtables.
244
+ void DedupVtables(bool dedup) { dedup_vtables_ = dedup; }
245
+
246
+ /// @cond FLATBUFFERS_INTERNAL
247
+ void Pad(size_t num_bytes) { buf_.fill(num_bytes); }
248
+
249
+ void TrackMinAlign(size_t elem_size) {
250
+ if (elem_size > minalign_) minalign_ = elem_size;
251
+ }
252
+
253
+ void Align(size_t elem_size) {
254
+ TrackMinAlign(elem_size);
255
+ buf_.fill(PaddingBytes(buf_.size(), elem_size));
256
+ }
257
+
258
+ void PushFlatBuffer(const uint8_t *bytes, size_t size) {
259
+ PushBytes(bytes, size);
260
+ finished = true;
261
+ }
262
+
263
+ void PushBytes(const uint8_t *bytes, size_t size) { buf_.push(bytes, size); }
264
+
265
+ void PopBytes(size_t amount) { buf_.pop(amount); }
266
+
267
+ template<typename T> void AssertScalarT() {
268
+ // The code assumes power of 2 sizes and endian-swap-ability.
269
+ static_assert(flatbuffers::is_scalar<T>::value, "T must be a scalar type");
270
+ }
271
+
272
+ // Write a single aligned scalar to the buffer
273
+ template<typename T> uoffset_t PushElement(T element) {
274
+ AssertScalarT<T>();
275
+ Align(sizeof(T));
276
+ buf_.push_small(EndianScalar(element));
277
+ return GetSize();
278
+ }
279
+
280
+ template<typename T> uoffset_t PushElement(Offset<T> off) {
281
+ // Special case for offsets: see ReferTo below.
282
+ return PushElement(ReferTo(off.o));
283
+ }
284
+
285
+ // When writing fields, we track where they are, so we can create correct
286
+ // vtables later.
287
+ void TrackField(voffset_t field, uoffset_t off) {
288
+ FieldLoc fl = { off, field };
289
+ buf_.scratch_push_small(fl);
290
+ num_field_loc++;
291
+ if (field > max_voffset_) { max_voffset_ = field; }
292
+ }
293
+
294
+ // Like PushElement, but additionally tracks the field this represents.
295
+ template<typename T> void AddElement(voffset_t field, T e, T def) {
296
+ // We don't serialize values equal to the default.
297
+ if (IsTheSameAs(e, def) && !force_defaults_) return;
298
+ TrackField(field, PushElement(e));
299
+ }
300
+
301
+ template<typename T> void AddElement(voffset_t field, T e) {
302
+ TrackField(field, PushElement(e));
303
+ }
304
+
305
+ template<typename T> void AddOffset(voffset_t field, Offset<T> off) {
306
+ if (off.IsNull()) return; // Don't store.
307
+ AddElement(field, ReferTo(off.o), static_cast<uoffset_t>(0));
308
+ }
309
+
310
+ template<typename T> void AddStruct(voffset_t field, const T *structptr) {
311
+ if (!structptr) return; // Default, don't store.
312
+ Align(AlignOf<T>());
313
+ buf_.push_small(*structptr);
314
+ TrackField(field, GetSize());
315
+ }
316
+
317
+ void AddStructOffset(voffset_t field, uoffset_t off) {
318
+ TrackField(field, off);
319
+ }
320
+
321
+ // Offsets initially are relative to the end of the buffer (downwards).
322
+ // This function converts them to be relative to the current location
323
+ // in the buffer (when stored here), pointing upwards.
324
+ uoffset_t ReferTo(uoffset_t off) {
325
+ // Align to ensure GetSize() below is correct.
326
+ Align(sizeof(uoffset_t));
327
+ // Offset must refer to something already in buffer.
328
+ const uoffset_t size = GetSize();
329
+ FLATBUFFERS_ASSERT(off && off <= size);
330
+ return size - off + static_cast<uoffset_t>(sizeof(uoffset_t));
331
+ }
332
+
333
+ void NotNested() {
334
+ // If you hit this, you're trying to construct a Table/Vector/String
335
+ // during the construction of its parent table (between the MyTableBuilder
336
+ // and table.Finish().
337
+ // Move the creation of these sub-objects to above the MyTableBuilder to
338
+ // not get this assert.
339
+ // Ignoring this assert may appear to work in simple cases, but the reason
340
+ // it is here is that storing objects in-line may cause vtable offsets
341
+ // to not fit anymore. It also leads to vtable duplication.
342
+ FLATBUFFERS_ASSERT(!nested);
343
+ // If you hit this, fields were added outside the scope of a table.
344
+ FLATBUFFERS_ASSERT(!num_field_loc);
345
+ }
346
+
347
+ // From generated code (or from the parser), we call StartTable/EndTable
348
+ // with a sequence of AddElement calls in between.
349
+ uoffset_t StartTable() {
350
+ NotNested();
351
+ nested = true;
352
+ return GetSize();
353
+ }
354
+
355
+ // This finishes one serialized object by generating the vtable if it's a
356
+ // table, comparing it against existing vtables, and writing the
357
+ // resulting vtable offset.
358
+ uoffset_t EndTable(uoffset_t start) {
359
+ // If you get this assert, a corresponding StartTable wasn't called.
360
+ FLATBUFFERS_ASSERT(nested);
361
+ // Write the vtable offset, which is the start of any Table.
362
+ // We fill its value later.
363
+ auto vtableoffsetloc = PushElement<soffset_t>(0);
364
+ // Write a vtable, which consists entirely of voffset_t elements.
365
+ // It starts with the number of offsets, followed by a type id, followed
366
+ // by the offsets themselves. In reverse:
367
+ // Include space for the last offset and ensure empty tables have a
368
+ // minimum size.
369
+ max_voffset_ =
370
+ (std::max)(static_cast<voffset_t>(max_voffset_ + sizeof(voffset_t)),
371
+ FieldIndexToOffset(0));
372
+ buf_.fill_big(max_voffset_);
373
+ auto table_object_size = vtableoffsetloc - start;
374
+ // Vtable use 16bit offsets.
375
+ FLATBUFFERS_ASSERT(table_object_size < 0x10000);
376
+ WriteScalar<voffset_t>(buf_.data() + sizeof(voffset_t),
377
+ static_cast<voffset_t>(table_object_size));
378
+ WriteScalar<voffset_t>(buf_.data(), max_voffset_);
379
+ // Write the offsets into the table
380
+ for (auto it = buf_.scratch_end() - num_field_loc * sizeof(FieldLoc);
381
+ it < buf_.scratch_end(); it += sizeof(FieldLoc)) {
382
+ auto field_location = reinterpret_cast<FieldLoc *>(it);
383
+ auto pos = static_cast<voffset_t>(vtableoffsetloc - field_location->off);
384
+ // If this asserts, it means you've set a field twice.
385
+ FLATBUFFERS_ASSERT(
386
+ !ReadScalar<voffset_t>(buf_.data() + field_location->id));
387
+ WriteScalar<voffset_t>(buf_.data() + field_location->id, pos);
388
+ }
389
+ ClearOffsets();
390
+ auto vt1 = reinterpret_cast<voffset_t *>(buf_.data());
391
+ auto vt1_size = ReadScalar<voffset_t>(vt1);
392
+ auto vt_use = GetSize();
393
+ // See if we already have generated a vtable with this exact same
394
+ // layout before. If so, make it point to the old one, remove this one.
395
+ if (dedup_vtables_) {
396
+ for (auto it = buf_.scratch_data(); it < buf_.scratch_end();
397
+ it += sizeof(uoffset_t)) {
398
+ auto vt_offset_ptr = reinterpret_cast<uoffset_t *>(it);
399
+ auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(*vt_offset_ptr));
400
+ auto vt2_size = ReadScalar<voffset_t>(vt2);
401
+ if (vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size)) continue;
402
+ vt_use = *vt_offset_ptr;
403
+ buf_.pop(GetSize() - vtableoffsetloc);
404
+ break;
405
+ }
406
+ }
407
+ // If this is a new vtable, remember it.
408
+ if (vt_use == GetSize()) { buf_.scratch_push_small(vt_use); }
409
+ // Fill the vtable offset we created above.
410
+ // The offset points from the beginning of the object to where the
411
+ // vtable is stored.
412
+ // Offsets default direction is downward in memory for future format
413
+ // flexibility (storing all vtables at the start of the file).
414
+ WriteScalar(buf_.data_at(vtableoffsetloc),
415
+ static_cast<soffset_t>(vt_use) -
416
+ static_cast<soffset_t>(vtableoffsetloc));
417
+
418
+ nested = false;
419
+ return vtableoffsetloc;
420
+ }
421
+
422
+ FLATBUFFERS_ATTRIBUTE([[deprecated("call the version above instead")]])
423
+ uoffset_t EndTable(uoffset_t start, voffset_t /*numfields*/) {
424
+ return EndTable(start);
425
+ }
426
+
427
+ // This checks a required field has been set in a given table that has
428
+ // just been constructed.
429
+ template<typename T> void Required(Offset<T> table, voffset_t field);
430
+
431
+ uoffset_t StartStruct(size_t alignment) {
432
+ Align(alignment);
433
+ return GetSize();
434
+ }
435
+
436
+ uoffset_t EndStruct() { return GetSize(); }
437
+
438
+ void ClearOffsets() {
439
+ buf_.scratch_pop(num_field_loc * sizeof(FieldLoc));
440
+ num_field_loc = 0;
441
+ max_voffset_ = 0;
442
+ }
443
+
444
+ // Aligns such that when "len" bytes are written, an object can be written
445
+ // after it with "alignment" without padding.
446
+ void PreAlign(size_t len, size_t alignment) {
447
+ if (len == 0) return;
448
+ TrackMinAlign(alignment);
449
+ buf_.fill(PaddingBytes(GetSize() + len, alignment));
450
+ }
451
+ template<typename T> void PreAlign(size_t len) {
452
+ AssertScalarT<T>();
453
+ PreAlign(len, AlignOf<T>());
454
+ }
455
+ /// @endcond
456
+
457
+ /// @brief Store a string in the buffer, which can contain any binary data.
458
+ /// @param[in] str A const char pointer to the data to be stored as a string.
459
+ /// @param[in] len The number of bytes that should be stored from `str`.
460
+ /// @return Returns the offset in the buffer where the string starts.
461
+ Offset<String> CreateString(const char *str, size_t len) {
462
+ NotNested();
463
+ PreAlign<uoffset_t>(len + 1); // Always 0-terminated.
464
+ buf_.fill(1);
465
+ PushBytes(reinterpret_cast<const uint8_t *>(str), len);
466
+ PushElement(static_cast<uoffset_t>(len));
467
+ return Offset<String>(GetSize());
468
+ }
469
+
470
+ /// @brief Store a string in the buffer, which is null-terminated.
471
+ /// @param[in] str A const char pointer to a C-string to add to the buffer.
472
+ /// @return Returns the offset in the buffer where the string starts.
473
+ Offset<String> CreateString(const char *str) {
474
+ return CreateString(str, strlen(str));
475
+ }
476
+
477
+ /// @brief Store a string in the buffer, which is null-terminated.
478
+ /// @param[in] str A char pointer to a C-string to add to the buffer.
479
+ /// @return Returns the offset in the buffer where the string starts.
480
+ Offset<String> CreateString(char *str) {
481
+ return CreateString(str, strlen(str));
482
+ }
483
+
484
+ /// @brief Store a string in the buffer, which can contain any binary data.
485
+ /// @param[in] str A const reference to a std::string to store in the buffer.
486
+ /// @return Returns the offset in the buffer where the string starts.
487
+ Offset<String> CreateString(const std::string &str) {
488
+ return CreateString(str.c_str(), str.length());
489
+ }
490
+
491
+ // clang-format off
492
+ #ifdef FLATBUFFERS_HAS_STRING_VIEW
493
+ /// @brief Store a string in the buffer, which can contain any binary data.
494
+ /// @param[in] str A const string_view to copy in to the buffer.
495
+ /// @return Returns the offset in the buffer where the string starts.
496
+ Offset<String> CreateString(flatbuffers::string_view str) {
497
+ return CreateString(str.data(), str.size());
498
+ }
499
+ #endif // FLATBUFFERS_HAS_STRING_VIEW
500
+ // clang-format on
501
+
502
+ /// @brief Store a string in the buffer, which can contain any binary data.
503
+ /// @param[in] str A const pointer to a `String` struct to add to the buffer.
504
+ /// @return Returns the offset in the buffer where the string starts
505
+ Offset<String> CreateString(const String *str) {
506
+ return str ? CreateString(str->c_str(), str->size()) : 0;
507
+ }
508
+
509
+ /// @brief Store a string in the buffer, which can contain any binary data.
510
+ /// @param[in] str A const reference to a std::string like type with support
511
+ /// of T::c_str() and T::length() to store in the buffer.
512
+ /// @return Returns the offset in the buffer where the string starts.
513
+ template<typename T> Offset<String> CreateString(const T &str) {
514
+ return CreateString(str.c_str(), str.length());
515
+ }
516
+
517
+ /// @brief Store a string in the buffer, which can contain any binary data.
518
+ /// If a string with this exact contents has already been serialized before,
519
+ /// instead simply returns the offset of the existing string. This uses a map
520
+ /// stored on the heap, but only stores the numerical offsets.
521
+ /// @param[in] str A const char pointer to the data to be stored as a string.
522
+ /// @param[in] len The number of bytes that should be stored from `str`.
523
+ /// @return Returns the offset in the buffer where the string starts.
524
+ Offset<String> CreateSharedString(const char *str, size_t len) {
525
+ FLATBUFFERS_ASSERT(FLATBUFFERS_GENERAL_HEAP_ALLOC_OK);
526
+ if (!string_pool)
527
+ string_pool = new StringOffsetMap(StringOffsetCompare(buf_));
528
+ auto size_before_string = buf_.size();
529
+ // Must first serialize the string, since the set is all offsets into
530
+ // buffer.
531
+ auto off = CreateString(str, len);
532
+ auto it = string_pool->find(off);
533
+ // If it exists we reuse existing serialized data!
534
+ if (it != string_pool->end()) {
535
+ // We can remove the string we serialized.
536
+ buf_.pop(buf_.size() - size_before_string);
537
+ return *it;
538
+ }
539
+ // Record this string for future use.
540
+ string_pool->insert(off);
541
+ return off;
542
+ }
543
+
544
+ #ifdef FLATBUFFERS_HAS_STRING_VIEW
545
+ /// @brief Store a string in the buffer, which can contain any binary data.
546
+ /// If a string with this exact contents has already been serialized before,
547
+ /// instead simply returns the offset of the existing string. This uses a map
548
+ /// stored on the heap, but only stores the numerical offsets.
549
+ /// @param[in] str A const std::string_view to store in the buffer.
550
+ /// @return Returns the offset in the buffer where the string starts
551
+ Offset<String> CreateSharedString(const flatbuffers::string_view str) {
552
+ return CreateSharedString(str.data(), str.size());
553
+ }
554
+ #else
555
+ /// @brief Store a string in the buffer, which null-terminated.
556
+ /// If a string with this exact contents has already been serialized before,
557
+ /// instead simply returns the offset of the existing string. This uses a map
558
+ /// stored on the heap, but only stores the numerical offsets.
559
+ /// @param[in] str A const char pointer to a C-string to add to the buffer.
560
+ /// @return Returns the offset in the buffer where the string starts.
561
+ Offset<String> CreateSharedString(const char *str) {
562
+ return CreateSharedString(str, strlen(str));
563
+ }
564
+
565
+ /// @brief Store a string in the buffer, which can contain any binary data.
566
+ /// If a string with this exact contents has already been serialized before,
567
+ /// instead simply returns the offset of the existing string. This uses a map
568
+ /// stored on the heap, but only stores the numerical offsets.
569
+ /// @param[in] str A const reference to a std::string to store in the buffer.
570
+ /// @return Returns the offset in the buffer where the string starts.
571
+ Offset<String> CreateSharedString(const std::string &str) {
572
+ return CreateSharedString(str.c_str(), str.length());
573
+ }
574
+ #endif
575
+
576
+ /// @brief Store a string in the buffer, which can contain any binary data.
577
+ /// If a string with this exact contents has already been serialized before,
578
+ /// instead simply returns the offset of the existing string. This uses a map
579
+ /// stored on the heap, but only stores the numerical offsets.
580
+ /// @param[in] str A const pointer to a `String` struct to add to the buffer.
581
+ /// @return Returns the offset in the buffer where the string starts
582
+ Offset<String> CreateSharedString(const String *str) {
583
+ return str ? CreateSharedString(str->c_str(), str->size()) : 0;
584
+ }
585
+
586
+ /// @cond FLATBUFFERS_INTERNAL
587
+ uoffset_t EndVector(size_t len) {
588
+ FLATBUFFERS_ASSERT(nested); // Hit if no corresponding StartVector.
589
+ nested = false;
590
+ return PushElement(static_cast<uoffset_t>(len));
591
+ }
592
+
593
+ void StartVector(size_t len, size_t elemsize, size_t alignment) {
594
+ NotNested();
595
+ nested = true;
596
+ PreAlign<uoffset_t>(len * elemsize);
597
+ PreAlign(len * elemsize, alignment); // Just in case elemsize > uoffset_t.
598
+ }
599
+
600
+ template<typename T> void StartVector(size_t len) {
601
+ return StartVector(len, sizeof(T), AlignOf<T>());
602
+ }
603
+
604
+ // Call this right before StartVector/CreateVector if you want to force the
605
+ // alignment to be something different than what the element size would
606
+ // normally dictate.
607
+ // This is useful when storing a nested_flatbuffer in a vector of bytes,
608
+ // or when storing SIMD floats, etc.
609
+ void ForceVectorAlignment(size_t len, size_t elemsize, size_t alignment) {
610
+ if (len == 0) return;
611
+ FLATBUFFERS_ASSERT(VerifyAlignmentRequirements(alignment));
612
+ PreAlign(len * elemsize, alignment);
613
+ }
614
+
615
+ // Similar to ForceVectorAlignment but for String fields.
616
+ void ForceStringAlignment(size_t len, size_t alignment) {
617
+ if (len == 0) return;
618
+ FLATBUFFERS_ASSERT(VerifyAlignmentRequirements(alignment));
619
+ PreAlign((len + 1) * sizeof(char), alignment);
620
+ }
621
+
622
+ /// @endcond
623
+
624
+ /// @brief Serialize an array into a FlatBuffer `vector`.
625
+ /// @tparam T The data type of the array elements.
626
+ /// @param[in] v A pointer to the array of type `T` to serialize into the
627
+ /// buffer as a `vector`.
628
+ /// @param[in] len The number of elements to serialize.
629
+ /// @return Returns a typed `Offset` into the serialized data indicating
630
+ /// where the vector is stored.
631
+ template<typename T> Offset<Vector<T>> CreateVector(const T *v, size_t len) {
632
+ // If this assert hits, you're specifying a template argument that is
633
+ // causing the wrong overload to be selected, remove it.
634
+ AssertScalarT<T>();
635
+ StartVector<T>(len);
636
+ if (len == 0) { return Offset<Vector<T>>(EndVector(len)); }
637
+ // clang-format off
638
+ #if FLATBUFFERS_LITTLEENDIAN
639
+ PushBytes(reinterpret_cast<const uint8_t *>(v), len * sizeof(T));
640
+ #else
641
+ if (sizeof(T) == 1) {
642
+ PushBytes(reinterpret_cast<const uint8_t *>(v), len);
643
+ } else {
644
+ for (auto i = len; i > 0; ) {
645
+ PushElement(v[--i]);
646
+ }
647
+ }
648
+ #endif
649
+ // clang-format on
650
+ return Offset<Vector<T>>(EndVector(len));
651
+ }
652
+
653
+ /// @brief Serialize an array like object into a FlatBuffer `vector`.
654
+ /// @tparam T The data type of the array elements.
655
+ /// @tparam C The type of the array.
656
+ /// @param[in] array A reference to an array like object of type `T` to
657
+ /// serialize into the buffer as a `vector`.
658
+ /// @return Returns a typed `Offset` into the serialized data indicating
659
+ /// where the vector is stored.
660
+ template<typename T, class C> Offset<Vector<T>> CreateVector(const C &array) {
661
+ return CreateVector(array.data(), array.size());
662
+ }
663
+
664
+ /// @brief Serialize an initializer list into a FlatBuffer `vector`.
665
+ /// @tparam T The data type of the initializer list elements.
666
+ /// @param[in] v The value of the initializer list.
667
+ /// @return Returns a typed `Offset` into the serialized data indicating
668
+ /// where the vector is stored.
669
+ template<typename T>
670
+ Offset<Vector<T>> CreateVector(std::initializer_list<T> v) {
671
+ return CreateVector(v.begin(), v.size());
672
+ }
673
+
674
+ template<typename T>
675
+ Offset<Vector<Offset<T>>> CreateVector(const Offset<T> *v, size_t len) {
676
+ StartVector<Offset<T>>(len);
677
+ for (auto i = len; i > 0;) { PushElement(v[--i]); }
678
+ return Offset<Vector<Offset<T>>>(EndVector(len));
679
+ }
680
+
681
+ /// @brief Serialize a `std::vector` into a FlatBuffer `vector`.
682
+ /// @tparam T The data type of the `std::vector` elements.
683
+ /// @param v A const reference to the `std::vector` to serialize into the
684
+ /// buffer as a `vector`.
685
+ /// @return Returns a typed `Offset` into the serialized data indicating
686
+ /// where the vector is stored.
687
+ template<typename T, typename Alloc = std::allocator<T>>
688
+ Offset<Vector<T>> CreateVector(const std::vector<T, Alloc> &v) {
689
+ return CreateVector(data(v), v.size());
690
+ }
691
+
692
+ // vector<bool> may be implemented using a bit-set, so we can't access it as
693
+ // an array. Instead, read elements manually.
694
+ // Background: https://isocpp.org/blog/2012/11/on-vectorbool
695
+ Offset<Vector<uint8_t>> CreateVector(const std::vector<bool> &v) {
696
+ StartVector<uint8_t>(v.size());
697
+ for (auto i = v.size(); i > 0;) {
698
+ PushElement(static_cast<uint8_t>(v[--i]));
699
+ }
700
+ return Offset<Vector<uint8_t>>(EndVector(v.size()));
701
+ }
702
+
703
+ /// @brief Serialize values returned by a function into a FlatBuffer `vector`.
704
+ /// This is a convenience function that takes care of iteration for you.
705
+ /// @tparam T The data type of the `std::vector` elements.
706
+ /// @param f A function that takes the current iteration 0..vector_size-1 and
707
+ /// returns any type that you can construct a FlatBuffers vector out of.
708
+ /// @return Returns a typed `Offset` into the serialized data indicating
709
+ /// where the vector is stored.
710
+ template<typename T>
711
+ Offset<Vector<T>> CreateVector(size_t vector_size,
712
+ const std::function<T(size_t i)> &f) {
713
+ FLATBUFFERS_ASSERT(FLATBUFFERS_GENERAL_HEAP_ALLOC_OK);
714
+ std::vector<T> elems(vector_size);
715
+ for (size_t i = 0; i < vector_size; i++) elems[i] = f(i);
716
+ return CreateVector(elems);
717
+ }
718
+
719
+ /// @brief Serialize values returned by a function into a FlatBuffer `vector`.
720
+ /// This is a convenience function that takes care of iteration for you. This
721
+ /// uses a vector stored on the heap to store the intermediate results of the
722
+ /// iteration.
723
+ /// @tparam T The data type of the `std::vector` elements.
724
+ /// @param f A function that takes the current iteration 0..vector_size-1,
725
+ /// and the state parameter returning any type that you can construct a
726
+ /// FlatBuffers vector out of.
727
+ /// @param state State passed to f.
728
+ /// @return Returns a typed `Offset` into the serialized data indicating
729
+ /// where the vector is stored.
730
+ template<typename T, typename F, typename S>
731
+ Offset<Vector<T>> CreateVector(size_t vector_size, F f, S *state) {
732
+ FLATBUFFERS_ASSERT(FLATBUFFERS_GENERAL_HEAP_ALLOC_OK);
733
+ std::vector<T> elems(vector_size);
734
+ for (size_t i = 0; i < vector_size; i++) elems[i] = f(i, state);
735
+ return CreateVector(elems);
736
+ }
737
+
738
+ /// @brief Serialize a `std::vector<StringType>` into a FlatBuffer `vector`.
739
+ /// whereas StringType is any type that is accepted by the CreateString()
740
+ /// overloads.
741
+ /// This is a convenience function for a common case.
742
+ /// @param v A const reference to the `std::vector` to serialize into the
743
+ /// buffer as a `vector`.
744
+ /// @return Returns a typed `Offset` into the serialized data indicating
745
+ /// where the vector is stored.
746
+ template<typename StringType = std::string,
747
+ typename Alloc = std::allocator<StringType>>
748
+ Offset<Vector<Offset<String>>> CreateVectorOfStrings(
749
+ const std::vector<StringType, Alloc> &v) {
750
+ return CreateVectorOfStrings(v.cbegin(), v.cend());
751
+ }
752
+
753
+ /// @brief Serialize a collection of Strings into a FlatBuffer `vector`.
754
+ /// This is a convenience function for a common case.
755
+ /// @param begin The beginning iterator of the collection
756
+ /// @param end The ending iterator of the collection
757
+ /// @return Returns a typed `Offset` into the serialized data indicating
758
+ /// where the vector is stored.
759
+ template<class It>
760
+ Offset<Vector<Offset<String>>> CreateVectorOfStrings(It begin, It end) {
761
+ auto size = std::distance(begin, end);
762
+ auto scratch_buffer_usage = size * sizeof(Offset<String>);
763
+ // If there is not enough space to store the offsets, there definitely won't
764
+ // be enough space to store all the strings. So ensuring space for the
765
+ // scratch region is OK, for if it fails, it would have failed later.
766
+ buf_.ensure_space(scratch_buffer_usage);
767
+ for (auto it = begin; it != end; ++it) {
768
+ buf_.scratch_push_small(CreateString(*it));
769
+ }
770
+ StartVector<Offset<String>>(size);
771
+ for (auto i = 1; i <= size; i++) {
772
+ // Note we re-evaluate the buf location each iteration to account for any
773
+ // underlying buffer resizing that may occur.
774
+ PushElement(*reinterpret_cast<Offset<String> *>(
775
+ buf_.scratch_end() - i * sizeof(Offset<String>)));
776
+ }
777
+ buf_.scratch_pop(scratch_buffer_usage);
778
+ return Offset<Vector<Offset<String>>>(EndVector(size));
779
+ }
780
+
781
+ /// @brief Serialize an array of structs into a FlatBuffer `vector`.
782
+ /// @tparam T The data type of the struct array elements.
783
+ /// @param[in] v A pointer to the array of type `T` to serialize into the
784
+ /// buffer as a `vector`.
785
+ /// @param[in] len The number of elements to serialize.
786
+ /// @return Returns a typed `Offset` into the serialized data indicating
787
+ /// where the vector is stored.
788
+ template<typename T>
789
+ Offset<Vector<const T *>> CreateVectorOfStructs(const T *v, size_t len) {
790
+ StartVector(len * sizeof(T) / AlignOf<T>(), sizeof(T), AlignOf<T>());
791
+ if (len > 0) {
792
+ PushBytes(reinterpret_cast<const uint8_t *>(v), sizeof(T) * len);
793
+ }
794
+ return Offset<Vector<const T *>>(EndVector(len));
795
+ }
796
+
797
+ /// @brief Serialize an array of native structs into a FlatBuffer `vector`.
798
+ /// @tparam T The data type of the struct array elements.
799
+ /// @tparam S The data type of the native struct array elements.
800
+ /// @param[in] v A pointer to the array of type `S` to serialize into the
801
+ /// buffer as a `vector`.
802
+ /// @param[in] len The number of elements to serialize.
803
+ /// @param[in] pack_func Pointer to a function to convert the native struct
804
+ /// to the FlatBuffer struct.
805
+ /// @return Returns a typed `Offset` into the serialized data indicating
806
+ /// where the vector is stored.
807
+ template<typename T, typename S>
808
+ Offset<Vector<const T *>> CreateVectorOfNativeStructs(
809
+ const S *v, size_t len, T (*const pack_func)(const S &)) {
810
+ FLATBUFFERS_ASSERT(pack_func);
811
+ auto structs = StartVectorOfStructs<T>(len);
812
+ for (size_t i = 0; i < len; i++) { structs[i] = pack_func(v[i]); }
813
+ return EndVectorOfStructs<T>(len);
814
+ }
815
+
816
+ /// @brief Serialize an array of native structs into a FlatBuffer `vector`.
817
+ /// @tparam T The data type of the struct array elements.
818
+ /// @tparam S The data type of the native struct array elements.
819
+ /// @param[in] v A pointer to the array of type `S` to serialize into the
820
+ /// buffer as a `vector`.
821
+ /// @param[in] len The number of elements to serialize.
822
+ /// @return Returns a typed `Offset` into the serialized data indicating
823
+ /// where the vector is stored.
824
+ template<typename T, typename S>
825
+ Offset<Vector<const T *>> CreateVectorOfNativeStructs(const S *v,
826
+ size_t len) {
827
+ extern T Pack(const S &);
828
+ return CreateVectorOfNativeStructs(v, len, Pack);
829
+ }
830
+
831
+ /// @brief Serialize an array of structs into a FlatBuffer `vector`.
832
+ /// @tparam T The data type of the struct array elements.
833
+ /// @param[in] filler A function that takes the current iteration
834
+ /// 0..vector_size-1 and a pointer to the struct that must be filled.
835
+ /// @return Returns a typed `Offset` into the serialized data indicating
836
+ /// where the vector is stored.
837
+ /// This is mostly useful when flatbuffers are generated with mutation
838
+ /// accessors.
839
+ template<typename T>
840
+ Offset<Vector<const T *>> CreateVectorOfStructs(
841
+ size_t vector_size, const std::function<void(size_t i, T *)> &filler) {
842
+ T *structs = StartVectorOfStructs<T>(vector_size);
843
+ for (size_t i = 0; i < vector_size; i++) {
844
+ filler(i, structs);
845
+ structs++;
846
+ }
847
+ return EndVectorOfStructs<T>(vector_size);
848
+ }
849
+
850
+ /// @brief Serialize an array of structs into a FlatBuffer `vector`.
851
+ /// @tparam T The data type of the struct array elements.
852
+ /// @param[in] f A function that takes the current iteration 0..vector_size-1,
853
+ /// a pointer to the struct that must be filled and the state argument.
854
+ /// @param[in] state Arbitrary state to pass to f.
855
+ /// @return Returns a typed `Offset` into the serialized data indicating
856
+ /// where the vector is stored.
857
+ /// This is mostly useful when flatbuffers are generated with mutation
858
+ /// accessors.
859
+ template<typename T, typename F, typename S>
860
+ Offset<Vector<const T *>> CreateVectorOfStructs(size_t vector_size, F f,
861
+ S *state) {
862
+ T *structs = StartVectorOfStructs<T>(vector_size);
863
+ for (size_t i = 0; i < vector_size; i++) {
864
+ f(i, structs, state);
865
+ structs++;
866
+ }
867
+ return EndVectorOfStructs<T>(vector_size);
868
+ }
869
+
870
+ /// @brief Serialize a `std::vector` of structs into a FlatBuffer `vector`.
871
+ /// @tparam T The data type of the `std::vector` struct elements.
872
+ /// @param[in] v A const reference to the `std::vector` of structs to
873
+ /// serialize into the buffer as a `vector`.
874
+ /// @return Returns a typed `Offset` into the serialized data indicating
875
+ /// where the vector is stored.
876
+ template<typename T, typename Alloc = std::allocator<T>>
877
+ Offset<Vector<const T *>> CreateVectorOfStructs(
878
+ const std::vector<T, Alloc> &v) {
879
+ return CreateVectorOfStructs(data(v), v.size());
880
+ }
881
+
882
+ /// @brief Serialize a `std::vector` of native structs into a FlatBuffer
883
+ /// `vector`.
884
+ /// @tparam T The data type of the `std::vector` struct elements.
885
+ /// @tparam S The data type of the `std::vector` native struct elements.
886
+ /// @param[in] v A const reference to the `std::vector` of structs to
887
+ /// serialize into the buffer as a `vector`.
888
+ /// @param[in] pack_func Pointer to a function to convert the native struct
889
+ /// to the FlatBuffer struct.
890
+ /// @return Returns a typed `Offset` into the serialized data indicating
891
+ /// where the vector is stored.
892
+ template<typename T, typename S, typename Alloc = std::allocator<T>>
893
+ Offset<Vector<const T *>> CreateVectorOfNativeStructs(
894
+ const std::vector<S, Alloc> &v, T (*const pack_func)(const S &)) {
895
+ return CreateVectorOfNativeStructs<T, S>(data(v), v.size(), pack_func);
896
+ }
897
+
898
+ /// @brief Serialize a `std::vector` of native structs into a FlatBuffer
899
+ /// `vector`.
900
+ /// @tparam T The data type of the `std::vector` struct elements.
901
+ /// @tparam S The data type of the `std::vector` native struct elements.
902
+ /// @param[in] v A const reference to the `std::vector` of structs to
903
+ /// serialize into the buffer as a `vector`.
904
+ /// @return Returns a typed `Offset` into the serialized data indicating
905
+ /// where the vector is stored.
906
+ template<typename T, typename S, typename Alloc = std::allocator<S>>
907
+ Offset<Vector<const T *>> CreateVectorOfNativeStructs(
908
+ const std::vector<S, Alloc> &v) {
909
+ return CreateVectorOfNativeStructs<T, S>(data(v), v.size());
910
+ }
911
+
912
+ /// @cond FLATBUFFERS_INTERNAL
913
+ template<typename T> struct StructKeyComparator {
914
+ bool operator()(const T &a, const T &b) const {
915
+ return a.KeyCompareLessThan(&b);
916
+ }
917
+ };
918
+ /// @endcond
919
+
920
+ /// @brief Serialize a `std::vector` of structs into a FlatBuffer `vector`
921
+ /// in sorted order.
922
+ /// @tparam T The data type of the `std::vector` struct elements.
923
+ /// @param[in] v A const reference to the `std::vector` of structs to
924
+ /// serialize into the buffer as a `vector`.
925
+ /// @return Returns a typed `Offset` into the serialized data indicating
926
+ /// where the vector is stored.
927
+ template<typename T, typename Alloc = std::allocator<T>>
928
+ Offset<Vector<const T *>> CreateVectorOfSortedStructs(
929
+ std::vector<T, Alloc> *v) {
930
+ return CreateVectorOfSortedStructs(data(*v), v->size());
931
+ }
932
+
933
+ /// @brief Serialize a `std::vector` of native structs into a FlatBuffer
934
+ /// `vector` in sorted order.
935
+ /// @tparam T The data type of the `std::vector` struct elements.
936
+ /// @tparam S The data type of the `std::vector` native struct elements.
937
+ /// @param[in] v A const reference to the `std::vector` of structs to
938
+ /// serialize into the buffer as a `vector`.
939
+ /// @return Returns a typed `Offset` into the serialized data indicating
940
+ /// where the vector is stored.
941
+ template<typename T, typename S, typename Alloc = std::allocator<T>>
942
+ Offset<Vector<const T *>> CreateVectorOfSortedNativeStructs(
943
+ std::vector<S, Alloc> *v) {
944
+ return CreateVectorOfSortedNativeStructs<T, S>(data(*v), v->size());
945
+ }
946
+
947
+ /// @brief Serialize an array of structs into a FlatBuffer `vector` in sorted
948
+ /// order.
949
+ /// @tparam T The data type of the struct array elements.
950
+ /// @param[in] v A pointer to the array of type `T` to serialize into the
951
+ /// buffer as a `vector`.
952
+ /// @param[in] len The number of elements to serialize.
953
+ /// @return Returns a typed `Offset` into the serialized data indicating
954
+ /// where the vector is stored.
955
+ template<typename T>
956
+ Offset<Vector<const T *>> CreateVectorOfSortedStructs(T *v, size_t len) {
957
+ std::stable_sort(v, v + len, StructKeyComparator<T>());
958
+ return CreateVectorOfStructs(v, len);
959
+ }
960
+
961
+ /// @brief Serialize an array of native structs into a FlatBuffer `vector` in
962
+ /// sorted order.
963
+ /// @tparam T The data type of the struct array elements.
964
+ /// @tparam S The data type of the native struct array elements.
965
+ /// @param[in] v A pointer to the array of type `S` to serialize into the
966
+ /// buffer as a `vector`.
967
+ /// @param[in] len The number of elements to serialize.
968
+ /// @return Returns a typed `Offset` into the serialized data indicating
969
+ /// where the vector is stored.
970
+ template<typename T, typename S>
971
+ Offset<Vector<const T *>> CreateVectorOfSortedNativeStructs(S *v,
972
+ size_t len) {
973
+ extern T Pack(const S &);
974
+ auto structs = StartVectorOfStructs<T>(len);
975
+ for (size_t i = 0; i < len; i++) { structs[i] = Pack(v[i]); }
976
+ std::stable_sort(structs, structs + len, StructKeyComparator<T>());
977
+ return EndVectorOfStructs<T>(len);
978
+ }
979
+
980
+ /// @cond FLATBUFFERS_INTERNAL
981
+ template<typename T> struct TableKeyComparator {
982
+ TableKeyComparator(vector_downward &buf) : buf_(buf) {}
983
+ TableKeyComparator(const TableKeyComparator &other) : buf_(other.buf_) {}
984
+ bool operator()(const Offset<T> &a, const Offset<T> &b) const {
985
+ auto table_a = reinterpret_cast<T *>(buf_.data_at(a.o));
986
+ auto table_b = reinterpret_cast<T *>(buf_.data_at(b.o));
987
+ return table_a->KeyCompareLessThan(table_b);
988
+ }
989
+ vector_downward &buf_;
990
+
991
+ private:
992
+ FLATBUFFERS_DELETE_FUNC(
993
+ TableKeyComparator &operator=(const TableKeyComparator &other));
994
+ };
995
+ /// @endcond
996
+
997
+ /// @brief Serialize an array of `table` offsets as a `vector` in the buffer
998
+ /// in sorted order.
999
+ /// @tparam T The data type that the offset refers to.
1000
+ /// @param[in] v An array of type `Offset<T>` that contains the `table`
1001
+ /// offsets to store in the buffer in sorted order.
1002
+ /// @param[in] len The number of elements to store in the `vector`.
1003
+ /// @return Returns a typed `Offset` into the serialized data indicating
1004
+ /// where the vector is stored.
1005
+ template<typename T>
1006
+ Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(Offset<T> *v,
1007
+ size_t len) {
1008
+ std::stable_sort(v, v + len, TableKeyComparator<T>(buf_));
1009
+ return CreateVector(v, len);
1010
+ }
1011
+
1012
+ /// @brief Serialize an array of `table` offsets as a `vector` in the buffer
1013
+ /// in sorted order.
1014
+ /// @tparam T The data type that the offset refers to.
1015
+ /// @param[in] v An array of type `Offset<T>` that contains the `table`
1016
+ /// offsets to store in the buffer in sorted order.
1017
+ /// @return Returns a typed `Offset` into the serialized data indicating
1018
+ /// where the vector is stored.
1019
+ template<typename T, typename Alloc = std::allocator<T>>
1020
+ Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(
1021
+ std::vector<Offset<T>, Alloc> *v) {
1022
+ return CreateVectorOfSortedTables(data(*v), v->size());
1023
+ }
1024
+
1025
+ /// @brief Specialized version of `CreateVector` for non-copying use cases.
1026
+ /// Write the data any time later to the returned buffer pointer `buf`.
1027
+ /// @param[in] len The number of elements to store in the `vector`.
1028
+ /// @param[in] elemsize The size of each element in the `vector`.
1029
+ /// @param[out] buf A pointer to a `uint8_t` pointer that can be
1030
+ /// written to at a later time to serialize the data into a `vector`
1031
+ /// in the buffer.
1032
+ uoffset_t CreateUninitializedVector(size_t len, size_t elemsize,
1033
+ size_t alignment, uint8_t **buf) {
1034
+ NotNested();
1035
+ StartVector(len, elemsize, alignment);
1036
+ buf_.make_space(len * elemsize);
1037
+ auto vec_start = GetSize();
1038
+ auto vec_end = EndVector(len);
1039
+ *buf = buf_.data_at(vec_start);
1040
+ return vec_end;
1041
+ }
1042
+
1043
+ FLATBUFFERS_ATTRIBUTE([[deprecated("call the version above instead")]])
1044
+ uoffset_t CreateUninitializedVector(size_t len, size_t elemsize,
1045
+ uint8_t **buf) {
1046
+ return CreateUninitializedVector(len, elemsize, elemsize, buf);
1047
+ }
1048
+
1049
+ /// @brief Specialized version of `CreateVector` for non-copying use cases.
1050
+ /// Write the data any time later to the returned buffer pointer `buf`.
1051
+ /// @tparam T The data type of the data that will be stored in the buffer
1052
+ /// as a `vector`.
1053
+ /// @param[in] len The number of elements to store in the `vector`.
1054
+ /// @param[out] buf A pointer to a pointer of type `T` that can be
1055
+ /// written to at a later time to serialize the data into a `vector`
1056
+ /// in the buffer.
1057
+ template<typename T>
1058
+ Offset<Vector<T>> CreateUninitializedVector(size_t len, T **buf) {
1059
+ AssertScalarT<T>();
1060
+ return CreateUninitializedVector(len, sizeof(T), AlignOf<T>(),
1061
+ reinterpret_cast<uint8_t **>(buf));
1062
+ }
1063
+
1064
+ template<typename T>
1065
+ Offset<Vector<const T *>> CreateUninitializedVectorOfStructs(size_t len,
1066
+ T **buf) {
1067
+ return CreateUninitializedVector(len, sizeof(T), AlignOf<T>(),
1068
+ reinterpret_cast<uint8_t **>(buf));
1069
+ }
1070
+
1071
+ // @brief Create a vector of scalar type T given as input a vector of scalar
1072
+ // type U, useful with e.g. pre "enum class" enums, or any existing scalar
1073
+ // data of the wrong type.
1074
+ template<typename T, typename U>
1075
+ Offset<Vector<T>> CreateVectorScalarCast(const U *v, size_t len) {
1076
+ AssertScalarT<T>();
1077
+ AssertScalarT<U>();
1078
+ StartVector<T>(len);
1079
+ for (auto i = len; i > 0;) { PushElement(static_cast<T>(v[--i])); }
1080
+ return Offset<Vector<T>>(EndVector(len));
1081
+ }
1082
+
1083
+ /// @brief Write a struct by itself, typically to be part of a union.
1084
+ template<typename T> Offset<const T *> CreateStruct(const T &structobj) {
1085
+ NotNested();
1086
+ Align(AlignOf<T>());
1087
+ buf_.push_small(structobj);
1088
+ return Offset<const T *>(GetSize());
1089
+ }
1090
+
1091
+ /// @brief Finish serializing a buffer by writing the root offset.
1092
+ /// @param[in] file_identifier If a `file_identifier` is given, the buffer
1093
+ /// will be prefixed with a standard FlatBuffers file header.
1094
+ template<typename T>
1095
+ void Finish(Offset<T> root, const char *file_identifier = nullptr) {
1096
+ Finish(root.o, file_identifier, false);
1097
+ }
1098
+
1099
+ /// @brief Finish a buffer with a 32 bit size field pre-fixed (size of the
1100
+ /// buffer following the size field). These buffers are NOT compatible
1101
+ /// with standard buffers created by Finish, i.e. you can't call GetRoot
1102
+ /// on them, you have to use GetSizePrefixedRoot instead.
1103
+ /// All >32 bit quantities in this buffer will be aligned when the whole
1104
+ /// size pre-fixed buffer is aligned.
1105
+ /// These kinds of buffers are useful for creating a stream of FlatBuffers.
1106
+ template<typename T>
1107
+ void FinishSizePrefixed(Offset<T> root,
1108
+ const char *file_identifier = nullptr) {
1109
+ Finish(root.o, file_identifier, true);
1110
+ }
1111
+
1112
+ void SwapBufAllocator(FlatBufferBuilder &other) {
1113
+ buf_.swap_allocator(other.buf_);
1114
+ }
1115
+
1116
+ /// @brief The length of a FlatBuffer file header.
1117
+ static const size_t kFileIdentifierLength =
1118
+ ::flatbuffers::kFileIdentifierLength;
1119
+
1120
+ protected:
1121
+ // You shouldn't really be copying instances of this class.
1122
+ FlatBufferBuilder(const FlatBufferBuilder &);
1123
+ FlatBufferBuilder &operator=(const FlatBufferBuilder &);
1124
+
1125
+ void Finish(uoffset_t root, const char *file_identifier, bool size_prefix) {
1126
+ NotNested();
1127
+ buf_.clear_scratch();
1128
+ // This will cause the whole buffer to be aligned.
1129
+ PreAlign((size_prefix ? sizeof(uoffset_t) : 0) + sizeof(uoffset_t) +
1130
+ (file_identifier ? kFileIdentifierLength : 0),
1131
+ minalign_);
1132
+ if (file_identifier) {
1133
+ FLATBUFFERS_ASSERT(strlen(file_identifier) == kFileIdentifierLength);
1134
+ PushBytes(reinterpret_cast<const uint8_t *>(file_identifier),
1135
+ kFileIdentifierLength);
1136
+ }
1137
+ PushElement(ReferTo(root)); // Location of root.
1138
+ if (size_prefix) { PushElement(GetSize()); }
1139
+ finished = true;
1140
+ }
1141
+
1142
+ struct FieldLoc {
1143
+ uoffset_t off;
1144
+ voffset_t id;
1145
+ };
1146
+
1147
+ vector_downward buf_;
1148
+
1149
+ // Accumulating offsets of table members while it is being built.
1150
+ // We store these in the scratch pad of buf_, after the vtable offsets.
1151
+ uoffset_t num_field_loc;
1152
+ // Track how much of the vtable is in use, so we can output the most compact
1153
+ // possible vtable.
1154
+ voffset_t max_voffset_;
1155
+
1156
+ // Ensure objects are not nested.
1157
+ bool nested;
1158
+
1159
+ // Ensure the buffer is finished before it is being accessed.
1160
+ bool finished;
1161
+
1162
+ size_t minalign_;
1163
+
1164
+ bool force_defaults_; // Serialize values equal to their defaults anyway.
1165
+
1166
+ bool dedup_vtables_;
1167
+
1168
+ struct StringOffsetCompare {
1169
+ StringOffsetCompare(const vector_downward &buf) : buf_(&buf) {}
1170
+ bool operator()(const Offset<String> &a, const Offset<String> &b) const {
1171
+ auto stra = reinterpret_cast<const String *>(buf_->data_at(a.o));
1172
+ auto strb = reinterpret_cast<const String *>(buf_->data_at(b.o));
1173
+ return StringLessThan(stra->data(), stra->size(), strb->data(),
1174
+ strb->size());
1175
+ }
1176
+ const vector_downward *buf_;
1177
+ };
1178
+
1179
+ // For use with CreateSharedString. Instantiated on first use only.
1180
+ typedef std::set<Offset<String>, StringOffsetCompare> StringOffsetMap;
1181
+ StringOffsetMap *string_pool;
1182
+
1183
+ private:
1184
+ // Allocates space for a vector of structures.
1185
+ // Must be completed with EndVectorOfStructs().
1186
+ template<typename T> T *StartVectorOfStructs(size_t vector_size) {
1187
+ StartVector(vector_size * sizeof(T) / AlignOf<T>(), sizeof(T), AlignOf<T>());
1188
+ return reinterpret_cast<T *>(buf_.make_space(vector_size * sizeof(T)));
1189
+ }
1190
+
1191
+ // End the vector of structures in the flatbuffers.
1192
+ // Vector should have previously be started with StartVectorOfStructs().
1193
+ template<typename T>
1194
+ Offset<Vector<const T *>> EndVectorOfStructs(size_t vector_size) {
1195
+ return Offset<Vector<const T *>>(EndVector(vector_size));
1196
+ }
1197
+ };
1198
+ /// @}
1199
+
1200
+ /// Helpers to get a typed pointer to objects that are currently being built.
1201
+ /// @warning Creating new objects will lead to reallocations and invalidates
1202
+ /// the pointer!
1203
+ template<typename T>
1204
+ T *GetMutableTemporaryPointer(FlatBufferBuilder &fbb, Offset<T> offset) {
1205
+ return reinterpret_cast<T *>(fbb.GetCurrentBufferPointer() + fbb.GetSize() -
1206
+ offset.o);
1207
+ }
1208
+
1209
+ template<typename T>
1210
+ const T *GetTemporaryPointer(FlatBufferBuilder &fbb, Offset<T> offset) {
1211
+ return GetMutableTemporaryPointer<T>(fbb, offset);
1212
+ }
1213
+
1214
+ template<typename T>
1215
+ void FlatBufferBuilder::Required(Offset<T> table, voffset_t field) {
1216
+ auto table_ptr = reinterpret_cast<const Table *>(buf_.data_at(table.o));
1217
+ bool ok = table_ptr->GetOptionalFieldOffset(field) != 0;
1218
+ // If this fails, the caller will show what field needs to be set.
1219
+ FLATBUFFERS_ASSERT(ok);
1220
+ (void)ok;
1221
+ }
1222
+
1223
+ } // namespace flatbuffers
1224
+
1225
+ #endif // FLATBUFFERS_VECTOR_DOWNWARD_H_