diff --git a/include/simdjson/generic/builder/json_builder.h b/include/simdjson/generic/builder/json_builder.h index c0e2c72cc..4b4a4a9ea 100644 --- a/include/simdjson/generic/builder/json_builder.h +++ b/include/simdjson/generic/builder/json_builder.h @@ -100,12 +100,12 @@ simdjson_really_inline constexpr void atom(string_builder &b, const T &t) { constevalutil::consteval_to_quoted_escaped(std::meta::identifier_of(dm)) + ":"); constexpr auto rest_key = std::define_static_string( std::string(",") + constevalutil::consteval_to_quoted_escaped(std::meta::identifier_of(dm)) + ":"); - // Pass size explicitly so we avoid the runtime strlen() in - // append_raw(const char*) — these keys are compile-time constants. + // Pass size as template parameter so memcpy is fully inlined with + // a compile-time-constant size. constexpr size_t first_key_len = std::char_traits::length(first_key); constexpr size_t rest_key_len = std::char_traits::length(rest_key); - if (i == 0) b.append_raw(first_key, first_key_len); - else b.append_raw(rest_key, rest_key_len); + if (i == 0) b.template append_raw_n(first_key); + else b.template append_raw_n(rest_key); atom(b, t.[:dm:]); i++; }; diff --git a/include/simdjson/generic/builder/json_string_builder-inl.h b/include/simdjson/generic/builder/json_string_builder-inl.h index 46ded99ad..7860cfaca 100644 --- a/include/simdjson/generic/builder/json_string_builder-inl.h +++ b/include/simdjson/generic/builder/json_string_builder-inl.h @@ -780,6 +780,14 @@ simdjson_inline void string_builder::append_raw(const char *str, position += len; } } + +template +simdjson_inline void string_builder::append_raw_n(const char *str) noexcept { + if (capacity_check(N)) { + std::memcpy(buffer.get() + position, str, N); + position += N; + } +} #if SIMDJSON_SUPPORTS_CONCEPTS // Support for optional types (std::optional, etc.) template diff --git a/include/simdjson/generic/builder/json_string_builder.h b/include/simdjson/generic/builder/json_string_builder.h index 39196d182..187a76a16 100644 --- a/include/simdjson/generic/builder/json_string_builder.h +++ b/include/simdjson/generic/builder/json_string_builder.h @@ -185,6 +185,15 @@ requires (!std::is_convertible::value && !concepts::optiona * There is no UTF-8 validation. */ simdjson_inline void append_raw(const char *str, size_t len) noexcept; + + /** + * Append exactly N characters from str. The length is a template parameter + * so the compiler can fully inline the memcpy with a compile-time-constant + * size, avoiding the libc call. Used for compile-time-constant keys in the + * reflection struct atom. + */ + template + simdjson_inline void append_raw_n(const char *str) noexcept; #if SIMDJSON_EXCEPTIONS /** * Creates an std::string from the written JSON buffer.