mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
c806e955c4
* Initial work on JSON builder * moving the files back to ondemand for now. * tweak * more later * update * minor edits * dropping vs arm (missing support) * adding tests. we still specialized write_string_escaped * tweaking * fix typo * tweaking the approach * minor fix * missing store * another missing store * Attempt at fixing failing serialization tests. (#2292) * Fixing appeand_float typo (#2294) * applying a couple of fixes * updating single header * fix for pre C++17 if constexpr * Fixing unused argument problem and updating the singleheader file * various pedantic fixes * Sketch of builder * reordering. * simplify * Adding draft of static reflection based deserialization * Updating simdjson singleheader * patching the automated deserialization. * automated * Adding support for smart pointers of user defined types. * Adding specialization for smart pointers for basic types. I think it is highly likely that this can be done in a more generic way. * Referncing a later version of rapidjson that fixed the issue related with assignment attempt of a const variable for GenericStringRef class. * guarding the tests * adding documentation for string_builder * saving * rename to 'append' * saving * non-functional benchmarks (#2342) * non-functional benchmarks * Fix typo * various fixes * tweaking --------- Co-authored-by: Daniel Lemire <dlemire@lemire.me> Co-authored-by: Francisco Geiman Thiesen <franciscogthiesen@gmail.com> * tuning * various minor fixes * minor tweak * minor simplification * updating amal * adding a cast * update * fancy casting * removing dead code * Pushing latest changes. CITM benchmark is still not working. * Still not working, but now I am getting only 10 errors. * add static reflection benchmark to 'large random' benchmark and allows (#2349) deserialization (with static reflection) from objects and arrays. Co-authored-by: Daniel Lemire <dlemire@lemire.me> * Removing std::map from CitmCatalog definition, since that is not currently supported. * Added free to rust bench, segfault is still happening.. * The syntax changed: ^E became ^^E. (#2350) * The syntax changed: ^E became ^^E. * guarding --------- Co-authored-by: Daniel Lemire <dlemire@lemire.me> * Adding support for string_view_keyed_map types. * Adding concepts as a conditional include. * updating single-header * Adding concepts to ondemand deps * rust benchmark is finally working * Fixing small typo in docs. * adding docker config and instructions so that our users can test the static reflection (#2358) * adding docker config and instructions so that our users can test the static reflection * completing the instructions * pruning white spaces --------- Co-authored-by: Daniel Lemire <dlemire@lemire.me> * minor optimizations on the JSON builder branch * avoiding undef behaviour * saving * somewhat nicer builder * make it possible to run just one benchmark * adding linux perf * fixing minor issue * updating swar * Adding real world compilation benchmark (#2379) * Adding compilation benchmark for json parsing with and without reflection * Moving it to the benchmark folder, also reducing a bit the number of iterations. * Removing script from root folder. * Reducing number of iterations * Update benchmark/benchmark_reflection_usage_compilation.sh Co-authored-by: Daniel Lemire <daniel@lemire.me> * Update benchmark/benchmark_reflection_usage_compilation.sh Co-authored-by: Daniel Lemire <daniel@lemire.me> * Update benchmark/benchmark_reflection_usage_compilation.sh Co-authored-by: Daniel Lemire <daniel@lemire.me> * Making the script more customizable and also test whether the compiler being used supports reflection before actually running the benchmark --------- Co-authored-by: Daniel Lemire <daniel@lemire.me> * Using define_static_string from https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3491r2.html (#2389) * Applying changes needed after latest reflection paper updates. * Working, but no template for yet. * Updating single-header to incldue the use of define_static_string. * copying over master --------- Co-authored-by: Daniel Lemire <dlemire@lemire.me> Co-authored-by: Francisco Geiman Thiesen <franciscogthiesen@gmail.com>
140 lines
5.8 KiB
C++
140 lines
5.8 KiB
C++
#if SIMDJSON_SUPPORTS_DESERIALIZATION
|
|
|
|
#ifndef SIMDJSON_ONDEMAND_DESERIALIZE_H
|
|
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
|
#define SIMDJSON_ONDEMAND_DESERIALIZE_H
|
|
#include "simdjson/generic/ondemand/base.h"
|
|
#include "simdjson/generic/ondemand/array.h"
|
|
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
|
|
|
#include <concepts>
|
|
namespace simdjson {
|
|
|
|
namespace tag_invoke_fn_ns {
|
|
void tag_invoke();
|
|
|
|
struct tag_invoke_fn {
|
|
template <typename Tag, typename... Args>
|
|
requires requires(Tag tag, Args &&...args) {
|
|
tag_invoke(std::forward<Tag>(tag), std::forward<Args>(args)...);
|
|
}
|
|
constexpr auto operator()(Tag tag, Args &&...args) const
|
|
noexcept(noexcept(tag_invoke(std::forward<Tag>(tag),
|
|
std::forward<Args>(args)...)))
|
|
-> decltype(tag_invoke(std::forward<Tag>(tag),
|
|
std::forward<Args>(args)...)) {
|
|
return tag_invoke(std::forward<Tag>(tag), std::forward<Args>(args)...);
|
|
}
|
|
};
|
|
} // namespace tag_invoke_fn_ns
|
|
|
|
inline namespace tag_invoke_ns {
|
|
inline constexpr tag_invoke_fn_ns::tag_invoke_fn tag_invoke = {};
|
|
} // namespace tag_invoke_ns
|
|
|
|
template <typename Tag, typename... Args>
|
|
concept tag_invocable = requires(Tag tag, Args... args) {
|
|
tag_invoke(std::forward<Tag>(tag), std::forward<Args>(args)...);
|
|
};
|
|
|
|
template <typename Tag, typename... Args>
|
|
concept nothrow_tag_invocable =
|
|
tag_invocable<Tag, Args...> && requires(Tag tag, Args... args) {
|
|
{
|
|
tag_invoke(std::forward<Tag>(tag), std::forward<Args>(args)...)
|
|
} noexcept;
|
|
};
|
|
|
|
template <typename Tag, typename... Args>
|
|
using tag_invoke_result =
|
|
std::invoke_result<decltype(tag_invoke), Tag, Args...>;
|
|
|
|
template <typename Tag, typename... Args>
|
|
using tag_invoke_result_t =
|
|
std::invoke_result_t<decltype(tag_invoke), Tag, Args...>;
|
|
|
|
template <auto &Tag> using tag_t = std::decay_t<decltype(Tag)>;
|
|
|
|
|
|
struct deserialize_tag;
|
|
|
|
/// These types are deserializable in a built-in way
|
|
template <typename> struct is_builtin_deserializable : std::false_type {};
|
|
template <> struct is_builtin_deserializable<int64_t> : std::true_type {};
|
|
template <> struct is_builtin_deserializable<uint64_t> : std::true_type {};
|
|
template <> struct is_builtin_deserializable<double> : std::true_type {};
|
|
template <> struct is_builtin_deserializable<bool> : std::true_type {};
|
|
template <> struct is_builtin_deserializable<SIMDJSON_IMPLEMENTATION::ondemand::array> : std::true_type {};
|
|
template <> struct is_builtin_deserializable<SIMDJSON_IMPLEMENTATION::ondemand::object> : std::true_type {};
|
|
template <> struct is_builtin_deserializable<SIMDJSON_IMPLEMENTATION::ondemand::value> : std::true_type {};
|
|
template <> struct is_builtin_deserializable<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string> : std::true_type {};
|
|
template <> struct is_builtin_deserializable<std::string_view> : std::true_type {};
|
|
|
|
template <typename T>
|
|
concept is_builtin_deserializable_v = is_builtin_deserializable<T>::value;
|
|
|
|
template <typename T, typename ValT = SIMDJSON_IMPLEMENTATION::ondemand::value>
|
|
concept custom_deserializable = tag_invocable<deserialize_tag, ValT&, T&>;
|
|
|
|
template <typename T, typename ValT = SIMDJSON_IMPLEMENTATION::ondemand::value>
|
|
concept deserializable = custom_deserializable<T, ValT> || is_builtin_deserializable_v<T>;
|
|
|
|
template <typename T, typename ValT = SIMDJSON_IMPLEMENTATION::ondemand::value>
|
|
concept nothrow_custom_deserializable = nothrow_tag_invocable<deserialize_tag, ValT&, T&>;
|
|
|
|
// built-in types are noexcept and if an error happens, the value simply gets ignored and the error is returned.
|
|
template <typename T, typename ValT = SIMDJSON_IMPLEMENTATION::ondemand::value>
|
|
concept nothrow_deserializable = nothrow_custom_deserializable<T, ValT> || is_builtin_deserializable_v<T>;
|
|
|
|
/// Deserialize Tag
|
|
inline constexpr struct deserialize_tag {
|
|
using array_type = SIMDJSON_IMPLEMENTATION::ondemand::array;
|
|
using object_type = SIMDJSON_IMPLEMENTATION::ondemand::object;
|
|
using value_type = SIMDJSON_IMPLEMENTATION::ondemand::value;
|
|
using document_type = SIMDJSON_IMPLEMENTATION::ondemand::document;
|
|
using document_reference_type = SIMDJSON_IMPLEMENTATION::ondemand::document_reference;
|
|
|
|
// Customization Point for array
|
|
template <typename T>
|
|
requires custom_deserializable<T, value_type>
|
|
[[nodiscard]] constexpr /* error_code */ auto operator()(array_type &object, T& output) const noexcept(nothrow_custom_deserializable<T, value_type>) {
|
|
return tag_invoke(*this, object, output);
|
|
}
|
|
|
|
// Customization Point for object
|
|
template <typename T>
|
|
requires custom_deserializable<T, value_type>
|
|
[[nodiscard]] constexpr /* error_code */ auto operator()(object_type &object, T& output) const noexcept(nothrow_custom_deserializable<T, value_type>) {
|
|
return tag_invoke(*this, object, output);
|
|
}
|
|
|
|
// Customization Point for value
|
|
template <typename T>
|
|
requires custom_deserializable<T, value_type>
|
|
[[nodiscard]] constexpr /* error_code */ auto operator()(value_type &object, T& output) const noexcept(nothrow_custom_deserializable<T, value_type>) {
|
|
return tag_invoke(*this, object, output);
|
|
}
|
|
|
|
// Customization Point for document
|
|
template <typename T>
|
|
requires custom_deserializable<T, document_type>
|
|
[[nodiscard]] constexpr /* error_code */ auto operator()(document_type &object, T& output) const noexcept(nothrow_custom_deserializable<T, document_type>) {
|
|
return tag_invoke(*this, object, output);
|
|
}
|
|
|
|
// Customization Point for document reference
|
|
template <typename T>
|
|
requires custom_deserializable<T, document_reference_type>
|
|
[[nodiscard]] constexpr /* error_code */ auto operator()(document_reference_type &object, T& output) const noexcept(nothrow_custom_deserializable<T, document_reference_type>) {
|
|
return tag_invoke(*this, object, output);
|
|
}
|
|
|
|
|
|
} deserialize{};
|
|
|
|
} // namespace simdjson
|
|
|
|
#endif // SIMDJSON_ONDEMAND_DESERIALIZE_H
|
|
#endif // SIMDJSON_SUPPORTS_DESERIALIZATION
|
|
|