mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5be57348c4 | |||
| 8955c2c6d5 | |||
| 73e69a5e84 |
@@ -22,4 +22,4 @@ jobs:
|
|||||||
- name: Build
|
- name: Build
|
||||||
run: cmake --build build -j=2
|
run: cmake --build build -j=2
|
||||||
- name: Test
|
- name: Test
|
||||||
run: ctest --output-on-failure --test-dir build
|
run: ctest --output-on-failure --test-dir build
|
||||||
|
|||||||
+38
-7
@@ -167,13 +167,37 @@ if(MSVC)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(SIMDJSON_STATIC_REFLECTION)
|
if(SIMDJSON_STATIC_REFLECTION)
|
||||||
|
|
||||||
|
|
||||||
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION MATCHES "^21")
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${CMAKE_CXX_COMPILER} --version
|
||||||
|
OUTPUT_VARIABLE CLANG_VERSION_OUTPUT
|
||||||
|
ERROR_VARIABLE CLANG_VERSION_ERROR
|
||||||
|
RESULT_VARIABLE CLANG_VERSION_RESULT
|
||||||
|
)
|
||||||
|
if(CLANG_VERSION_RESULT EQUAL 0 AND CLANG_VERSION_OUTPUT MATCHES "https://github.com/bloomberg/clang-p2996.git")
|
||||||
|
set(IS_BLOOMBERG_P2996_CLANG ON)
|
||||||
|
message(STATUS "Using Bloomberg P2996 Clang fork")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# We would like to require C++26, but no compiler supports that!
|
# We would like to require C++26, but no compiler supports that!
|
||||||
# This is a hack:
|
# This is a hack:
|
||||||
|
if(IS_BLOOMBERG_P2996_CLANG)
|
||||||
simdjson_add_props(
|
simdjson_add_props(
|
||||||
target_compile_options PUBLIC
|
target_compile_options PUBLIC
|
||||||
-freflection -fexpansion-statements -stdlib=libc++ -std=c++26
|
-freflection -fexpansion-statements -stdlib=libc++ -std=c++26
|
||||||
)
|
)
|
||||||
|
else()
|
||||||
|
simdjson_add_props(
|
||||||
|
target_compile_options PUBLIC
|
||||||
|
-freflection -std=c++26
|
||||||
|
)
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
simdjson_add_props(target_compile_features PUBLIC cxx_std_11)
|
simdjson_add_props(target_compile_features PUBLIC cxx_std_11)
|
||||||
endif()
|
endif()
|
||||||
@@ -387,18 +411,25 @@ add_subdirectory(fuzz)
|
|||||||
#
|
#
|
||||||
# Source files should be just ASCII
|
# Source files should be just ASCII
|
||||||
#
|
#
|
||||||
find_program(FIND find)
|
find_program(FIND_CMD find)
|
||||||
find_program(FILE file)
|
find_program(FILE_CMD file)
|
||||||
find_program(GREP grep)
|
find_program(GREP_CMD grep)
|
||||||
if(FIND AND FILE AND GREP)
|
if(FIND_CMD AND FILE_CMD AND GREP_CMD)
|
||||||
add_test(
|
add_test(
|
||||||
NAME just_ascii
|
NAME just_ascii
|
||||||
COMMAND sh -c "\
|
COMMAND sh -c "\
|
||||||
${FIND} include src windows tools singleheader tests examples benchmark \
|
non_ascii=$(${FIND_CMD} include src windows tools singleheader tests examples benchmark \
|
||||||
-path benchmark/checkperf-reference -prune -name '*.h' -o -name '*.cpp' \
|
-path benchmark/checkperf-reference -prune -name '*.h' -o -name '*.cpp' \
|
||||||
-type f -exec ${FILE} '{}' \; | ${GREP} -qv ASCII || exit 0 && exit 1"
|
-type f -exec ${FILE_CMD} '{}' \; | ${GREP_CMD} -v ASCII); \
|
||||||
|
if [ -n \"$non_ascii\" ]; then \
|
||||||
|
echo 'The following files contain non-ASCII characters:'; \
|
||||||
|
echo \"$non_ascii\"; \
|
||||||
|
exit 1; \
|
||||||
|
fi"
|
||||||
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
|
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
|
||||||
)
|
)
|
||||||
|
else()
|
||||||
|
message(WARNING "just_ascii test disabled because required tools were not found: find='${FIND_CMD}', file='${FILE_CMD}', grep='${GREP_CMD}'")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace partial_tweets {
|
|||||||
// {
|
// {
|
||||||
// "created_at": "Sun Aug 31 00:29:15 +0000 2014",
|
// "created_at": "Sun Aug 31 00:29:15 +0000 2014",
|
||||||
// "id": 505874924095815700,
|
// "id": 505874924095815700,
|
||||||
// "text": "@aym0566x \n\n名前:前田あゆみ\n第一印象:なんか怖っ!\n今の印象:とりあえずキモい。噛み合わない\n好きなところ:ぶすでキモいとこ😋✨✨\n思い出:んーーー、ありすぎ😊❤️\nLINE交換できる?:あぁ……ごめん✋\nトプ画をみて:照れますがな😘✨\n一言:お前は一生もんのダチ💖",
|
// "text": "@aym0566x ...",
|
||||||
// "in_reply_to_status_id": null,
|
// "in_reply_to_status_id": null,
|
||||||
// "user": {
|
// "user": {
|
||||||
// "id": 1186275104,
|
// "id": 1186275104,
|
||||||
|
|||||||
+2
-4
@@ -379,6 +379,8 @@ tracking explicitly potential programming mistakes. Thus you should not relying
|
|||||||
size (`sizeof`) of our data structures to be constant: they may change depending on the
|
size (`sizeof`) of our data structures to be constant: they may change depending on the
|
||||||
compiler settings.
|
compiler settings.
|
||||||
|
|
||||||
|
When `SIMDJSON_DEVELOPMENT_CHECKS` is set at compile time, the global variable `simdjson_development_checks_enabled` is defined as true. It is false otherwise.
|
||||||
|
|
||||||
Once your code has been tested, you can then run it in
|
Once your code has been tested, you can then run it in
|
||||||
Release mode: under Visual Studio, it means having the `_DEBUG` macro undefined, and, for other
|
Release mode: under Visual Studio, it means having the `_DEBUG` macro undefined, and, for other
|
||||||
compilers, it means setting `__OPTIMIZE__` to a positive integer. You can also forcefully
|
compilers, it means setting `__OPTIMIZE__` to a positive integer. You can also forcefully
|
||||||
@@ -1300,10 +1302,6 @@ You can also use the custom `Car` type as part of a template such as `std::vecto
|
|||||||
simdjson::ondemand::parser parser;
|
simdjson::ondemand::parser parser;
|
||||||
simdjson::ondemand::document doc = parser.iterate(json);
|
simdjson::ondemand::document doc = parser.iterate(json);
|
||||||
std::vector<Car> cars(doc);
|
std::vector<Car> cars(doc);
|
||||||
// visual studio users need an explicit call:
|
|
||||||
// std::vector<Car> cars = doc.get<std::vector<Car>>();
|
|
||||||
// because the compiler does not know whether to convert
|
|
||||||
// doc to an unsigned int or to a vector.
|
|
||||||
for(Car& c : cars) {
|
for(Car& c : cars) {
|
||||||
std::cout << c.year << std::endl;
|
std::cout << c.year << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -297,6 +297,15 @@ namespace std {
|
|||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
#endif // SIMDJSON_DEVELOPMENT_CHECKS
|
#endif // SIMDJSON_DEVELOPMENT_CHECKS
|
||||||
|
|
||||||
|
|
||||||
|
// Prevent ODR violations for the simdjson_development_checks_enabled variable.
|
||||||
|
#if SIMDJSON_DEVELOPMENT_CHECKS
|
||||||
|
extern const bool simdjson_development_checks_enabled = true;
|
||||||
|
#else
|
||||||
|
extern const bool simdjson_development_checks_enabled = false;
|
||||||
|
#endif // SIMDJSON_DEVELOPMENT_CHECKS
|
||||||
|
|
||||||
|
|
||||||
// The SIMDJSON_CHECK_EOF macro is a feature flag for the "don't require padding"
|
// The SIMDJSON_CHECK_EOF macro is a feature flag for the "don't require padding"
|
||||||
// feature.
|
// feature.
|
||||||
|
|
||||||
|
|||||||
@@ -266,6 +266,12 @@ consteval std::pair<double, size_t> parse_double(const char *src,
|
|||||||
}
|
}
|
||||||
} // namespace number_parsing
|
} // namespace number_parsing
|
||||||
|
|
||||||
|
consteval auto make_data_member_options(auto&& name_str) {
|
||||||
|
std::meta::data_member_options options{};
|
||||||
|
options.name = std::forward<decltype(name_str)>(name_str);
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
// JSON string may contain embedded nulls, and C++26 reflection does not yet
|
// JSON string may contain embedded nulls, and C++26 reflection does not yet
|
||||||
// support std::string_view as a data member type. As a workaround, we define
|
// support std::string_view as a data member type. As a workaround, we define
|
||||||
// a custom type that holds a const char* and a size.
|
// a custom type that holds a const char* and a size.
|
||||||
@@ -320,7 +326,8 @@ using class_type = type_builder<meta_info...>::constructed_type;
|
|||||||
/**
|
/**
|
||||||
* @brief Variable template for constructing instances with values
|
* @brief Variable template for constructing instances with values
|
||||||
*/
|
*/
|
||||||
template <typename T, auto... Vs> constexpr auto construct_from = T{Vs...};
|
template <typename T, auto... Vs> constexpr T construct_from = T{Vs...};
|
||||||
|
|
||||||
|
|
||||||
// in JSON, there are only a few whitespace characters that are allowed
|
// in JSON, there are only a few whitespace characters that are allowed
|
||||||
// outside of objects, arrays, strings, and numbers.
|
// outside of objects, arrays, strings, and numbers.
|
||||||
@@ -410,7 +417,7 @@ parse_number(std::string_view json,
|
|||||||
std::from_chars(json.data(), json.data() + json.size(), int_value);
|
std::from_chars(json.data(), json.data() + json.size(), int_value);
|
||||||
if (res.ec == std::errc()) {
|
if (res.ec == std::errc()) {
|
||||||
out = int_value;
|
out = int_value;
|
||||||
if ((res.ptr - json.data()) != scope) {
|
if (static_cast<std::size_t>(res.ptr - json.data()) != scope) {
|
||||||
simdjson_consteval_error(
|
simdjson_consteval_error(
|
||||||
"Internal error: cannot agree on the character range of the float");
|
"Internal error: cannot agree on the character range of the float");
|
||||||
}
|
}
|
||||||
@@ -424,7 +431,7 @@ parse_number(std::string_view json,
|
|||||||
std::from_chars(json.data(), json.data() + json.size(), uint_value);
|
std::from_chars(json.data(), json.data() + json.size(), uint_value);
|
||||||
if (res.ec == std::errc()) {
|
if (res.ec == std::errc()) {
|
||||||
out = uint_value;
|
out = uint_value;
|
||||||
if ((res.ptr - json.data()) != scope) {
|
if (static_cast<std::size_t>(res.ptr - json.data()) != scope) {
|
||||||
simdjson_consteval_error(
|
simdjson_consteval_error(
|
||||||
"Internal error: cannot agree on the character range of the float");
|
"Internal error: cannot agree on the character range of the float");
|
||||||
}
|
}
|
||||||
@@ -533,7 +540,7 @@ parse_string(std::string_view json) {
|
|||||||
// present, we have an error (isolated high surrogate), which we
|
// present, we have an error (isolated high surrogate), which we
|
||||||
// tolerate by substituting the substitution_code_point.
|
// tolerate by substituting the substitution_code_point.
|
||||||
if (end - cursor < 6 || *cursor != '\\' ||
|
if (end - cursor < 6 || *cursor != '\\' ||
|
||||||
*(cursor + 1) != 'u' > 0xFFFF) {
|
*(cursor + 1) != 'u') {
|
||||||
code_point = substitution_code_point;
|
code_point = substitution_code_point;
|
||||||
} else { // we have \u following the high surrogate
|
} else { // we have \u following the high surrogate
|
||||||
cursor += 2; // skip \u
|
cursor += 2; // skip \u
|
||||||
@@ -887,10 +894,19 @@ parse_json_array_impl(const std::string_view json) {
|
|||||||
std::size_t count = values.size() - 1;
|
std::size_t count = values.size() - 1;
|
||||||
// We assume all elements have the same type as the first element.
|
// We assume all elements have the same type as the first element.
|
||||||
// However, if the array is heterogeneous, we should use std::variant.
|
// However, if the array is heterogeneous, we should use std::variant.
|
||||||
|
auto elem_type = std::meta::type_of(values[1]);
|
||||||
|
// String literals reflected via reflect_constant_string have type const
|
||||||
|
// char[N], but when passed as template auto parameters they decay to
|
||||||
|
// const char*. Use const char* as the element type so that
|
||||||
|
// construct_from can aggregate-initialize the array.
|
||||||
|
if (std::meta::is_array_type(elem_type) &&
|
||||||
|
std::meta::remove_all_extents(elem_type) == ^^const char) {
|
||||||
|
elem_type = ^^const char *;
|
||||||
|
}
|
||||||
auto array_type = std::meta::substitute(
|
auto array_type = std::meta::substitute(
|
||||||
^^std::array,
|
^^std::array,
|
||||||
{
|
{
|
||||||
std::meta::type_of(values[1]), std::meta::reflect_constant(count)});
|
elem_type, std::meta::reflect_constant(count)});
|
||||||
|
|
||||||
// Create array instance with values
|
// Create array instance with values
|
||||||
values[0] = array_type;
|
values[0] = array_type;
|
||||||
@@ -957,8 +973,7 @@ parse_json_object_impl(std::string_view json) {
|
|||||||
simdjson_consteval_error("Expected '}'");
|
simdjson_consteval_error("Expected '}'");
|
||||||
}
|
}
|
||||||
cursor += object_size;
|
cursor += object_size;
|
||||||
auto dms = std::meta::data_member_spec(std::meta::type_of(parsed),
|
auto dms = std::meta::data_member_spec(std::meta::type_of(parsed), make_data_member_options(field_name));
|
||||||
{.name = field_name});
|
|
||||||
members.push_back(std::meta::reflect_constant(dms));
|
members.push_back(std::meta::reflect_constant(dms));
|
||||||
values.push_back(parsed);
|
values.push_back(parsed);
|
||||||
|
|
||||||
@@ -967,8 +982,7 @@ parse_json_object_impl(std::string_view json) {
|
|||||||
case '[': {
|
case '[': {
|
||||||
std::string_view value(cursor, end);
|
std::string_view value(cursor, end);
|
||||||
auto [parsed, array_size] = parse_json_array_impl(value);
|
auto [parsed, array_size] = parse_json_array_impl(value);
|
||||||
auto dms = std::meta::data_member_spec(std::meta::type_of(parsed),
|
auto dms = std::meta::data_member_spec(std::meta::type_of(parsed), make_data_member_options(field_name));
|
||||||
{.name = field_name});
|
|
||||||
members.push_back(std::meta::reflect_constant(dms));
|
members.push_back(std::meta::reflect_constant(dms));
|
||||||
values.push_back(parsed);
|
values.push_back(parsed);
|
||||||
if (*(cursor + array_size - 1) != ']') {
|
if (*(cursor + array_size - 1) != ']') {
|
||||||
@@ -989,8 +1003,7 @@ parse_json_object_impl(std::string_view json) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto dms =
|
auto dms =
|
||||||
std::meta::data_member_spec(^^const char *, {
|
std::meta::data_member_spec(^^const char *, make_data_member_options(field_name));
|
||||||
.name = field_name});
|
|
||||||
members.push_back(std::meta::reflect_constant(dms));
|
members.push_back(std::meta::reflect_constant(dms));
|
||||||
values.push_back(std::meta::reflect_constant_string(value));
|
values.push_back(std::meta::reflect_constant_string(value));
|
||||||
break;
|
break;
|
||||||
@@ -1001,8 +1014,7 @@ parse_json_object_impl(std::string_view json) {
|
|||||||
}
|
}
|
||||||
cursor += 4;
|
cursor += 4;
|
||||||
|
|
||||||
auto dms = std::meta::data_member_spec(^^bool, {
|
auto dms = std::meta::data_member_spec(^^bool, make_data_member_options(field_name));
|
||||||
.name = field_name});
|
|
||||||
members.push_back(std::meta::reflect_constant(dms));
|
members.push_back(std::meta::reflect_constant(dms));
|
||||||
values.push_back(std::meta::reflect_constant(true));
|
values.push_back(std::meta::reflect_constant(true));
|
||||||
break;
|
break;
|
||||||
@@ -1013,8 +1025,7 @@ parse_json_object_impl(std::string_view json) {
|
|||||||
}
|
}
|
||||||
cursor += 5;
|
cursor += 5;
|
||||||
|
|
||||||
auto dms = std::meta::data_member_spec(^^bool, {
|
auto dms = std::meta::data_member_spec(^^bool, make_data_member_options(field_name));
|
||||||
.name = field_name});
|
|
||||||
members.push_back(std::meta::reflect_constant(dms));
|
members.push_back(std::meta::reflect_constant(dms));
|
||||||
values.push_back(std::meta::reflect_constant(false));
|
values.push_back(std::meta::reflect_constant(false));
|
||||||
break;
|
break;
|
||||||
@@ -1025,9 +1036,7 @@ parse_json_object_impl(std::string_view json) {
|
|||||||
}
|
}
|
||||||
cursor += 4;
|
cursor += 4;
|
||||||
|
|
||||||
auto dms = std::meta::data_member_spec(^^std::nullptr_t,
|
auto dms = std::meta::data_member_spec(^^std::nullptr_t, make_data_member_options(field_name));
|
||||||
{
|
|
||||||
.name = field_name});
|
|
||||||
members.push_back(std::meta::reflect_constant(dms));
|
members.push_back(std::meta::reflect_constant(dms));
|
||||||
values.push_back(std::meta::reflect_constant(nullptr));
|
values.push_back(std::meta::reflect_constant(nullptr));
|
||||||
break;
|
break;
|
||||||
@@ -1051,22 +1060,19 @@ parse_json_object_impl(std::string_view json) {
|
|||||||
if (std::holds_alternative<int64_t>(out)) {
|
if (std::holds_alternative<int64_t>(out)) {
|
||||||
int64_t int_value = std::get<int64_t>(out);
|
int64_t int_value = std::get<int64_t>(out);
|
||||||
auto dms =
|
auto dms =
|
||||||
std::meta::data_member_spec(^^int64_t, {
|
std::meta::data_member_spec(^^int64_t, make_data_member_options(field_name));
|
||||||
.name = field_name});
|
|
||||||
members.push_back(std::meta::reflect_constant(dms));
|
members.push_back(std::meta::reflect_constant(dms));
|
||||||
values.push_back(std::meta::reflect_constant(int_value));
|
values.push_back(std::meta::reflect_constant(int_value));
|
||||||
} else if (std::holds_alternative<uint64_t>(out)) {
|
} else if (std::holds_alternative<uint64_t>(out)) {
|
||||||
uint64_t uint_value = std::get<uint64_t>(out);
|
uint64_t uint_value = std::get<uint64_t>(out);
|
||||||
auto dms =
|
auto dms =
|
||||||
std::meta::data_member_spec(^^uint64_t, {
|
std::meta::data_member_spec(^^uint64_t, make_data_member_options(field_name));
|
||||||
.name = field_name});
|
|
||||||
members.push_back(std::meta::reflect_constant(dms));
|
members.push_back(std::meta::reflect_constant(dms));
|
||||||
values.push_back(std::meta::reflect_constant(uint_value));
|
values.push_back(std::meta::reflect_constant(uint_value));
|
||||||
} else {
|
} else {
|
||||||
double float_value = std::get<double>(out);
|
double float_value = std::get<double>(out);
|
||||||
auto dms =
|
auto dms =
|
||||||
std::meta::data_member_spec(^^double, {
|
std::meta::data_member_spec(^^double, make_data_member_options(field_name));
|
||||||
.name = field_name});
|
|
||||||
members.push_back(std::meta::reflect_constant(dms));
|
members.push_back(std::meta::reflect_constant(dms));
|
||||||
values.push_back(std::meta::reflect_constant(float_value));
|
values.push_back(std::meta::reflect_constant(float_value));
|
||||||
}
|
}
|
||||||
@@ -1111,16 +1117,11 @@ template <constevalutil::fixed_string json_str> consteval auto parse_json() {
|
|||||||
"Only JSON objects and arrays are supported at the top level, this "
|
"Only JSON objects and arrays are supported at the top level, this "
|
||||||
"limitation will be lifted in the future.");*/
|
"limitation will be lifted in the future.");*/
|
||||||
|
|
||||||
constexpr auto result = json.front() == '['
|
if constexpr (json.front() == '[') {
|
||||||
? parse_json_array_impl(json)
|
return [: parse_json_array_impl(json).first :];
|
||||||
: parse_json_object_impl(json);
|
} else {
|
||||||
return [: result.first :];
|
return [: parse_json_object_impl(json).first :];
|
||||||
/*
|
}
|
||||||
if(json.front() == '[') {
|
|
||||||
return [:parse_json_array_impl(json).first:];
|
|
||||||
} else if(json.front() == '{') {
|
|
||||||
// return [:parse_json_object_impl(json).first:];
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace compile_time
|
} // namespace compile_time
|
||||||
|
|||||||
@@ -58,6 +58,11 @@ struct fixed_string {
|
|||||||
data[i] = str[i];
|
data[i] = str[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
constexpr fixed_string(const unsigned char (&str)[N]) {
|
||||||
|
for (std::size_t i = 0; i < N; ++i) {
|
||||||
|
data[i] = static_cast<char>(str[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
char data[N];
|
char data[N];
|
||||||
constexpr std::string_view view() const { return {data, N - 1}; }
|
constexpr std::string_view view() const { return {data, N - 1}; }
|
||||||
constexpr size_t size() const { return N ; }
|
constexpr size_t size() const { return N ; }
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace SIMDJSON_IMPLEMENTATION {
|
|||||||
namespace builder {
|
namespace builder {
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
requires(concepts::container_but_not_string<T> && !require_custom_serialization<T>)
|
requires(concepts::container_but_not_string<T> && ! concepts::optional_type<T> && !require_custom_serialization<T>)
|
||||||
constexpr void atom(string_builder &b, const T &t) {
|
constexpr void atom(string_builder &b, const T &t) {
|
||||||
auto it = t.begin();
|
auto it = t.begin();
|
||||||
auto end = t.end();
|
auto end = t.end();
|
||||||
@@ -130,7 +130,7 @@ template <typename T>
|
|||||||
requires(std::is_enum_v<T> && !require_custom_serialization<T>)
|
requires(std::is_enum_v<T> && !require_custom_serialization<T>)
|
||||||
void atom(string_builder &b, const T &e) {
|
void atom(string_builder &b, const T &e) {
|
||||||
#if SIMDJSON_STATIC_REFLECTION
|
#if SIMDJSON_STATIC_REFLECTION
|
||||||
constexpr auto enumerators = std::define_static_array(std::meta::enumerators_of(^^T));
|
static constexpr auto enumerators = std::define_static_array(std::meta::enumerators_of(^^T));
|
||||||
template for (constexpr auto enum_val : enumerators) {
|
template for (constexpr auto enum_val : enumerators) {
|
||||||
constexpr auto enum_str = std::define_static_string(constevalutil::consteval_to_quoted_escaped(std::meta::identifier_of(enum_val)));
|
constexpr auto enum_str = std::define_static_string(constevalutil::consteval_to_quoted_escaped(std::meta::identifier_of(enum_val)));
|
||||||
if (e == [:enum_val:]) {
|
if (e == [:enum_val:]) {
|
||||||
@@ -294,30 +294,23 @@ string_builder& operator<<(string_builder& b, const Z& z) {
|
|||||||
template<constevalutil::fixed_string... FieldNames, typename T>
|
template<constevalutil::fixed_string... FieldNames, typename T>
|
||||||
requires(std::is_class_v<T> && (sizeof...(FieldNames) > 0))
|
requires(std::is_class_v<T> && (sizeof...(FieldNames) > 0))
|
||||||
void extract_from(string_builder &b, const T &obj) {
|
void extract_from(string_builder &b, const T &obj) {
|
||||||
// Helper to check if a field name matches any of the requested fields
|
|
||||||
auto should_extract = [](std::string_view field_name) constexpr -> bool {
|
|
||||||
return ((FieldNames.view() == field_name) || ...);
|
|
||||||
};
|
|
||||||
|
|
||||||
b.append('{');
|
b.append('{');
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
|
||||||
// Iterate through all members of T using reflection
|
// Iterate through all members of T using reflection
|
||||||
template for (constexpr auto mem : std::define_static_array(
|
static constexpr auto members = std::define_static_array(std::meta::nonstatic_data_members_of(^^T, std::meta::access_context::unchecked()));
|
||||||
std::meta::nonstatic_data_members_of(^^T, std::meta::access_context::unchecked()))) {
|
template for (constexpr auto mem : members) {
|
||||||
|
|
||||||
if constexpr (std::meta::is_public(mem)) {
|
if constexpr (std::meta::is_public(mem)) {
|
||||||
constexpr std::string_view key = std::define_static_string(std::meta::identifier_of(mem));
|
static constexpr std::string_view key = std::define_static_string(std::meta::identifier_of(mem));
|
||||||
|
|
||||||
// Only serialize this field if it's in our list of requested fields
|
// Only serialize this field if it's in our list of requested fields
|
||||||
if constexpr (should_extract(key)) {
|
if constexpr (((FieldNames.view() == key) || ...)) {
|
||||||
if (!first) {
|
if (!first) {
|
||||||
b.append(',');
|
b.append(',');
|
||||||
}
|
}
|
||||||
first = false;
|
first = false;
|
||||||
|
|
||||||
// Serialize the key
|
// Serialize the key
|
||||||
constexpr auto quoted_key = std::define_static_string(constevalutil::consteval_to_quoted_escaped(std::meta::identifier_of(mem)));
|
static constexpr auto quoted_key = std::define_static_string(constevalutil::consteval_to_quoted_escaped(std::meta::identifier_of(mem)));
|
||||||
b.append_raw(quoted_key);
|
b.append_raw(quoted_key);
|
||||||
b.append(':');
|
b.append(':');
|
||||||
|
|
||||||
|
|||||||
@@ -505,7 +505,7 @@ simdjson_inline bool string_builder::capacity_check(size_t upcoming_bytes) {
|
|||||||
return is_valid;
|
return is_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
simdjson_inline void string_builder::grow_buffer(size_t desired_capacity) {
|
inline void string_builder::grow_buffer(size_t desired_capacity) {
|
||||||
if (!is_valid) {
|
if (!is_valid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -842,7 +842,7 @@ simdjson_inline void string_builder::append(const T &value) {
|
|||||||
#if SIMDJSON_SUPPORTS_RANGES && SIMDJSON_SUPPORTS_CONCEPTS
|
#if SIMDJSON_SUPPORTS_RANGES && SIMDJSON_SUPPORTS_CONCEPTS
|
||||||
// Support for range-based appending (std::ranges::view, etc.)
|
// Support for range-based appending (std::ranges::view, etc.)
|
||||||
template <std::ranges::range R>
|
template <std::ranges::range R>
|
||||||
requires(!std::is_convertible<R, std::string_view>::value && !require_custom_serialization<R>)
|
requires(!std::is_convertible<R, std::string_view>::value && !concepts::optional_type<R> && !require_custom_serialization<R>)
|
||||||
simdjson_inline void string_builder::append(const R &range) noexcept {
|
simdjson_inline void string_builder::append(const R &range) noexcept {
|
||||||
auto it = std::ranges::begin(range);
|
auto it = std::ranges::begin(range);
|
||||||
auto end = std::ranges::end(range);
|
auto end = std::ranges::end(range);
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ public:
|
|||||||
#if SIMDJSON_SUPPORTS_RANGES && SIMDJSON_SUPPORTS_CONCEPTS
|
#if SIMDJSON_SUPPORTS_RANGES && SIMDJSON_SUPPORTS_CONCEPTS
|
||||||
// Support for range-based appending (std::ranges::view, etc.)
|
// Support for range-based appending (std::ranges::view, etc.)
|
||||||
template <std::ranges::range R>
|
template <std::ranges::range R>
|
||||||
requires (!std::is_convertible<R, std::string_view>::value && !require_custom_serialization<R>)
|
requires (!std::is_convertible<R, std::string_view>::value && !concepts::optional_type<R> && !require_custom_serialization<R>)
|
||||||
simdjson_inline void append(const R &range) noexcept;
|
simdjson_inline void append(const R &range) noexcept;
|
||||||
#endif
|
#endif
|
||||||
/**
|
/**
|
||||||
@@ -249,7 +249,7 @@ private:
|
|||||||
* If the allocation fails, is_valid is set to false. We expect
|
* If the allocation fails, is_valid is set to false. We expect
|
||||||
* that this function would not be repeatedly called.
|
* that this function would not be repeatedly called.
|
||||||
*/
|
*/
|
||||||
simdjson_inline void grow_buffer(size_t desired_capacity);
|
inline void grow_buffer(size_t desired_capacity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We use this helper function to make sure that is_valid is kept consistent.
|
* We use this helper function to make sure that is_valid is kept consistent.
|
||||||
|
|||||||
@@ -653,27 +653,27 @@ simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::op
|
|||||||
}
|
}
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator uint64_t() noexcept(false) {
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator uint64_t() noexcept(false) {
|
||||||
if (error()) { throw simdjson_error(error()); }
|
if (error()) { throw simdjson_error(error()); }
|
||||||
return first;
|
return first.get_uint64();
|
||||||
}
|
}
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator int64_t() noexcept(false) {
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator int64_t() noexcept(false) {
|
||||||
if (error()) { throw simdjson_error(error()); }
|
if (error()) { throw simdjson_error(error()); }
|
||||||
return first;
|
return first.get_int64();
|
||||||
}
|
}
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator double() noexcept(false) {
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator double() noexcept(false) {
|
||||||
if (error()) { throw simdjson_error(error()); }
|
if (error()) { throw simdjson_error(error()); }
|
||||||
return first;
|
return first.get_double();
|
||||||
}
|
}
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator std::string_view() noexcept(false) {
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator std::string_view() noexcept(false) {
|
||||||
if (error()) { throw simdjson_error(error()); }
|
if (error()) { throw simdjson_error(error()); }
|
||||||
return first;
|
return first.get_string();
|
||||||
}
|
}
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string() noexcept(false) {
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string() noexcept(false) {
|
||||||
if (error()) { throw simdjson_error(error()); }
|
if (error()) { throw simdjson_error(error()); }
|
||||||
return first;
|
return first.get_raw_json_string();
|
||||||
}
|
}
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator bool() noexcept(false) {
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator bool() noexcept(false) {
|
||||||
if (error()) { throw simdjson_error(error()); }
|
if (error()) { throw simdjson_error(error()); }
|
||||||
return first;
|
return first.get_bool();
|
||||||
}
|
}
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator SIMDJSON_IMPLEMENTATION::ondemand::value() noexcept(false) {
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator SIMDJSON_IMPLEMENTATION::ondemand::value() noexcept(false) {
|
||||||
if (error()) { throw simdjson_error(error()); }
|
if (error()) { throw simdjson_error(error()); }
|
||||||
@@ -1042,27 +1042,27 @@ simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_refe
|
|||||||
}
|
}
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator uint64_t() noexcept(false) {
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator uint64_t() noexcept(false) {
|
||||||
if (error()) { throw simdjson_error(error()); }
|
if (error()) { throw simdjson_error(error()); }
|
||||||
return first;
|
return first.get_uint64();
|
||||||
}
|
}
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator int64_t() noexcept(false) {
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator int64_t() noexcept(false) {
|
||||||
if (error()) { throw simdjson_error(error()); }
|
if (error()) { throw simdjson_error(error()); }
|
||||||
return first;
|
return first.get_int64();
|
||||||
}
|
}
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator double() noexcept(false) {
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator double() noexcept(false) {
|
||||||
if (error()) { throw simdjson_error(error()); }
|
if (error()) { throw simdjson_error(error()); }
|
||||||
return first;
|
return first.get_double();
|
||||||
}
|
}
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator std::string_view() noexcept(false) {
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator std::string_view() noexcept(false) {
|
||||||
if (error()) { throw simdjson_error(error()); }
|
if (error()) { throw simdjson_error(error()); }
|
||||||
return first;
|
return first.get_string();
|
||||||
}
|
}
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string() noexcept(false) {
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string() noexcept(false) {
|
||||||
if (error()) { throw simdjson_error(error()); }
|
if (error()) { throw simdjson_error(error()); }
|
||||||
return first;
|
return first.get_raw_json_string();
|
||||||
}
|
}
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator bool() noexcept(false) {
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator bool() noexcept(false) {
|
||||||
if (error()) { throw simdjson_error(error()); }
|
if (error()) { throw simdjson_error(error()); }
|
||||||
return first;
|
return first.get_bool();
|
||||||
}
|
}
|
||||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator SIMDJSON_IMPLEMENTATION::ondemand::value() noexcept(false) {
|
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator SIMDJSON_IMPLEMENTATION::ondemand::value() noexcept(false) {
|
||||||
if (error()) { throw simdjson_error(error()); }
|
if (error()) { throw simdjson_error(error()); }
|
||||||
|
|||||||
@@ -319,21 +319,21 @@ public:
|
|||||||
* @returns A signed 64-bit integer.
|
* @returns A signed 64-bit integer.
|
||||||
* @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit unsigned integer.
|
* @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit unsigned integer.
|
||||||
*/
|
*/
|
||||||
simdjson_inline operator uint64_t() noexcept(false);
|
explicit simdjson_inline operator uint64_t() noexcept(false);
|
||||||
/**
|
/**
|
||||||
* Cast this JSON value to a signed integer.
|
* Cast this JSON value to a signed integer.
|
||||||
*
|
*
|
||||||
* @returns A signed 64-bit integer.
|
* @returns A signed 64-bit integer.
|
||||||
* @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit integer.
|
* @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit integer.
|
||||||
*/
|
*/
|
||||||
simdjson_inline operator int64_t() noexcept(false);
|
explicit simdjson_inline operator int64_t() noexcept(false);
|
||||||
/**
|
/**
|
||||||
* Cast this JSON value to a double.
|
* Cast this JSON value to a double.
|
||||||
*
|
*
|
||||||
* @returns A double.
|
* @returns A double.
|
||||||
* @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a valid floating-point number.
|
* @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a valid floating-point number.
|
||||||
*/
|
*/
|
||||||
simdjson_inline operator double() noexcept(false);
|
explicit simdjson_inline operator double() noexcept(false);
|
||||||
/**
|
/**
|
||||||
* Cast this JSON value to a string.
|
* Cast this JSON value to a string.
|
||||||
*
|
*
|
||||||
@@ -343,7 +343,7 @@ public:
|
|||||||
* time it parses a document or when it is destroyed.
|
* time it parses a document or when it is destroyed.
|
||||||
* @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string.
|
* @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string.
|
||||||
*/
|
*/
|
||||||
simdjson_inline operator std::string_view() noexcept(false) simdjson_lifetime_bound;
|
explicit simdjson_inline operator std::string_view() noexcept(false) simdjson_lifetime_bound;
|
||||||
/**
|
/**
|
||||||
* Cast this JSON value to a raw_json_string.
|
* Cast this JSON value to a raw_json_string.
|
||||||
*
|
*
|
||||||
@@ -352,14 +352,14 @@ public:
|
|||||||
* @returns A pointer to the raw JSON for the given string.
|
* @returns A pointer to the raw JSON for the given string.
|
||||||
* @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string.
|
* @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string.
|
||||||
*/
|
*/
|
||||||
simdjson_inline operator raw_json_string() noexcept(false) simdjson_lifetime_bound;
|
explicit simdjson_inline operator raw_json_string() noexcept(false) simdjson_lifetime_bound;
|
||||||
/**
|
/**
|
||||||
* Cast this JSON value to a bool.
|
* Cast this JSON value to a bool.
|
||||||
*
|
*
|
||||||
* @returns A bool value.
|
* @returns A bool value.
|
||||||
* @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not true or false.
|
* @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not true or false.
|
||||||
*/
|
*/
|
||||||
simdjson_inline operator bool() noexcept(false);
|
explicit simdjson_inline operator bool() noexcept(false);
|
||||||
/**
|
/**
|
||||||
* Cast this JSON value to a value when the document is an object or an array.
|
* Cast this JSON value to a value when the document is an object or an array.
|
||||||
*
|
*
|
||||||
@@ -945,12 +945,12 @@ public:
|
|||||||
explicit simdjson_inline operator T() noexcept(false);
|
explicit simdjson_inline operator T() noexcept(false);
|
||||||
simdjson_inline operator array() & noexcept(false);
|
simdjson_inline operator array() & noexcept(false);
|
||||||
simdjson_inline operator object() & noexcept(false);
|
simdjson_inline operator object() & noexcept(false);
|
||||||
simdjson_inline operator uint64_t() noexcept(false);
|
explicit simdjson_inline operator uint64_t() noexcept(false);
|
||||||
simdjson_inline operator int64_t() noexcept(false);
|
explicit simdjson_inline operator int64_t() noexcept(false);
|
||||||
simdjson_inline operator double() noexcept(false);
|
explicit simdjson_inline operator double() noexcept(false);
|
||||||
simdjson_inline operator std::string_view() noexcept(false);
|
explicit simdjson_inline operator std::string_view() noexcept(false);
|
||||||
simdjson_inline operator raw_json_string() noexcept(false);
|
explicit simdjson_inline operator raw_json_string() noexcept(false);
|
||||||
simdjson_inline operator bool() noexcept(false);
|
explicit simdjson_inline operator bool() noexcept(false);
|
||||||
simdjson_inline operator value() noexcept(false);
|
simdjson_inline operator value() noexcept(false);
|
||||||
#endif
|
#endif
|
||||||
simdjson_inline simdjson_result<size_t> count_elements() & noexcept;
|
simdjson_inline simdjson_result<size_t> count_elements() & noexcept;
|
||||||
@@ -1030,12 +1030,12 @@ public:
|
|||||||
explicit simdjson_inline operator T() noexcept(false);
|
explicit simdjson_inline operator T() noexcept(false);
|
||||||
simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::array() & noexcept(false);
|
simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::array() & noexcept(false);
|
||||||
simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::object() & noexcept(false);
|
simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::object() & noexcept(false);
|
||||||
simdjson_inline operator uint64_t() noexcept(false);
|
explicit simdjson_inline operator uint64_t() noexcept(false);
|
||||||
simdjson_inline operator int64_t() noexcept(false);
|
explicit simdjson_inline operator int64_t() noexcept(false);
|
||||||
simdjson_inline operator double() noexcept(false);
|
explicit simdjson_inline operator double() noexcept(false);
|
||||||
simdjson_inline operator std::string_view() noexcept(false);
|
explicit simdjson_inline operator std::string_view() noexcept(false);
|
||||||
simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string() noexcept(false);
|
explicit simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string() noexcept(false);
|
||||||
simdjson_inline operator bool() noexcept(false);
|
explicit simdjson_inline operator bool() noexcept(false);
|
||||||
simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::value() noexcept(false);
|
simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::value() noexcept(false);
|
||||||
#endif
|
#endif
|
||||||
simdjson_inline simdjson_result<size_t> count_elements() & noexcept;
|
simdjson_inline simdjson_result<size_t> count_elements() & noexcept;
|
||||||
@@ -1116,12 +1116,12 @@ public:
|
|||||||
explicit simdjson_inline operator T() noexcept(false);
|
explicit simdjson_inline operator T() noexcept(false);
|
||||||
simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::array() & noexcept(false);
|
simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::array() & noexcept(false);
|
||||||
simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::object() & noexcept(false);
|
simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::object() & noexcept(false);
|
||||||
simdjson_inline operator uint64_t() noexcept(false);
|
explicit simdjson_inline operator uint64_t() noexcept(false);
|
||||||
simdjson_inline operator int64_t() noexcept(false);
|
explicit simdjson_inline operator int64_t() noexcept(false);
|
||||||
simdjson_inline operator double() noexcept(false);
|
explicit simdjson_inline operator double() noexcept(false);
|
||||||
simdjson_inline operator std::string_view() noexcept(false);
|
explicit simdjson_inline operator std::string_view() noexcept(false);
|
||||||
simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string() noexcept(false);
|
explicit simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string() noexcept(false);
|
||||||
simdjson_inline operator bool() noexcept(false);
|
explicit simdjson_inline operator bool() noexcept(false);
|
||||||
simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::value() noexcept(false);
|
simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::value() noexcept(false);
|
||||||
#endif
|
#endif
|
||||||
simdjson_inline simdjson_result<size_t> count_elements() & noexcept;
|
simdjson_inline simdjson_result<size_t> count_elements() & noexcept;
|
||||||
|
|||||||
@@ -305,7 +305,7 @@ error_code tag_invoke(deserialize_tag, ValT &val, T &out) noexcept {
|
|||||||
#if SIMDJSON_STATIC_REFLECTION
|
#if SIMDJSON_STATIC_REFLECTION
|
||||||
std::string_view str;
|
std::string_view str;
|
||||||
SIMDJSON_TRY(val.get_string().get(str));
|
SIMDJSON_TRY(val.get_string().get(str));
|
||||||
constexpr auto enumerators = std::define_static_array(std::meta::enumerators_of(^^T));
|
static constexpr auto enumerators = std::define_static_array(std::meta::enumerators_of(^^T));
|
||||||
template for (constexpr auto enum_val : enumerators) {
|
template for (constexpr auto enum_val : enumerators) {
|
||||||
if (str == std::meta::identifier_of(enum_val)) {
|
if (str == std::meta::identifier_of(enum_val)) {
|
||||||
out = [:enum_val:];
|
out = [:enum_val:];
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"app_name": "MyApp",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"port": 8080,
|
||||||
|
"debug": true,
|
||||||
|
"features": ["logging", "caching"],
|
||||||
|
"database": {
|
||||||
|
"host": "localhost",
|
||||||
|
"port": 5432
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* auto-generated on 2026-04-03 15:25:03 -0400. version 4.6.1 Do not edit! */
|
/* auto-generated on 2026-04-02 19:14:16 -0400. version 4.6.1 Do not edit! */
|
||||||
/* including simdjson.cpp: */
|
/* including simdjson.cpp: */
|
||||||
/* begin file simdjson.cpp */
|
/* begin file simdjson.cpp */
|
||||||
#define SIMDJSON_SRC_SIMDJSON_CPP
|
#define SIMDJSON_SRC_SIMDJSON_CPP
|
||||||
@@ -3168,6 +3168,11 @@ struct fixed_string {
|
|||||||
data[i] = str[i];
|
data[i] = str[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
constexpr fixed_string(const unsigned char (&str)[N]) {
|
||||||
|
for (std::size_t i = 0; i < N; ++i) {
|
||||||
|
data[i] = static_cast<char>(str[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
char data[N];
|
char data[N];
|
||||||
constexpr std::string_view view() const { return {data, N - 1}; }
|
constexpr std::string_view view() const { return {data, N - 1}; }
|
||||||
constexpr size_t size() const { return N ; }
|
constexpr size_t size() const { return N ; }
|
||||||
|
|||||||
+473
-530
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -6,40 +6,40 @@
|
|||||||
|
|
||||||
using namespace simdjson;
|
using namespace simdjson;
|
||||||
struct Car {
|
struct Car {
|
||||||
std::string make;
|
std::string make{};
|
||||||
std::string model;
|
std::string model{};
|
||||||
int64_t year;
|
int64_t year{};
|
||||||
std::vector<double> tire_pressure;
|
std::vector<double> tire_pressure{};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct kid {
|
struct kid {
|
||||||
int age;
|
int age{};
|
||||||
std::string name;
|
std::string name{};
|
||||||
std::vector<std::string> toys;
|
std::vector<std::string> toys{};
|
||||||
bool operator<=> (const kid&) const = default;
|
bool operator<=> (const kid&) const = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Z {
|
struct Z {
|
||||||
int x;
|
int x{};
|
||||||
bool operator<=> (const Z&) const = default;
|
bool operator<=> (const Z&) const = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Y {
|
struct Y {
|
||||||
int g;
|
int g{};
|
||||||
std::string h;
|
std::string h{};
|
||||||
std::vector<int> i;
|
std::vector<int> i{};
|
||||||
Z z;
|
Z z{};
|
||||||
bool operator<=> (const Y&) const = default;
|
bool operator<=> (const Y&) const = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct X {
|
struct X {
|
||||||
char a;
|
char a{};
|
||||||
int b;
|
int b{};
|
||||||
int c;
|
int c{};
|
||||||
std::string d;
|
std::string d{};
|
||||||
std::vector<int> e;
|
std::vector<int> e{};
|
||||||
std::vector<std::string> f;
|
std::vector<std::string> f{};
|
||||||
Y y;
|
Y y{};
|
||||||
bool operator<=> (const X&) const = default;
|
bool operator<=> (const X&) const = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ namespace builder_tests {
|
|||||||
#if SIMDJSON_STATIC_REFLECTION
|
#if SIMDJSON_STATIC_REFLECTION
|
||||||
// Custom type for testing tag_invoke with extract_into
|
// Custom type for testing tag_invoke with extract_into
|
||||||
struct Price {
|
struct Price {
|
||||||
double amount;
|
double amount{};
|
||||||
std::string currency;
|
std::string currency{};
|
||||||
|
|
||||||
// Custom deserializer that applies currency conversion
|
// Custom deserializer that applies currency conversion
|
||||||
friend error_code tag_invoke(deserialize_tag,
|
friend error_code tag_invoke(deserialize_tag,
|
||||||
@@ -46,17 +46,37 @@ namespace builder_tests {
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
struct Car {
|
||||||
|
std::string make{};
|
||||||
|
std::string model{};
|
||||||
|
int year{};
|
||||||
|
double price{};
|
||||||
|
bool electric{};
|
||||||
|
};
|
||||||
|
struct CarOpt {
|
||||||
|
std::string make;
|
||||||
|
std::string model;
|
||||||
|
int year;
|
||||||
|
double price;
|
||||||
|
std::optional<std::string> color;
|
||||||
|
};
|
||||||
|
struct CarColor {
|
||||||
|
std::string make;
|
||||||
|
std::string model;
|
||||||
|
int year;
|
||||||
|
double price;
|
||||||
|
std::string color;
|
||||||
|
};
|
||||||
struct Product {
|
struct Product {
|
||||||
std::string name;
|
std::string name{};
|
||||||
Price price; // Custom deserializable type
|
Price price{}; // Custom deserializable type
|
||||||
int stock;
|
int stock{};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Another custom type for testing
|
// Another custom type for testing
|
||||||
struct Dimensions {
|
struct Dimensions {
|
||||||
double value;
|
double value{};
|
||||||
std::string unit;
|
std::string unit{};
|
||||||
|
|
||||||
// Custom deserializer that converts to metric
|
// Custom deserializer that converts to metric
|
||||||
friend error_code tag_invoke(deserialize_tag,
|
friend error_code tag_invoke(deserialize_tag,
|
||||||
@@ -89,6 +109,13 @@ namespace builder_tests {
|
|||||||
Dimensions weight;
|
Dimensions weight;
|
||||||
Dimensions length;
|
Dimensions length;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Person {
|
||||||
|
std::string name;
|
||||||
|
int age;
|
||||||
|
std::optional<std::string> email;
|
||||||
|
std::optional<std::string> phone;
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool test_primitive_types() {
|
bool test_primitive_types() {
|
||||||
@@ -132,8 +159,8 @@ namespace builder_tests {
|
|||||||
TEST_START();
|
TEST_START();
|
||||||
#if SIMDJSON_STATIC_REFLECTION
|
#if SIMDJSON_STATIC_REFLECTION
|
||||||
struct StringTypes {
|
struct StringTypes {
|
||||||
std::string string_val;
|
std::string string_val{};
|
||||||
std::string_view string_view_val;
|
std::string_view string_view_val{};
|
||||||
};
|
};
|
||||||
|
|
||||||
StringTypes test{"hello world", "test_view"};
|
StringTypes test{"hello world", "test_view"};
|
||||||
@@ -159,10 +186,10 @@ namespace builder_tests {
|
|||||||
TEST_START();
|
TEST_START();
|
||||||
#if SIMDJSON_STATIC_REFLECTION
|
#if SIMDJSON_STATIC_REFLECTION
|
||||||
struct OptionalTypes {
|
struct OptionalTypes {
|
||||||
std::optional<int> opt_int_with_value;
|
std::optional<int> opt_int_with_value{};
|
||||||
std::optional<std::string> opt_string_with_value;
|
std::optional<std::string> opt_string_with_value{};
|
||||||
std::optional<int> opt_int_null;
|
std::optional<int> opt_int_null{};
|
||||||
std::optional<std::string> opt_string_null;
|
std::optional<std::string> opt_string_null{};
|
||||||
};
|
};
|
||||||
|
|
||||||
OptionalTypes test;
|
OptionalTypes test;
|
||||||
@@ -200,11 +227,11 @@ namespace builder_tests {
|
|||||||
TEST_START();
|
TEST_START();
|
||||||
#if SIMDJSON_STATIC_REFLECTION
|
#if SIMDJSON_STATIC_REFLECTION
|
||||||
struct SmartPointerTypes {
|
struct SmartPointerTypes {
|
||||||
std::unique_ptr<int> unique_int_with_value;
|
std::unique_ptr<int> unique_int_with_value{};
|
||||||
std::shared_ptr<std::string> shared_string_with_value;
|
std::shared_ptr<std::string> shared_string_with_value{};
|
||||||
std::unique_ptr<bool> unique_bool_with_value;
|
std::unique_ptr<bool> unique_bool_with_value{};
|
||||||
std::unique_ptr<int> unique_int_null;
|
std::unique_ptr<int> unique_int_null{};
|
||||||
std::shared_ptr<std::string> shared_string_null;
|
std::shared_ptr<std::string> shared_string_null{};
|
||||||
};
|
};
|
||||||
|
|
||||||
SmartPointerTypes test;
|
SmartPointerTypes test;
|
||||||
@@ -245,9 +272,9 @@ namespace builder_tests {
|
|||||||
#if SIMDJSON_STATIC_REFLECTION
|
#if SIMDJSON_STATIC_REFLECTION
|
||||||
// Test basic container types
|
// Test basic container types
|
||||||
struct ContainerTypes {
|
struct ContainerTypes {
|
||||||
std::vector<int> int_vector;
|
std::vector<int> int_vector{};
|
||||||
std::set<std::string> string_set;
|
std::set<std::string> string_set{};
|
||||||
std::map<std::string, int> string_map;
|
std::map<std::string, int> string_map{};
|
||||||
};
|
};
|
||||||
|
|
||||||
ContainerTypes test;
|
ContainerTypes test;
|
||||||
@@ -278,8 +305,8 @@ namespace builder_tests {
|
|||||||
|
|
||||||
// Test std::list with iterator-based serialization
|
// Test std::list with iterator-based serialization
|
||||||
struct ListContainer {
|
struct ListContainer {
|
||||||
std::list<int> int_list;
|
std::list<int> int_list{};
|
||||||
std::list<std::string> string_list;
|
std::list<std::string> string_list{};
|
||||||
};
|
};
|
||||||
|
|
||||||
ListContainer list_test;
|
ListContainer list_test;
|
||||||
@@ -319,13 +346,7 @@ namespace builder_tests {
|
|||||||
bool test_extract_into() {
|
bool test_extract_into() {
|
||||||
TEST_START();
|
TEST_START();
|
||||||
#if SIMDJSON_STATIC_REFLECTION
|
#if SIMDJSON_STATIC_REFLECTION
|
||||||
struct Car {
|
|
||||||
std::string make;
|
|
||||||
std::string model;
|
|
||||||
int year;
|
|
||||||
double price;
|
|
||||||
std::optional<std::string> color;
|
|
||||||
};
|
|
||||||
|
|
||||||
ondemand::parser parser;
|
ondemand::parser parser;
|
||||||
|
|
||||||
@@ -341,7 +362,7 @@ namespace builder_tests {
|
|||||||
"transmission": "Automatic"
|
"transmission": "Automatic"
|
||||||
})"_padded;
|
})"_padded;
|
||||||
|
|
||||||
Car car{};
|
CarOpt car{};
|
||||||
ondemand::document doc;
|
ondemand::document doc;
|
||||||
ASSERT_SUCCESS( parser.iterate(padded).get(doc) );
|
ASSERT_SUCCESS( parser.iterate(padded).get(doc) );
|
||||||
|
|
||||||
@@ -377,7 +398,7 @@ namespace builder_tests {
|
|||||||
"color": "Red"
|
"color": "Red"
|
||||||
})"_padded;
|
})"_padded;
|
||||||
|
|
||||||
Car car{};
|
CarOpt car{};
|
||||||
ondemand::document doc;
|
ondemand::document doc;
|
||||||
ASSERT_SUCCESS(parser.iterate(padded).get(doc));
|
ASSERT_SUCCESS(parser.iterate(padded).get(doc));
|
||||||
|
|
||||||
@@ -402,7 +423,7 @@ namespace builder_tests {
|
|||||||
"price": 35999.99
|
"price": 35999.99
|
||||||
})"_padded;
|
})"_padded;
|
||||||
|
|
||||||
Car car{};
|
CarOpt car{};
|
||||||
ondemand::document doc;
|
ondemand::document doc;
|
||||||
ASSERT_SUCCESS(parser.iterate(padded).get(doc));
|
ASSERT_SUCCESS(parser.iterate(padded).get(doc));
|
||||||
|
|
||||||
@@ -495,13 +516,6 @@ namespace builder_tests {
|
|||||||
#if SIMDJSON_STATIC_REFLECTION
|
#if SIMDJSON_STATIC_REFLECTION
|
||||||
// Test 1: Extract specific fields from Car struct
|
// Test 1: Extract specific fields from Car struct
|
||||||
{
|
{
|
||||||
struct Car {
|
|
||||||
std::string make;
|
|
||||||
std::string model;
|
|
||||||
int year;
|
|
||||||
double price;
|
|
||||||
bool electric;
|
|
||||||
};
|
|
||||||
|
|
||||||
Car car{"Tesla", "Model 3", 2023, 42000.0, true};
|
Car car{"Tesla", "Model 3", 2023, 42000.0, true};
|
||||||
|
|
||||||
@@ -533,13 +547,7 @@ namespace builder_tests {
|
|||||||
|
|
||||||
// Test 2: Extract different field combination
|
// Test 2: Extract different field combination
|
||||||
{
|
{
|
||||||
struct Car {
|
|
||||||
std::string make;
|
|
||||||
std::string model;
|
|
||||||
int year;
|
|
||||||
double price;
|
|
||||||
bool electric;
|
|
||||||
};
|
|
||||||
|
|
||||||
Car car{"Ford", "F-150", 2024, 55000.0, false};
|
Car car{"Ford", "F-150", 2024, 55000.0, false};
|
||||||
|
|
||||||
@@ -566,13 +574,6 @@ namespace builder_tests {
|
|||||||
|
|
||||||
// Test 3: Extract from struct with optional fields
|
// Test 3: Extract from struct with optional fields
|
||||||
{
|
{
|
||||||
struct Person {
|
|
||||||
std::string name;
|
|
||||||
int age;
|
|
||||||
std::optional<std::string> email;
|
|
||||||
std::optional<std::string> phone;
|
|
||||||
};
|
|
||||||
|
|
||||||
Person person{"John Doe", 30, "john@example.com", std::nullopt};
|
Person person{"John Doe", 30, "john@example.com", std::nullopt};
|
||||||
|
|
||||||
// Extract name and email
|
// Extract name and email
|
||||||
@@ -594,13 +595,6 @@ namespace builder_tests {
|
|||||||
|
|
||||||
// Test 4: Extract with optional that has value
|
// Test 4: Extract with optional that has value
|
||||||
{
|
{
|
||||||
struct Person {
|
|
||||||
std::string name;
|
|
||||||
int age;
|
|
||||||
std::optional<std::string> email;
|
|
||||||
std::optional<std::string> phone;
|
|
||||||
};
|
|
||||||
|
|
||||||
Person person{"Jane Smith", 25, "jane@example.com", "555-1234"};
|
Person person{"Jane Smith", 25, "jane@example.com", "555-1234"};
|
||||||
|
|
||||||
// Extract name, age, and phone
|
// Extract name, age, and phone
|
||||||
@@ -629,21 +623,21 @@ namespace builder_tests {
|
|||||||
|
|
||||||
// Test 5: Round-trip test - serialize with extract_from, deserialize with extract_into
|
// Test 5: Round-trip test - serialize with extract_from, deserialize with extract_into
|
||||||
{
|
{
|
||||||
struct Product {
|
struct MyProduct {
|
||||||
std::string id;
|
std::string id{};
|
||||||
std::string name;
|
std::string name{};
|
||||||
double price;
|
double price{};
|
||||||
int stock;
|
int stock{};
|
||||||
};
|
};
|
||||||
|
|
||||||
Product original{"P123", "Widget", 19.99, 100};
|
MyProduct original{"P123", "Widget", 19.99, 100};
|
||||||
|
|
||||||
// Extract specific fields to JSON
|
// Extract specific fields to JSON
|
||||||
std::string json;
|
std::string json;
|
||||||
ASSERT_SUCCESS((extract_from<"id", "name", "price">(original).get(json)));
|
ASSERT_SUCCESS((extract_from<"id", "name", "price">(original).get(json)));
|
||||||
|
|
||||||
// Parse and extract back
|
// Parse and extract back
|
||||||
Product restored{"", "", 0.0, 0};
|
MyProduct restored{"", "", 0.0, 0};
|
||||||
auto padded = pad(json);
|
auto padded = pad(json);
|
||||||
ondemand::parser parser;
|
ondemand::parser parser;
|
||||||
auto doc = parser.iterate(padded);
|
auto doc = parser.iterate(padded);
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ using namespace simdjson;
|
|||||||
// Suppose that we want to serialize/deserialize Car using
|
// Suppose that we want to serialize/deserialize Car using
|
||||||
// strings for the year
|
// strings for the year
|
||||||
struct Car {
|
struct Car {
|
||||||
std::string make;
|
std::string make{};
|
||||||
std::string model;
|
std::string model{};
|
||||||
int64_t year;
|
int64_t year{};
|
||||||
std::vector<float> tire_pressure;
|
std::vector<float> tire_pressure{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ namespace builder_tests {
|
|||||||
TEST_START();
|
TEST_START();
|
||||||
#if SIMDJSON_STATIC_REFLECTION
|
#if SIMDJSON_STATIC_REFLECTION
|
||||||
struct EmptyValues {
|
struct EmptyValues {
|
||||||
std::string empty_string;
|
std::string empty_string{};
|
||||||
std::vector<int> empty_vector;
|
std::vector<int> empty_vector{};
|
||||||
std::optional<int> null_optional;
|
std::optional<int> null_optional{};
|
||||||
std::unique_ptr<int> null_unique_ptr;
|
std::unique_ptr<int> null_unique_ptr{};
|
||||||
std::shared_ptr<std::string> null_shared_ptr;
|
std::shared_ptr<std::string> null_shared_ptr{};
|
||||||
};
|
};
|
||||||
|
|
||||||
EmptyValues test;
|
EmptyValues test;
|
||||||
@@ -56,18 +56,18 @@ namespace builder_tests {
|
|||||||
TEST_START();
|
TEST_START();
|
||||||
#if SIMDJSON_STATIC_REFLECTION
|
#if SIMDJSON_STATIC_REFLECTION
|
||||||
struct SpecialChars {
|
struct SpecialChars {
|
||||||
std::string quotes;
|
std::string quotes{};
|
||||||
std::string backslashes;
|
std::string backslashes{};
|
||||||
std::string newlines;
|
std::string newlines{};
|
||||||
std::string unicode;
|
std::string unicode{};
|
||||||
char null_char;
|
char null_char{};
|
||||||
};
|
};
|
||||||
|
|
||||||
SpecialChars test;
|
SpecialChars test;
|
||||||
test.quotes = "He said \"Hello\"";
|
test.quotes = "He said \"Hello\"";
|
||||||
test.backslashes = "Path\\to\\file";
|
test.backslashes = "Path\\to\\file";
|
||||||
test.newlines = "Line1\nLine2\tTabbed";
|
test.newlines = "Line1\nLine2\tTabbed";
|
||||||
test.unicode = "Café résumé";
|
test.unicode = "Caf\xc3\xa9 r\xc3\xa9sum\xc3\xa9";
|
||||||
test.null_char = '\0';
|
test.null_char = '\0';
|
||||||
|
|
||||||
std::string json;
|
std::string json;
|
||||||
@@ -82,10 +82,10 @@ namespace builder_tests {
|
|||||||
|
|
||||||
// Test round-trip (excluding null char which has special handling)
|
// Test round-trip (excluding null char which has special handling)
|
||||||
struct SpecialCharsNoNull {
|
struct SpecialCharsNoNull {
|
||||||
std::string quotes;
|
std::string quotes{};
|
||||||
std::string backslashes;
|
std::string backslashes{};
|
||||||
std::string newlines;
|
std::string newlines{};
|
||||||
std::string unicode;
|
std::string unicode{};
|
||||||
};
|
};
|
||||||
|
|
||||||
SpecialCharsNoNull test_no_null;
|
SpecialCharsNoNull test_no_null;
|
||||||
@@ -157,15 +157,15 @@ namespace builder_tests {
|
|||||||
TEST_START();
|
TEST_START();
|
||||||
#if SIMDJSON_STATIC_REFLECTION
|
#if SIMDJSON_STATIC_REFLECTION
|
||||||
struct Inner {
|
struct Inner {
|
||||||
int value;
|
int value{};
|
||||||
std::string name;
|
std::string name{};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Outer {
|
struct Outer {
|
||||||
Inner inner_obj;
|
Inner inner_obj{};
|
||||||
std::vector<Inner> inner_vector;
|
std::vector<Inner> inner_vector{};
|
||||||
std::optional<Inner> optional_inner;
|
std::optional<Inner> optional_inner{};
|
||||||
std::unique_ptr<Inner> unique_inner;
|
std::unique_ptr<Inner> unique_inner{};
|
||||||
};
|
};
|
||||||
|
|
||||||
Outer test;
|
Outer test;
|
||||||
@@ -213,4 +213,4 @@ namespace builder_tests {
|
|||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
return test_main(argc, argv, builder_tests::run);
|
return test_main(argc, argv, builder_tests::run);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,8 +51,8 @@ namespace builder_tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct StatusStruct {
|
struct StatusStruct {
|
||||||
Status status;
|
Status status{};
|
||||||
std::string name;
|
std::string name{};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Test deserialization of different enum values with string representation
|
// Test deserialization of different enum values with string representation
|
||||||
@@ -104,9 +104,9 @@ namespace builder_tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Task {
|
struct Task {
|
||||||
Priority priority;
|
Priority priority{};
|
||||||
std::string description;
|
std::string description{};
|
||||||
int id;
|
int id{};
|
||||||
};
|
};
|
||||||
|
|
||||||
Task original{Priority::High, "Important task", 123};
|
Task original{Priority::High, "Important task", 123};
|
||||||
@@ -144,8 +144,8 @@ namespace builder_tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Response {
|
struct Response {
|
||||||
ErrorCode error;
|
ErrorCode error{};
|
||||||
std::string message;
|
std::string message{};
|
||||||
};
|
};
|
||||||
|
|
||||||
Response test{ErrorCode::NotFound, "Resource not found"};
|
Response test{ErrorCode::NotFound, "Resource not found"};
|
||||||
|
|||||||
@@ -8,26 +8,26 @@ using namespace simdjson;
|
|||||||
|
|
||||||
// Test structures for FracturedJson builder integration
|
// Test structures for FracturedJson builder integration
|
||||||
struct SimpleUser {
|
struct SimpleUser {
|
||||||
int id;
|
int id{};
|
||||||
std::string name;
|
std::string name{};
|
||||||
bool active;
|
bool active{};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UserWithEmail {
|
struct UserWithEmail {
|
||||||
int id;
|
int id{};
|
||||||
std::string name;
|
std::string name{};
|
||||||
std::string email;
|
std::string email{};
|
||||||
bool active;
|
bool active{};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NestedData {
|
struct NestedData {
|
||||||
std::string title;
|
std::string title{};
|
||||||
std::vector<SimpleUser> users;
|
std::vector<SimpleUser> users{};
|
||||||
int count;
|
int count{};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TableTestData {
|
struct TableTestData {
|
||||||
std::vector<SimpleUser> records;
|
std::vector<SimpleUser> records{};
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace fractured_json_builder_tests {
|
namespace fractured_json_builder_tests {
|
||||||
|
|||||||
@@ -666,27 +666,27 @@ bool test_array_of_objects_with_concept() {
|
|||||||
/**
|
/**
|
||||||
* Test: #embed support for external JSON files (C++26)
|
* Test: #embed support for external JSON files (C++26)
|
||||||
*/
|
*/
|
||||||
bool test_embed_twitter_json() {
|
bool test_embed_example_config_json() {
|
||||||
TEST_START();
|
TEST_START();
|
||||||
|
|
||||||
// C++26 #embed allows embedding files directly into the binary at compile time
|
// C++26 #embed allows embedding files directly into the binary at compile time
|
||||||
// This creates a const char array with the file contents plus null terminator
|
// This creates a const char array with the file contents plus null terminator
|
||||||
constexpr const char twitter_json[] = {
|
constexpr const unsigned char example_config_json[] = {
|
||||||
#embed TWITTER_JSON
|
#embed "../../jsonexamples/example_config.json"
|
||||||
, 0
|
, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
// Parse the embedded JSON at compile time
|
// Parse the embedded JSON at compile time
|
||||||
constexpr auto parsed_twitter = simdjson::compile_time::parse_json<twitter_json>();
|
constexpr auto parsed_example_config = simdjson::compile_time::parse_json<example_config_json>();
|
||||||
|
|
||||||
// Verify the structure - twitter.json should have a "statuses" array
|
// Verify the structure - example_config.json should have an "app_name" field
|
||||||
static_assert(parsed_twitter.statuses.size() > 0);
|
static_assert(std::string_view(parsed_example_config.app_name) == "MyApp");
|
||||||
|
|
||||||
// Runtime verification
|
// Runtime verification
|
||||||
ASSERT_TRUE(parsed_twitter.statuses.size() > 0);
|
ASSERT_TRUE(std::string_view(parsed_example_config.app_name) == "MyApp");
|
||||||
|
|
||||||
std::cout << "Successfully parsed embedded twitter.json with "
|
std::cout << "Successfully parsed embedded example_config.json with "
|
||||||
<< parsed_twitter.statuses.size() << " statuses" << std::endl;
|
<< parsed_example_config.app_name << " as app_name" << std::endl;
|
||||||
|
|
||||||
TEST_SUCCEED();
|
TEST_SUCCEED();
|
||||||
}
|
}
|
||||||
@@ -718,11 +718,10 @@ bool run() {
|
|||||||
test_top_level_array_example() &&
|
test_top_level_array_example() &&
|
||||||
test_array_of_objects_with_concept()
|
test_array_of_objects_with_concept()
|
||||||
#ifdef TEST_EMBED_SUPPORTED
|
#ifdef TEST_EMBED_SUPPORTED
|
||||||
&& test_embed_twitter_json()
|
&& test_embed_example_config_json()
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace compile_time_json_tests
|
} // namespace compile_time_json_tests
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ namespace big_integer_tests {
|
|||||||
std::string output = simdjson::to_string(doc);
|
std::string output = simdjson::to_string(doc);
|
||||||
// Raw digits should appear
|
// Raw digits should appear
|
||||||
ASSERT_TRUE(output.find("123456789012345678901") != std::string::npos);
|
ASSERT_TRUE(output.find("123456789012345678901") != std::string::npos);
|
||||||
// Must not be quoted — it's a number, not a string
|
// Must not be quoted - it's a number, not a string
|
||||||
ASSERT_EQUAL(output.find("\"123456789012345678901\""), std::string::npos);
|
ASSERT_EQUAL(output.find("\"123456789012345678901\""), std::string::npos);
|
||||||
TEST_SUCCEED();
|
TEST_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -475,11 +475,11 @@ bool unicode_test() {
|
|||||||
std::cout << "Running " << __func__ << std::endl;
|
std::cout << "Running " << __func__ << std::endl;
|
||||||
|
|
||||||
const char* json = R"({
|
const char* json = R"({
|
||||||
"greeting": "Hello, 世界!",
|
"greeting": "Hello, \u4e16\u754c!",
|
||||||
"emoji": "🎉🚀✨",
|
"emoji": "\ud83c\udf89\ud83d\ude80\u2728",
|
||||||
"arabic": "مرحبا",
|
"arabic": "\u0645\u0631\u062d\u0628\u0627",
|
||||||
"russian": "Привет",
|
"russian": "\u041f\u0440\u0438\u0432\u0435\u0442",
|
||||||
"mixed": "café résumé naïve"
|
"mixed": "caf\u00e9 r\u00e9sum\u00e9 na\u00efve"
|
||||||
})";
|
})";
|
||||||
|
|
||||||
simdjson::dom::parser parser;
|
simdjson::dom::parser parser;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public:
|
|||||||
return date_str;
|
return date_str;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
std::string date_str;
|
std::string date_str{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -52,8 +52,8 @@ auto tag_invoke(deserialize_tag, simdjson_value &val, MyDate& date) {
|
|||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
struct complicated_weather_data {
|
struct complicated_weather_data {
|
||||||
std::vector<MyDate> time;
|
std::vector<MyDate> time{};
|
||||||
std::vector<float> temperature;
|
std::vector<float> temperature{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -152,19 +152,19 @@ simdjson::padded_string json_cars =
|
|||||||
TEST_SUCCEED();
|
TEST_SUCCEED();
|
||||||
}
|
}
|
||||||
struct Player {
|
struct Player {
|
||||||
std::string username;
|
std::string username{};
|
||||||
int level;
|
int level{};
|
||||||
double health;
|
double health{};
|
||||||
};
|
};
|
||||||
struct BadPlayer {
|
struct BadPlayer {
|
||||||
int username; // Oops, should be string!
|
int username{}; // Oops, should be string!
|
||||||
int level;
|
int level{};
|
||||||
double health;
|
double health{};
|
||||||
};
|
};
|
||||||
struct OptionalPlayer {
|
struct OptionalPlayer {
|
||||||
std::string username;
|
std::string username{};
|
||||||
std::optional<int> level;
|
std::optional<int> level{};
|
||||||
double health;
|
double health{};
|
||||||
};
|
};
|
||||||
#if SIMDJSON_STATIC_REFLECTION
|
#if SIMDJSON_STATIC_REFLECTION
|
||||||
bool missing_key_player() {
|
bool missing_key_player() {
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ namespace wrong_type_error_tests {
|
|||||||
return false; \
|
return false; \
|
||||||
} \
|
} \
|
||||||
{ \
|
{ \
|
||||||
padded_string a_json(std::string(R"({ "a": )") + JSON + " }"); \
|
std::string a_json(R"({ "a": )"); a_json += JSON; a_json += " }"; \
|
||||||
std::cout << R"(- Subtest: get_)" << (#TYPE) << "() - JSON: " << a_json << std::endl; \
|
std::cout << R"(- Subtest: get_)" << (#TYPE) << "() - JSON: " << a_json << std::endl; \
|
||||||
if (!test_ondemand_doc(a_json, [&](auto doc_result) { \
|
if (!test_ondemand_doc(simdjson::pad(a_json), [&](auto doc_result) { \
|
||||||
ASSERT_ERROR( doc_result["a"].get_##TYPE(), (ERROR) ); \
|
ASSERT_ERROR( doc_result["a"].get_##TYPE(), (ERROR) ); \
|
||||||
return true; \
|
return true; \
|
||||||
})) { \
|
})) { \
|
||||||
|
|||||||
Reference in New Issue
Block a user