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.
- nvfuser/_C.cpython-312-x86_64-linux-gnu.so +0 -0
- nvfuser/__init__.py +618 -0
- nvfuser/__init__.pyi +4 -0
- nvfuser/contrib/__init__.py +9 -0
- nvfuser/contrib/nn/__init__.py +13 -0
- nvfuser/contrib/nn/normalization.py +725 -0
- nvfuser/include/nvfuser/alias_analysis.h +116 -0
- nvfuser/include/nvfuser/bfs.h +929 -0
- nvfuser/include/nvfuser/codegen.h +26 -0
- nvfuser/include/nvfuser/compute_at.h +28 -0
- nvfuser/include/nvfuser/compute_at_map.h +394 -0
- nvfuser/include/nvfuser/contiguity.h +351 -0
- nvfuser/include/nvfuser/cuda_utils.h +50 -0
- nvfuser/include/nvfuser/debug.h +50 -0
- nvfuser/include/nvfuser/device_lower/analysis/bank_conflict.h +53 -0
- nvfuser/include/nvfuser/device_lower/analysis/circular_buffer.h +109 -0
- nvfuser/include/nvfuser/device_lower/analysis/device_version.h +65 -0
- nvfuser/include/nvfuser/device_lower/analysis/divisible_split.h +28 -0
- nvfuser/include/nvfuser/device_lower/analysis/fused_reduction.h +36 -0
- nvfuser/include/nvfuser/device_lower/analysis/index_compute.h +322 -0
- nvfuser/include/nvfuser/device_lower/analysis/predicate_elimination.h +71 -0
- nvfuser/include/nvfuser/device_lower/analysis/sync_information.h +47 -0
- nvfuser/include/nvfuser/device_lower/analysis/tensor_memory.h +65 -0
- nvfuser/include/nvfuser/device_lower/analysis/thread_predicate.h +158 -0
- nvfuser/include/nvfuser/device_lower/analysis/tma.h +93 -0
- nvfuser/include/nvfuser/device_lower/analysis/trivial_broadcast.h +75 -0
- nvfuser/include/nvfuser/device_lower/id_model_options.h +135 -0
- nvfuser/include/nvfuser/device_lower/lower2device.h +391 -0
- nvfuser/include/nvfuser/device_lower/pass/alias_memory.h +37 -0
- nvfuser/include/nvfuser/device_lower/pass/allocation.h +32 -0
- nvfuser/include/nvfuser/device_lower/pass/circular_buffer.h +191 -0
- nvfuser/include/nvfuser/device_lower/pass/expr_sort.h +17 -0
- nvfuser/include/nvfuser/device_lower/pass/fusion_simplifier.h +21 -0
- nvfuser/include/nvfuser/device_lower/pass/grid_serialization.h +26 -0
- nvfuser/include/nvfuser/device_lower/pass/index.h +200 -0
- nvfuser/include/nvfuser/device_lower/pass/inline_ptx.h +16 -0
- nvfuser/include/nvfuser/device_lower/pass/insert_syncs.h +39 -0
- nvfuser/include/nvfuser/device_lower/pass/instrument.h +24 -0
- nvfuser/include/nvfuser/device_lower/pass/loop_rotation.h +150 -0
- nvfuser/include/nvfuser/device_lower/pass/loops.h +68 -0
- nvfuser/include/nvfuser/device_lower/pass/magic_zero.h +86 -0
- nvfuser/include/nvfuser/device_lower/pass/misaligned_vectorization.h +118 -0
- nvfuser/include/nvfuser/device_lower/pass/predicate.h +23 -0
- nvfuser/include/nvfuser/device_lower/pass/replace_size.h +24 -0
- nvfuser/include/nvfuser/device_lower/pass/scalar_hoist.h +115 -0
- nvfuser/include/nvfuser/device_lower/pass/unroll.h +98 -0
- nvfuser/include/nvfuser/device_lower/pass/vectorize_welford.h +45 -0
- nvfuser/include/nvfuser/device_lower/pass/warp_reduce.h +23 -0
- nvfuser/include/nvfuser/device_lower/utils.h +382 -0
- nvfuser/include/nvfuser/device_lower/validation.h +74 -0
- nvfuser/include/nvfuser/disjoint_set.h +556 -0
- nvfuser/include/nvfuser/dispatch.h +334 -0
- nvfuser/include/nvfuser/driver_api.h +49 -0
- nvfuser/include/nvfuser/dynamic_transform.h +316 -0
- nvfuser/include/nvfuser/dynamic_type/C++20/type_traits +37 -0
- nvfuser/include/nvfuser/dynamic_type/dynamic_type.h +969 -0
- nvfuser/include/nvfuser/dynamic_type/error.h +24 -0
- nvfuser/include/nvfuser/dynamic_type/type_traits.h +703 -0
- nvfuser/include/nvfuser/evaluator_common.h +295 -0
- nvfuser/include/nvfuser/exceptions.h +283 -0
- nvfuser/include/nvfuser/expr_evaluator.h +125 -0
- nvfuser/include/nvfuser/expr_simplifier.h +218 -0
- nvfuser/include/nvfuser/flatbuffers/allocator.h +68 -0
- nvfuser/include/nvfuser/flatbuffers/array.h +253 -0
- nvfuser/include/nvfuser/flatbuffers/base.h +486 -0
- nvfuser/include/nvfuser/flatbuffers/buffer.h +154 -0
- nvfuser/include/nvfuser/flatbuffers/buffer_ref.h +53 -0
- nvfuser/include/nvfuser/flatbuffers/code_generator.h +80 -0
- nvfuser/include/nvfuser/flatbuffers/code_generators.h +234 -0
- nvfuser/include/nvfuser/flatbuffers/default_allocator.h +64 -0
- nvfuser/include/nvfuser/flatbuffers/detached_buffer.h +114 -0
- nvfuser/include/nvfuser/flatbuffers/flatbuffer_builder.h +1225 -0
- nvfuser/include/nvfuser/flatbuffers/flatbuffers.h +272 -0
- nvfuser/include/nvfuser/flatbuffers/flatc.h +130 -0
- nvfuser/include/nvfuser/flatbuffers/flex_flat_util.h +36 -0
- nvfuser/include/nvfuser/flatbuffers/flexbuffers.h +1889 -0
- nvfuser/include/nvfuser/flatbuffers/grpc.h +300 -0
- nvfuser/include/nvfuser/flatbuffers/hash.h +127 -0
- nvfuser/include/nvfuser/flatbuffers/idl.h +1359 -0
- nvfuser/include/nvfuser/flatbuffers/minireflect.h +420 -0
- nvfuser/include/nvfuser/flatbuffers/reflection.h +522 -0
- nvfuser/include/nvfuser/flatbuffers/reflection_generated.h +1471 -0
- nvfuser/include/nvfuser/flatbuffers/registry.h +128 -0
- nvfuser/include/nvfuser/flatbuffers/stl_emulation.h +513 -0
- nvfuser/include/nvfuser/flatbuffers/string.h +64 -0
- nvfuser/include/nvfuser/flatbuffers/struct.h +53 -0
- nvfuser/include/nvfuser/flatbuffers/table.h +168 -0
- nvfuser/include/nvfuser/flatbuffers/util.h +731 -0
- nvfuser/include/nvfuser/flatbuffers/vector.h +393 -0
- nvfuser/include/nvfuser/flatbuffers/vector_downward.h +273 -0
- nvfuser/include/nvfuser/flatbuffers/verifier.h +317 -0
- nvfuser/include/nvfuser/fusion.h +511 -0
- nvfuser/include/nvfuser/fusion_guard.h +37 -0
- nvfuser/include/nvfuser/fusion_profiler.h +311 -0
- nvfuser/include/nvfuser/fusion_segmenter.h +751 -0
- nvfuser/include/nvfuser/global_allocator.h +27 -0
- nvfuser/include/nvfuser/grouped_reduction.h +47 -0
- nvfuser/include/nvfuser/host_ir/container.h +60 -0
- nvfuser/include/nvfuser/host_ir/executor.h +152 -0
- nvfuser/include/nvfuser/host_ir/host_ir.h +320 -0
- nvfuser/include/nvfuser/host_ir/lower.h +35 -0
- nvfuser/include/nvfuser/id_model/circular_buffer_indexing.h +56 -0
- nvfuser/include/nvfuser/id_model/contiguity.h +166 -0
- nvfuser/include/nvfuser/id_model/id_model.h +359 -0
- nvfuser/include/nvfuser/id_model/id_model_index_compute.h +81 -0
- nvfuser/include/nvfuser/id_model/indexing.h +208 -0
- nvfuser/include/nvfuser/id_model/indexing_traversal.h +72 -0
- nvfuser/include/nvfuser/id_model/indexing_utils.h +62 -0
- nvfuser/include/nvfuser/id_model/loop_promotion.h +180 -0
- nvfuser/include/nvfuser/id_model/predicate_indexing.h +104 -0
- nvfuser/include/nvfuser/id_model/schedule.h +54 -0
- nvfuser/include/nvfuser/id_model/to_string.h +87 -0
- nvfuser/include/nvfuser/id_model/transform_replay.h +58 -0
- nvfuser/include/nvfuser/id_model/utils.h +176 -0
- nvfuser/include/nvfuser/id_model/validation_utils.h +55 -0
- nvfuser/include/nvfuser/index_compute.h +651 -0
- nvfuser/include/nvfuser/instrumentation.h +107 -0
- nvfuser/include/nvfuser/ir/all_nodes.h +14 -0
- nvfuser/include/nvfuser/ir/base_nodes.h +687 -0
- nvfuser/include/nvfuser/ir/builder.h +215 -0
- nvfuser/include/nvfuser/ir/builder_passkey.h +29 -0
- nvfuser/include/nvfuser/ir/cloner.h +185 -0
- nvfuser/include/nvfuser/ir/container.h +226 -0
- nvfuser/include/nvfuser/ir/graphviz.h +119 -0
- nvfuser/include/nvfuser/ir/interface_nodes.h +957 -0
- nvfuser/include/nvfuser/ir/internal_base_nodes.h +744 -0
- nvfuser/include/nvfuser/ir/internal_nodes.h +2792 -0
- nvfuser/include/nvfuser/ir/iostream.h +98 -0
- nvfuser/include/nvfuser/ir/printer.h +57 -0
- nvfuser/include/nvfuser/ir/utils.h +801 -0
- nvfuser/include/nvfuser/iter_visitor.h +661 -0
- nvfuser/include/nvfuser/kernel.h +299 -0
- nvfuser/include/nvfuser/kernel_db/kernel_db.h +109 -0
- nvfuser/include/nvfuser/kernel_db/utils.h +37 -0
- nvfuser/include/nvfuser/kernel_ir.h +1457 -0
- nvfuser/include/nvfuser/kernel_ir_dispatch.h +147 -0
- nvfuser/include/nvfuser/linked_hash_map.h +97 -0
- nvfuser/include/nvfuser/logical_domain_map.h +577 -0
- nvfuser/include/nvfuser/macros.h +23 -0
- nvfuser/include/nvfuser/mma_type.h +257 -0
- nvfuser/include/nvfuser/multidevice/c10d_mock.h +175 -0
- nvfuser/include/nvfuser/multidevice/communication.h +232 -0
- nvfuser/include/nvfuser/multidevice/communicator.h +179 -0
- nvfuser/include/nvfuser/multidevice/device_mesh.h +95 -0
- nvfuser/include/nvfuser/multidevice/executor.h +107 -0
- nvfuser/include/nvfuser/multidevice/multidevice.h +18 -0
- nvfuser/include/nvfuser/multidevice/utils.h +187 -0
- nvfuser/include/nvfuser/non_divisible_split.h +86 -0
- nvfuser/include/nvfuser/opaque_type.h +129 -0
- nvfuser/include/nvfuser/ops/alias.h +192 -0
- nvfuser/include/nvfuser/ops/all_ops.h +13 -0
- nvfuser/include/nvfuser/ops/arith.h +712 -0
- nvfuser/include/nvfuser/ops/composite.h +130 -0
- nvfuser/include/nvfuser/ops/indexing.h +55 -0
- nvfuser/include/nvfuser/ops/normalization.h +263 -0
- nvfuser/include/nvfuser/ops/utils.h +127 -0
- nvfuser/include/nvfuser/options.h +313 -0
- nvfuser/include/nvfuser/parallel_dimension_map.h +95 -0
- nvfuser/include/nvfuser/parallel_type_bitmap.h +365 -0
- nvfuser/include/nvfuser/polymorphic_value.h +432 -0
- nvfuser/include/nvfuser/predicate_compute.h +213 -0
- nvfuser/include/nvfuser/python_frontend/distributed_tensor.h +50 -0
- nvfuser/include/nvfuser/python_frontend/fusion_cache.h +298 -0
- nvfuser/include/nvfuser/python_frontend/fusion_definition.h +372 -0
- nvfuser/include/nvfuser/python_frontend/fusion_record.h +3124 -0
- nvfuser/include/nvfuser/python_frontend/fusion_state.h +143 -0
- nvfuser/include/nvfuser/python_frontend/python_bindings.h +27 -0
- nvfuser/include/nvfuser/python_frontend/segmentation.h +246 -0
- nvfuser/include/nvfuser/python_frontend/translation.h +20 -0
- nvfuser/include/nvfuser/python_frontend/translation_utils.h +308 -0
- nvfuser/include/nvfuser/scheduler/all_schedulers.h +17 -0
- nvfuser/include/nvfuser/scheduler/ampere_multi_matmul.h +206 -0
- nvfuser/include/nvfuser/scheduler/cache_policy_refiner.h +19 -0
- nvfuser/include/nvfuser/scheduler/compile_time_info.h +322 -0
- nvfuser/include/nvfuser/scheduler/debug_utils.h +68 -0
- nvfuser/include/nvfuser/scheduler/expr_eval_sched.h +45 -0
- nvfuser/include/nvfuser/scheduler/heuristic.h +113 -0
- nvfuser/include/nvfuser/scheduler/hopper_multi_matmul.h +204 -0
- nvfuser/include/nvfuser/scheduler/mark_aliases.h +19 -0
- nvfuser/include/nvfuser/scheduler/matmul.h +40 -0
- nvfuser/include/nvfuser/scheduler/matmul_heuristic.h +293 -0
- nvfuser/include/nvfuser/scheduler/matmul_heuristic_plugin.h +65 -0
- nvfuser/include/nvfuser/scheduler/matmul_heuristic_plugin_api.h +99 -0
- nvfuser/include/nvfuser/scheduler/matmul_utils.h +54 -0
- nvfuser/include/nvfuser/scheduler/mma_utils.h +500 -0
- nvfuser/include/nvfuser/scheduler/multi_matmul.h +74 -0
- nvfuser/include/nvfuser/scheduler/no_op.h +48 -0
- nvfuser/include/nvfuser/scheduler/normalization_inner.h +49 -0
- nvfuser/include/nvfuser/scheduler/normalization_inner_outer.h +51 -0
- nvfuser/include/nvfuser/scheduler/normalization_outer.h +48 -0
- nvfuser/include/nvfuser/scheduler/normalization_utils.h +379 -0
- nvfuser/include/nvfuser/scheduler/pointwise.h +183 -0
- nvfuser/include/nvfuser/scheduler/pointwise_heuristic.h +118 -0
- nvfuser/include/nvfuser/scheduler/pointwise_utils.h +24 -0
- nvfuser/include/nvfuser/scheduler/reduction.h +43 -0
- nvfuser/include/nvfuser/scheduler/reduction_heuristic.h +339 -0
- nvfuser/include/nvfuser/scheduler/reduction_utils.h +159 -0
- nvfuser/include/nvfuser/scheduler/registry.h +97 -0
- nvfuser/include/nvfuser/scheduler/registry_utils.h +111 -0
- nvfuser/include/nvfuser/scheduler/resize.h +41 -0
- nvfuser/include/nvfuser/scheduler/resize_heuristic.h +67 -0
- nvfuser/include/nvfuser/scheduler/runtime_info.h +166 -0
- nvfuser/include/nvfuser/scheduler/scheduler_types.h +80 -0
- nvfuser/include/nvfuser/scheduler/transpose.h +114 -0
- nvfuser/include/nvfuser/scheduler/transpose_heuristic.h +164 -0
- nvfuser/include/nvfuser/scheduler/utils.h +771 -0
- nvfuser/include/nvfuser/scheduler/vectorize_helper.h +349 -0
- nvfuser/include/nvfuser/serde/factory.h +55 -0
- nvfuser/include/nvfuser/serde/fusion_cache_generated.h +4319 -0
- nvfuser/include/nvfuser/serde/fusion_record.h +124 -0
- nvfuser/include/nvfuser/serde/polymorphic_value.h +52 -0
- nvfuser/include/nvfuser/serde/utils.h +34 -0
- nvfuser/include/nvfuser/struct.inl +127 -0
- nvfuser/include/nvfuser/swizzle.h +54 -0
- nvfuser/include/nvfuser/sys_utils.h +40 -0
- nvfuser/include/nvfuser/tensor_metadata.h +118 -0
- nvfuser/include/nvfuser/tma.h +124 -0
- nvfuser/include/nvfuser/transform_iter.h +522 -0
- nvfuser/include/nvfuser/transform_replay.h +297 -0
- nvfuser/include/nvfuser/transform_rfactor.h +33 -0
- nvfuser/include/nvfuser/transform_view.h +136 -0
- nvfuser/include/nvfuser/type.h +1125 -0
- nvfuser/include/nvfuser/type_promotion.h +61 -0
- nvfuser/include/nvfuser/utils.h +619 -0
- nvfuser/include/nvfuser/val_graph.h +446 -0
- nvfuser/include/nvfuser/val_graph_visitor.h +259 -0
- nvfuser/include/nvfuser/validator_utils.h +92 -0
- nvfuser/include/nvfuser/vectorization_info.h +31 -0
- nvfuser/include/nvfuser/visibility.h +21 -0
- nvfuser/lib/libnvfuser_codegen.so +0 -0
- nvfuser/nvfuser_version.py +69 -0
- nvfuser/pytorch_utils.py +184 -0
- nvfuser/share/cmake/nvfuser/NvfuserConfig-release.cmake +20 -0
- nvfuser/share/cmake/nvfuser/NvfuserConfig.cmake +106 -0
- nvfuser/utils.py +18 -0
- nvfuser/version.py +1 -0
- nvfuser_cu121_torch25-0.2.25.dev20250201.dist-info/LICENSE +976 -0
- nvfuser_cu121_torch25-0.2.25.dev20250201.dist-info/METADATA +16 -0
- nvfuser_cu121_torch25-0.2.25.dev20250201.dist-info/RECORD +242 -0
- nvfuser_cu121_torch25-0.2.25.dev20250201.dist-info/WHEEL +5 -0
- nvfuser_cu121_torch25-0.2.25.dev20250201.dist-info/top_level.txt +1 -0
- 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_
|