5#ifndef SIMDJSON_GENERIC_BUILDER_H
7#ifndef SIMDJSON_CONDITIONAL_INCLUDE
8#define SIMDJSON_GENERIC_STRING_BUILDER_H
9#include "simdjson/generic/builder/json_string_builder.h"
10#include "simdjson/concepts.h"
12#if SIMDJSON_STATIC_REFLECTION
25namespace SIMDJSON_IMPLEMENTATION {
29 requires(concepts::container_but_not_string<T> && !require_custom_serialization<T>)
30constexpr void atom(string_builder &b,
const T &t) {
40 for (; it != end; ++it) {
48 requires(std::is_same_v<T, std::string> ||
49 std::is_same_v<T, std::string_view> ||
50 std::is_same_v<T, const char *> ||
51 std::is_same_v<T, char>)
52constexpr void atom(string_builder &b,
const T &t) {
53 b.escape_and_append_with_quotes(t);
56template <concepts::
string_view_keyed_map T>
57 requires(!require_custom_serialization<T>)
58constexpr void atom(string_builder &b,
const T &m) {
65 for (
const auto& [key, value] : m) {
71 b.escape_and_append_with_quotes(key);
79template<
typename number_type,
80 typename =
typename std::enable_if<std::is_arithmetic<number_type>::value && !std::is_same_v<number_type, char>>::type>
81constexpr void atom(string_builder &b,
const number_type t) {
86 requires(std::is_class_v<T> && !concepts::container_but_not_string<T> &&
87 !concepts::string_view_keyed_map<T> &&
88 !concepts::optional_type<T> &&
89 !concepts::smart_pointer<T> &&
90 !concepts::appendable_containers<T> &&
91 !std::is_same_v<T, std::string> &&
92 !std::is_same_v<T, std::string_view> &&
93 !std::is_same_v<T, const char*> &&
94 !std::is_same_v<T, char> && !require_custom_serialization<T>)
95constexpr void atom(string_builder &b,
const T &t) {
98 template for (
constexpr auto dm : std::define_static_array(std::meta::nonstatic_data_members_of(^^T, std::meta::access_context::unchecked()))) {
101 constexpr auto key = std::define_static_string(constevalutil::consteval_to_quoted_escaped(std::meta::identifier_of(dm)));
111template <concepts::optional_type T>
112 requires(!require_custom_serialization<T>)
113constexpr void atom(string_builder &b,
const T &opt) {
115 atom(b, opt.value());
117 b.append_raw(
"null");
122template <concepts::smart_po
inter T>
123 requires(!require_custom_serialization<T>)
124constexpr void atom(string_builder &b,
const T &ptr) {
128 b.append_raw(
"null");
134 requires(std::is_enum_v<T> && !require_custom_serialization<T>)
135void atom(string_builder &b,
const T &e) {
136#if SIMDJSON_STATIC_REFLECTION
137 constexpr auto enumerators = std::define_static_array(std::meta::enumerators_of(^^T));
138 template for (
constexpr auto enum_val : enumerators) {
139 constexpr auto enum_str = std::define_static_string(constevalutil::consteval_to_quoted_escaped(std::meta::identifier_of(enum_val)));
140 if (e == [:enum_val:]) {
141 b.append_raw(enum_str);
146 atom(b,
static_cast<std::underlying_type_t<T>
>(e));
149 atom(b,
static_cast<std::underlying_type_t<T>
>(e));
154template <concepts::appendable_containers T>
155 requires(!concepts::container_but_not_string<T> && !concepts::string_view_keyed_map<T> &&
156 !concepts::optional_type<T> && !concepts::smart_pointer<T> &&
157 !std::is_same_v<T, std::string> &&
158 !std::is_same_v<T, std::string_view> && !std::is_same_v<T, const char*> && !require_custom_serialization<T>)
159constexpr void atom(string_builder &b,
const T &container) {
160 if (container.empty()) {
166 for (
const auto& item : container) {
178 requires(std::is_arithmetic_v<T> && !std::is_same_v<T, char>)
179void append(string_builder &b,
const T &t) {
184 requires(std::is_same_v<T, std::string> ||
185 std::is_same_v<T, std::string_view> ||
186 std::is_same_v<T, const char *> ||
187 std::is_same_v<T, char>)
188void append(string_builder &b,
const T &t) {
192template <concepts::optional_type T>
193 requires(!require_custom_serialization<T>)
194void append(string_builder &b,
const T &t) {
198template <concepts::smart_po
inter T>
199 requires(!require_custom_serialization<T>)
200void append(string_builder &b,
const T &t) {
204template <concepts::appendable_containers T>
205 requires(!concepts::container_but_not_string<T> && !concepts::string_view_keyed_map<T> &&
206 !concepts::optional_type<T> && !concepts::smart_pointer<T> &&
207 !std::is_same_v<T, std::string> &&
208 !std::is_same_v<T, std::string_view> && !std::is_same_v<T, const char*> && !require_custom_serialization<T>)
209void append(string_builder &b,
const T &t) {
213template <concepts::
string_view_keyed_map T>
214 requires(!require_custom_serialization<T>)
215void append(string_builder &b,
const T &t) {
221 requires(std::is_class_v<Z> && !concepts::container_but_not_string<Z> &&
222 !concepts::string_view_keyed_map<Z> &&
223 !concepts::optional_type<Z> &&
224 !concepts::smart_pointer<Z> &&
225 !concepts::appendable_containers<Z> &&
226 !std::is_same_v<Z, std::string> &&
227 !std::is_same_v<Z, std::string_view> &&
228 !std::is_same_v<Z, const char*> &&
229 !std::is_same_v<Z, char> && !require_custom_serialization<Z>)
230void append(string_builder &b,
const Z &z) {
233 template for (
constexpr auto dm : std::define_static_array(std::meta::nonstatic_data_members_of(^^Z, std::meta::access_context::unchecked()))) {
236 constexpr auto key = std::define_static_string(constevalutil::consteval_to_quoted_escaped(std::meta::identifier_of(dm)));
247 requires(concepts::container_but_not_string<Z> && !require_custom_serialization<Z>)
248void append(string_builder &b,
const Z &z) {
258 for (; it != end; ++it) {
266 requires (require_custom_serialization<Z>)
267void append(string_builder &b,
const Z &z) {
273simdjson_warn_unused simdjson_result<std::string>
to_json_string(
const Z &z,
size_t initial_capacity = string_builder::DEFAULT_INITIAL_CAPACITY) {
274 string_builder b(initial_capacity);
277 if(
auto e = b.view().get(s); e) {
return e; }
278 return std::string(s);
282simdjson_warn_unused simdjson_error to_json(
const Z &z, std::string &s,
size_t initial_capacity = string_builder::DEFAULT_INITIAL_CAPACITY) {
283 string_builder b(initial_capacity);
285 std::string_view view;
286 if(
auto e = b.view().get(view); e) {
return e; }
292string_builder& operator<<(string_builder& b,
const Z& z) {
298template<constevalutil::fixed_string... FieldNames,
typename T>
299 requires(std::is_class_v<T> && (
sizeof...(FieldNames) > 0))
300void extract_from(string_builder &b,
const T &obj) {
302 auto should_extract = [](std::string_view field_name)
constexpr ->
bool {
303 return ((FieldNames.view() == field_name) || ...);
310 template for (
constexpr auto mem : std::define_static_array(
311 std::meta::nonstatic_data_members_of(^^T, std::meta::access_context::unchecked()))) {
313 if constexpr (std::meta::is_public(mem)) {
314 constexpr std::string_view key = std::define_static_string(std::meta::identifier_of(mem));
317 if constexpr (should_extract(key)) {
324 constexpr auto quoted_key = std::define_static_string(constevalutil::consteval_to_quoted_escaped(std::meta::identifier_of(mem)));
325 b.append_raw(quoted_key);
329 atom(b, obj.[:mem:]);
337template<constevalutil::fixed_string... FieldNames,
typename T>
338 requires(std::is_class_v<T> && (
sizeof...(FieldNames) > 0))
339simdjson_warn_unused simdjson_result<std::string> extract_from(
const T &obj,
size_t initial_capacity = string_builder::DEFAULT_INITIAL_CAPACITY) {
340 string_builder b(initial_capacity);
341 extract_from<FieldNames...>(b, obj);
343 if(
auto e = b.view().get(s); e) {
return e; }
344 return std::string(s);
351simdjson_warn_unused simdjson_result<std::string> to_json(
const Z &z,
size_t initial_capacity = SIMDJSON_IMPLEMENTATION::builder::string_builder::DEFAULT_INITIAL_CAPACITY) {
352 SIMDJSON_IMPLEMENTATION::builder::string_builder b(initial_capacity);
353 SIMDJSON_IMPLEMENTATION::builder::append(b, z);
355 if(
auto e = b.view().get(s); e) {
return e; }
356 return std::string(s);
359simdjson_warn_unused simdjson_error to_json(
const Z &z, std::string &s,
size_t initial_capacity = SIMDJSON_IMPLEMENTATION::builder::string_builder::DEFAULT_INITIAL_CAPACITY) {
360 SIMDJSON_IMPLEMENTATION::builder::string_builder b(initial_capacity);
361 SIMDJSON_IMPLEMENTATION::builder::append(b, z);
362 std::string_view view;
363 if(
auto e = b.view().get(view); e) {
return e; }
368template<constevalutil::fixed_string... FieldNames,
typename T>
369 requires(std::is_class_v<T> && (
sizeof...(FieldNames) > 0))
370simdjson_warn_unused simdjson_result<std::string> extract_from(
const T &obj,
size_t initial_capacity = SIMDJSON_IMPLEMENTATION::builder::string_builder::DEFAULT_INITIAL_CAPACITY) {
371 SIMDJSON_IMPLEMENTATION::builder::string_builder b(initial_capacity);
372 SIMDJSON_IMPLEMENTATION::builder::extract_from<FieldNames...>(b, obj);
374 if(
auto e = b.view().get(s); e) {
return e; }
375 return std::string(s);
The top level simdjson namespace, containing everything the library provides.
simdjson_result< std::string_view > to_json_string(SIMDJSON_IMPLEMENTATION::ondemand::document &x) noexcept
Create a string-view instance out of a document instance.