diff --git a/3rdparty/flatbuffers/README.md b/3rdparty/flatbuffers/README.md index 26b78f4392..4ea040adc6 100644 --- a/3rdparty/flatbuffers/README.md +++ b/3rdparty/flatbuffers/README.md @@ -1 +1 @@ -Origin: https://github.com/google/flatbuffers/tree/v23.1.21 +Origin: https://github.com/google/flatbuffers/tree/v23.5.9 diff --git a/3rdparty/flatbuffers/include/flatbuffers/array.h b/3rdparty/flatbuffers/include/flatbuffers/array.h index 2ff58c6fb5..f4bfbf054c 100644 --- a/3rdparty/flatbuffers/include/flatbuffers/array.h +++ b/3rdparty/flatbuffers/include/flatbuffers/array.h @@ -17,6 +17,7 @@ #ifndef FLATBUFFERS_ARRAY_H_ #define FLATBUFFERS_ARRAY_H_ +#include #include #include "flatbuffers/base.h" @@ -37,7 +38,7 @@ template class Array { public: typedef uint16_t size_type; typedef typename IndirectHelper::return_type return_type; - typedef VectorConstIterator const_iterator; + typedef VectorConstIterator const_iterator; typedef VectorReverseIterator const_reverse_iterator; // If T is a LE-scalar or a struct (!scalar_tag::value). @@ -158,11 +159,13 @@ template class Array { // Specialization for Array[struct] with access using Offset pointer. // This specialization used by idl_gen_text.cpp. -template class Array, length> { +template class OffsetT> +class Array, length> { static_assert(flatbuffers::is_same::value, "unexpected type T"); public: typedef const void *return_type; + typedef uint16_t size_type; const uint8_t *Data() const { return data_; } diff --git a/3rdparty/flatbuffers/include/flatbuffers/base.h b/3rdparty/flatbuffers/include/flatbuffers/base.h index 86688cc6e4..ac8db356a4 100644 --- a/3rdparty/flatbuffers/include/flatbuffers/base.h +++ b/3rdparty/flatbuffers/include/flatbuffers/base.h @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -139,8 +140,8 @@ #endif // !defined(FLATBUFFERS_LITTLEENDIAN) #define FLATBUFFERS_VERSION_MAJOR 23 -#define FLATBUFFERS_VERSION_MINOR 1 -#define FLATBUFFERS_VERSION_REVISION 21 +#define FLATBUFFERS_VERSION_MINOR 5 +#define FLATBUFFERS_VERSION_REVISION 9 #define FLATBUFFERS_STRING_EXPAND(X) #X #define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X) namespace flatbuffers { @@ -233,12 +234,17 @@ namespace flatbuffers { } #define FLATBUFFERS_HAS_STRING_VIEW 1 // Check for absl::string_view - #elif __has_include("absl/strings/string_view.h") - #include "absl/strings/string_view.h" - namespace flatbuffers { - typedef absl::string_view string_view; - } - #define FLATBUFFERS_HAS_STRING_VIEW 1 + #elif __has_include("absl/strings/string_view.h") && \ + __has_include("absl/base/config.h") && \ + (__cplusplus >= 201411) + #include "absl/base/config.h" + #if !defined(ABSL_USES_STD_STRING_VIEW) + #include "absl/strings/string_view.h" + namespace flatbuffers { + typedef absl::string_view string_view; + } + #define FLATBUFFERS_HAS_STRING_VIEW 1 + #endif #endif #endif // __has_include #endif // !FLATBUFFERS_HAS_STRING_VIEW @@ -318,9 +324,11 @@ namespace flatbuffers { // Also, using a consistent offset type maintains compatibility of serialized // offset values between 32bit and 64bit systems. typedef uint32_t uoffset_t; +typedef uint64_t uoffset64_t; // Signed offsets for references that can go in both directions. typedef int32_t soffset_t; +typedef int64_t soffset64_t; // Offset/index used in v-tables, can be changed to uint8_t in // format forks to save a bit of space if desired. @@ -329,7 +337,8 @@ typedef uint16_t voffset_t; typedef uintmax_t largest_scalar_t; // In 32bits, this evaluates to 2GB - 1 -#define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(::flatbuffers::soffset_t) * 8 - 1)) - 1) +#define FLATBUFFERS_MAX_BUFFER_SIZE std::numeric_limits<::flatbuffers::soffset_t>::max() +#define FLATBUFFERS_MAX_64_BUFFER_SIZE std::numeric_limits<::flatbuffers::soffset64_t>::max() // The minimum size buffer that can be a valid flatbuffer. // Includes the offset to the root table (uoffset_t), the offset to the vtable diff --git a/3rdparty/flatbuffers/include/flatbuffers/buffer.h b/3rdparty/flatbuffers/include/flatbuffers/buffer.h index e26a153c3f..94d4f7903b 100644 --- a/3rdparty/flatbuffers/include/flatbuffers/buffer.h +++ b/3rdparty/flatbuffers/include/flatbuffers/buffer.h @@ -25,14 +25,33 @@ namespace flatbuffers { // Wrapper for uoffset_t to allow safe template specialization. // Value is allowed to be 0 to indicate a null object (see e.g. AddOffset). -template struct Offset { - uoffset_t o; +template struct Offset { + // The type of offset to use. + typedef uoffset_t offset_type; + + offset_type o; Offset() : o(0) {} - Offset(uoffset_t _o) : o(_o) {} - Offset Union() const { return Offset(o); } + Offset(const offset_type _o) : o(_o) {} + Offset<> Union() const { return o; } bool IsNull() const { return !o; } }; +// Wrapper for uoffset64_t Offsets. +template struct Offset64 { + // The type of offset to use. + typedef uoffset64_t offset_type; + + offset_type o; + Offset64() : o(0) {} + Offset64(const offset_type offset) : o(offset) {} + Offset64<> Union() const { return o; } + bool IsNull() const { return !o; } +}; + +// Litmus check for ensuring the Offsets are the expected size. +static_assert(sizeof(Offset<>) == 4, "Offset has wrong size"); +static_assert(sizeof(Offset64<>) == 8, "Offset64 has wrong size"); + inline void EndianCheck() { int endiantest = 1; // If this fails, see FLATBUFFERS_LITTLEENDIAN above. @@ -75,35 +94,59 @@ template struct IndirectHelper { typedef T return_type; typedef T mutable_return_type; static const size_t element_stride = sizeof(T); - static return_type Read(const uint8_t *p, uoffset_t i) { + + static return_type Read(const uint8_t *p, const size_t i) { return EndianScalar((reinterpret_cast(p))[i]); } - static return_type Read(uint8_t *p, uoffset_t i) { - return Read(const_cast(p), i); + static mutable_return_type Read(uint8_t *p, const size_t i) { + return reinterpret_cast( + Read(const_cast(p), i)); } }; -template struct IndirectHelper> { + +// For vector of Offsets. +template class OffsetT> +struct IndirectHelper> { typedef const T *return_type; typedef T *mutable_return_type; - static const size_t element_stride = sizeof(uoffset_t); - static return_type Read(const uint8_t *p, uoffset_t i) { - p += i * sizeof(uoffset_t); - return reinterpret_cast(p + ReadScalar(p)); + typedef typename OffsetT::offset_type offset_type; + static const offset_type element_stride = sizeof(offset_type); + + static return_type Read(const uint8_t *const p, const offset_type i) { + // Offsets are relative to themselves, so first update the pointer to + // point to the offset location. + const uint8_t *const offset_location = p + i * element_stride; + + // Then read the scalar value of the offset (which may be 32 or 64-bits) and + // then determine the relative location from the offset location. + return reinterpret_cast( + offset_location + ReadScalar(offset_location)); } - static mutable_return_type Read(uint8_t *p, uoffset_t i) { - p += i * sizeof(uoffset_t); - return reinterpret_cast(p + ReadScalar(p)); + static mutable_return_type Read(uint8_t *const p, const offset_type i) { + // Offsets are relative to themselves, so first update the pointer to + // point to the offset location. + uint8_t *const offset_location = p + i * element_stride; + + // Then read the scalar value of the offset (which may be 32 or 64-bits) and + // then determine the relative location from the offset location. + return reinterpret_cast( + offset_location + ReadScalar(offset_location)); } }; + +// For vector of structs. template struct IndirectHelper { typedef const T *return_type; typedef T *mutable_return_type; static const size_t element_stride = sizeof(T); - static return_type Read(const uint8_t *p, uoffset_t i) { - return reinterpret_cast(p + i * sizeof(T)); + + static return_type Read(const uint8_t *const p, const size_t i) { + // Structs are stored inline, relative to the first struct pointer. + return reinterpret_cast(p + i * element_stride); } - static mutable_return_type Read(uint8_t *p, uoffset_t i) { - return reinterpret_cast(p + i * sizeof(T)); + static mutable_return_type Read(uint8_t *const p, const size_t i) { + // Structs are stored inline, relative to the first struct pointer. + return reinterpret_cast(p + i * element_stride); } }; @@ -130,23 +173,25 @@ inline bool BufferHasIdentifier(const void *buf, const char *identifier, /// @cond FLATBUFFERS_INTERNAL // Helpers to get a typed pointer to the root object contained in the buffer. template T *GetMutableRoot(void *buf) { + if (!buf) return nullptr; EndianCheck(); return reinterpret_cast( reinterpret_cast(buf) + EndianScalar(*reinterpret_cast(buf))); } -template T *GetMutableSizePrefixedRoot(void *buf) { - return GetMutableRoot(reinterpret_cast(buf) + - sizeof(uoffset_t)); +template +T *GetMutableSizePrefixedRoot(void *buf) { + return GetMutableRoot(reinterpret_cast(buf) + sizeof(SizeT)); } template const T *GetRoot(const void *buf) { return GetMutableRoot(const_cast(buf)); } -template const T *GetSizePrefixedRoot(const void *buf) { - return GetRoot(reinterpret_cast(buf) + sizeof(uoffset_t)); +template +const T *GetSizePrefixedRoot(const void *buf) { + return GetRoot(reinterpret_cast(buf) + sizeof(SizeT)); } } // namespace flatbuffers diff --git a/3rdparty/flatbuffers/include/flatbuffers/flatbuffer_builder.h b/3rdparty/flatbuffers/include/flatbuffers/flatbuffer_builder.h index a1d3d60a79..ed932cd9cc 100644 --- a/3rdparty/flatbuffers/include/flatbuffers/flatbuffer_builder.h +++ b/3rdparty/flatbuffers/include/flatbuffers/flatbuffer_builder.h @@ -18,12 +18,15 @@ #define FLATBUFFERS_FLATBUFFER_BUILDER_H_ #include +#include #include #include +#include #include "flatbuffers/allocator.h" #include "flatbuffers/array.h" #include "flatbuffers/base.h" +#include "flatbuffers/buffer.h" #include "flatbuffers/buffer_ref.h" #include "flatbuffers/default_allocator.h" #include "flatbuffers/detached_buffer.h" @@ -40,8 +43,9 @@ namespace flatbuffers { // Converts a Field ID to a virtual table offset. inline voffset_t FieldIndexToOffset(voffset_t field_id) { // Should correspond to what EndTable() below builds up. - const int fixed_fields = 2; // Vtable size and Object Size. - return static_cast((field_id + fixed_fields) * sizeof(voffset_t)); + const voffset_t fixed_fields = + 2 * sizeof(voffset_t); // Vtable size and Object Size. + return fixed_fields + field_id * sizeof(voffset_t); } template> @@ -68,8 +72,13 @@ T *data(std::vector &v) { /// `PushElement`/`AddElement`/`EndTable`, or the builtin `CreateString`/ /// `CreateVector` functions. Do this is depth-first order to build up a tree to /// the root. `Finish()` wraps up the buffer ready for transport. -class FlatBufferBuilder { +template class FlatBufferBuilderImpl { public: + // This switches the size type of the builder, based on if its 64-bit aware + // (uoffset64_t) or not (uoffset_t). + typedef + typename std::conditional::type SizeT; + /// @brief Default constructor for FlatBufferBuilder. /// @param[in] initial_size The initial size of the buffer, in bytes. Defaults /// to `1024`. @@ -81,13 +90,16 @@ class FlatBufferBuilder { /// minimum alignment upon reallocation. Only needed if you intend to store /// types with custom alignment AND you wish to read the buffer in-place /// directly after creation. - explicit FlatBufferBuilder( + explicit FlatBufferBuilderImpl( size_t initial_size = 1024, Allocator *allocator = nullptr, bool own_allocator = false, size_t buffer_minalign = AlignOf()) - : buf_(initial_size, allocator, own_allocator, buffer_minalign), + : buf_(initial_size, allocator, own_allocator, buffer_minalign, + static_cast(Is64Aware ? FLATBUFFERS_MAX_64_BUFFER_SIZE + : FLATBUFFERS_MAX_BUFFER_SIZE)), num_field_loc(0), max_voffset_(0), + length_of_64_bit_region_(0), nested(false), finished(false), minalign_(1), @@ -98,10 +110,13 @@ class FlatBufferBuilder { } /// @brief Move constructor for FlatBufferBuilder. - FlatBufferBuilder(FlatBufferBuilder &&other) noexcept - : buf_(1024, nullptr, false, AlignOf()), + FlatBufferBuilderImpl(FlatBufferBuilderImpl &&other) noexcept + : buf_(1024, nullptr, false, AlignOf(), + static_cast(Is64Aware ? FLATBUFFERS_MAX_64_BUFFER_SIZE + : FLATBUFFERS_MAX_BUFFER_SIZE)), num_field_loc(0), max_voffset_(0), + length_of_64_bit_region_(0), nested(false), finished(false), minalign_(1), @@ -116,18 +131,19 @@ class FlatBufferBuilder { } /// @brief Move assignment operator for FlatBufferBuilder. - FlatBufferBuilder &operator=(FlatBufferBuilder &&other) noexcept { + FlatBufferBuilderImpl &operator=(FlatBufferBuilderImpl &&other) noexcept { // Move construct a temporary and swap idiom - FlatBufferBuilder temp(std::move(other)); + FlatBufferBuilderImpl temp(std::move(other)); Swap(temp); return *this; } - void Swap(FlatBufferBuilder &other) { + void Swap(FlatBufferBuilderImpl &other) { using std::swap; buf_.swap(other.buf_); swap(num_field_loc, other.num_field_loc); swap(max_voffset_, other.max_voffset_); + swap(length_of_64_bit_region_, other.length_of_64_bit_region_); swap(nested, other.nested); swap(finished, other.finished); swap(minalign_, other.minalign_); @@ -136,7 +152,7 @@ class FlatBufferBuilder { swap(string_pool, other.string_pool); } - ~FlatBufferBuilder() { + ~FlatBufferBuilderImpl() { if (string_pool) delete string_pool; } @@ -153,12 +169,36 @@ class FlatBufferBuilder { nested = false; finished = false; minalign_ = 1; + length_of_64_bit_region_ = 0; if (string_pool) string_pool->clear(); } /// @brief The current size of the serialized buffer, counting from the end. + /// @return Returns an `SizeT` with the current size of the buffer. + SizeT GetSize() const { return buf_.size(); } + + /// @brief The current size of the serialized buffer relative to the end of + /// the 32-bit region. /// @return Returns an `uoffset_t` with the current size of the buffer. - uoffset_t GetSize() const { return buf_.size(); } + template + // Only enable this method for the 64-bit builder, as only that builder is + // concerned with the 32/64-bit boundary, and should be the one to bare any + // run time costs. + typename std::enable_if::type GetSizeRelative32BitRegion() + const { + //[32-bit region][64-bit region] + // [XXXXXXXXXXXXXXXXXXX] GetSize() + // [YYYYYYYYYYYYY] length_of_64_bit_region_ + // [ZZZZ] return size + return static_cast(GetSize() - length_of_64_bit_region_); + } + + template + // Only enable this method for the 32-bit builder. + typename std::enable_if::type GetSizeRelative32BitRegion() + const { + return static_cast(GetSize()); + } /// @brief Get the serialized buffer (after you call `Finish()`). /// @return Returns an `uint8_t` pointer to the FlatBuffer data inside the @@ -270,14 +310,16 @@ class FlatBufferBuilder { } // Write a single aligned scalar to the buffer - template uoffset_t PushElement(T element) { + template + ReturnT PushElement(T element) { AssertScalarT(); Align(sizeof(T)); buf_.push_small(EndianScalar(element)); - return GetSize(); + return CalculateOffset(); } - template uoffset_t PushElement(Offset off) { + template class OffsetT = Offset> + uoffset_t PushElement(OffsetT off) { // Special case for offsets: see ReferTo below. return PushElement(ReferTo(off.o)); } @@ -307,11 +349,16 @@ class FlatBufferBuilder { AddElement(field, ReferTo(off.o), static_cast(0)); } + template void AddOffset(voffset_t field, Offset64 off) { + if (off.IsNull()) return; // Don't store. + AddElement(field, ReferTo(off.o), static_cast(0)); + } + template void AddStruct(voffset_t field, const T *structptr) { if (!structptr) return; // Default, don't store. Align(AlignOf()); buf_.push_small(*structptr); - TrackField(field, GetSize()); + TrackField(field, CalculateOffset()); } void AddStructOffset(voffset_t field, uoffset_t off) { @@ -322,12 +369,29 @@ class FlatBufferBuilder { // This function converts them to be relative to the current location // in the buffer (when stored here), pointing upwards. uoffset_t ReferTo(uoffset_t off) { - // Align to ensure GetSize() below is correct. + // Align to ensure GetSizeRelative32BitRegion() below is correct. Align(sizeof(uoffset_t)); - // Offset must refer to something already in buffer. - const uoffset_t size = GetSize(); + // 32-bit offsets are relative to the tail of the 32-bit region of the + // buffer. For most cases (without 64-bit entities) this is equivalent to + // size of the whole buffer (e.g. GetSize()) + return ReferTo(off, GetSizeRelative32BitRegion()); + } + + uoffset64_t ReferTo(uoffset64_t off) { + // Align to ensure GetSize() below is correct. + Align(sizeof(uoffset64_t)); + // 64-bit offsets are relative to tail of the whole buffer + return ReferTo(off, GetSize()); + } + + template T ReferTo(const T off, const T2 size) { FLATBUFFERS_ASSERT(off && off <= size); - return size - off + static_cast(sizeof(uoffset_t)); + return size - off + static_cast(sizeof(T)); + } + + template T ReferTo(const T off, const T size) { + FLATBUFFERS_ASSERT(off && off <= size); + return size - off + static_cast(sizeof(T)); } void NotNested() { @@ -349,7 +413,7 @@ class FlatBufferBuilder { uoffset_t StartTable() { NotNested(); nested = true; - return GetSize(); + return GetSizeRelative32BitRegion(); } // This finishes one serialized object by generating the vtable if it's a @@ -360,7 +424,9 @@ class FlatBufferBuilder { FLATBUFFERS_ASSERT(nested); // Write the vtable offset, which is the start of any Table. // We fill its value later. - auto vtableoffsetloc = PushElement(0); + // This is relative to the end of the 32-bit region. + const uoffset_t vtable_offset_loc = + static_cast(PushElement(0)); // Write a vtable, which consists entirely of voffset_t elements. // It starts with the number of offsets, followed by a type id, followed // by the offsets themselves. In reverse: @@ -370,7 +436,7 @@ class FlatBufferBuilder { (std::max)(static_cast(max_voffset_ + sizeof(voffset_t)), FieldIndexToOffset(0)); buf_.fill_big(max_voffset_); - auto table_object_size = vtableoffsetloc - start; + const uoffset_t table_object_size = vtable_offset_loc - start; // Vtable use 16bit offsets. FLATBUFFERS_ASSERT(table_object_size < 0x10000); WriteScalar(buf_.data() + sizeof(voffset_t), @@ -380,7 +446,8 @@ class FlatBufferBuilder { for (auto it = buf_.scratch_end() - num_field_loc * sizeof(FieldLoc); it < buf_.scratch_end(); it += sizeof(FieldLoc)) { auto field_location = reinterpret_cast(it); - auto pos = static_cast(vtableoffsetloc - field_location->off); + const voffset_t pos = + static_cast(vtable_offset_loc - field_location->off); // If this asserts, it means you've set a field twice. FLATBUFFERS_ASSERT( !ReadScalar(buf_.data() + field_location->id)); @@ -389,7 +456,7 @@ class FlatBufferBuilder { ClearOffsets(); auto vt1 = reinterpret_cast(buf_.data()); auto vt1_size = ReadScalar(vt1); - auto vt_use = GetSize(); + auto vt_use = GetSizeRelative32BitRegion(); // See if we already have generated a vtable with this exact same // layout before. If so, make it point to the old one, remove this one. if (dedup_vtables_) { @@ -400,23 +467,24 @@ class FlatBufferBuilder { auto vt2_size = ReadScalar(vt2); if (vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size)) continue; vt_use = *vt_offset_ptr; - buf_.pop(GetSize() - vtableoffsetloc); + buf_.pop(GetSizeRelative32BitRegion() - vtable_offset_loc); break; } } // If this is a new vtable, remember it. - if (vt_use == GetSize()) { buf_.scratch_push_small(vt_use); } + if (vt_use == GetSizeRelative32BitRegion()) { + buf_.scratch_push_small(vt_use); + } // Fill the vtable offset we created above. - // The offset points from the beginning of the object to where the - // vtable is stored. + // The offset points from the beginning of the object to where the vtable is + // stored. // Offsets default direction is downward in memory for future format // flexibility (storing all vtables at the start of the file). - WriteScalar(buf_.data_at(vtableoffsetloc), + WriteScalar(buf_.data_at(vtable_offset_loc + length_of_64_bit_region_), static_cast(vt_use) - - static_cast(vtableoffsetloc)); - + static_cast(vtable_offset_loc)); nested = false; - return vtableoffsetloc; + return vtable_offset_loc; } FLATBUFFERS_ATTRIBUTE([[deprecated("call the version above instead")]]) @@ -426,14 +494,20 @@ class FlatBufferBuilder { // This checks a required field has been set in a given table that has // just been constructed. - template void Required(Offset table, voffset_t field); + template void Required(Offset table, voffset_t field) { + auto table_ptr = reinterpret_cast(buf_.data_at(table.o)); + bool ok = table_ptr->GetOptionalFieldOffset(field) != 0; + // If this fails, the caller will show what field needs to be set. + FLATBUFFERS_ASSERT(ok); + (void)ok; + } uoffset_t StartStruct(size_t alignment) { Align(alignment); - return GetSize(); + return GetSizeRelative32BitRegion(); } - uoffset_t EndStruct() { return GetSize(); } + uoffset_t EndStruct() { return GetSizeRelative32BitRegion(); } void ClearOffsets() { buf_.scratch_pop(num_field_loc * sizeof(FieldLoc)); @@ -442,15 +516,18 @@ class FlatBufferBuilder { } // Aligns such that when "len" bytes are written, an object can be written - // after it with "alignment" without padding. + // after it (forward in the buffer) with "alignment" without padding. void PreAlign(size_t len, size_t alignment) { if (len == 0) return; TrackMinAlign(alignment); buf_.fill(PaddingBytes(GetSize() + len, alignment)); } - template void PreAlign(size_t len) { - AssertScalarT(); - PreAlign(len, AlignOf()); + + // Aligns such than when "len" bytes are written, an object of type `AlignT` + // can be written after it (forward in the buffer) without padding. + template void PreAlign(size_t len) { + AssertScalarT(); + PreAlign(len, AlignOf()); } /// @endcond @@ -458,34 +535,35 @@ class FlatBufferBuilder { /// @param[in] str A const char pointer to the data to be stored as a string. /// @param[in] len The number of bytes that should be stored from `str`. /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(const char *str, size_t len) { - NotNested(); - PreAlign(len + 1); // Always 0-terminated. - buf_.fill(1); - PushBytes(reinterpret_cast(str), len); - PushElement(static_cast(len)); - return Offset(GetSize()); + template class OffsetT = Offset> + OffsetT CreateString(const char *str, size_t len) { + CreateStringImpl(str, len); + return OffsetT( + CalculateOffset::offset_type>()); } /// @brief Store a string in the buffer, which is null-terminated. /// @param[in] str A const char pointer to a C-string to add to the buffer. /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(const char *str) { - return CreateString(str, strlen(str)); + template class OffsetT = Offset> + OffsetT CreateString(const char *str) { + return CreateString(str, strlen(str)); } /// @brief Store a string in the buffer, which is null-terminated. /// @param[in] str A char pointer to a C-string to add to the buffer. /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(char *str) { - return CreateString(str, strlen(str)); + template class OffsetT = Offset> + OffsetT CreateString(char *str) { + return CreateString(str, strlen(str)); } /// @brief Store a string in the buffer, which can contain any binary data. /// @param[in] str A const reference to a std::string to store in the buffer. /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(const std::string &str) { - return CreateString(str.c_str(), str.length()); + template class OffsetT = Offset> + OffsetT CreateString(const std::string &str) { + return CreateString(str.c_str(), str.length()); } // clang-format off @@ -493,8 +571,9 @@ class FlatBufferBuilder { /// @brief Store a string in the buffer, which can contain any binary data. /// @param[in] str A const string_view to copy in to the buffer. /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(flatbuffers::string_view str) { - return CreateString(str.data(), str.size()); + template