Skip to content

Commit 51e0507

Browse files
Merge pull request #37 from simdjson/using_reflection_for_simdjson_ondemand_daniel
Using reflection for simdjson ondemand daniel
2 parents 9d55b40 + 1faaaab commit 51e0507

2 files changed

Lines changed: 36 additions & 40 deletions

File tree

examples/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ add_compile_options(-Wall -Wextra -Weffc++ -Wsign-compare -Wshadow -Wwrite-strin
44
add_executable(example example.cpp)
55
target_link_libraries(example PRIVATE simdjson::serialization simdjson::simdjson)
66

7-
add_executable(example2 example2.cpp)
8-
target_link_libraries(example2 PRIVATE simdjson::serialization simdjson::simdjson)
7+
#add_executable(example2 example2.cpp)
8+
#target_link_libraries(example2 PRIVATE simdjson::serialization simdjson::simdjson)
99

1010
add_executable(example3 example3.cpp)
1111
target_link_libraries(example3 PRIVATE simdjson::serialization simdjson::simdjson)

examples/example3.cpp

Lines changed: 34 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "simdjson.h"
22
#include "simdjson/json_builder/json_builder.h"
3+
#include <cstdlib>
34
#include <string>
45
#include <vector>
56
#include <iostream>
@@ -68,8 +69,14 @@ tag_invoke(deserialize_tag, std::type_identity<T>, ondemand::value &val) {
6869
return vec;
6970
}
7071

72+
73+
///
74+
/// For simplicity, the definitions of invoke should be non-overlapping.
75+
/// If we provide both a specialization for a container and a specialization for a user-defined type,
76+
/// which one gets picked is maybe unclear???
77+
///
7178
template <typename T>
72-
requires json_builder::UserDefinedType<T>
79+
requires (json_builder::UserDefinedType<T> && ! PushableContainer<T>)
7380
simdjson_result<T>
7481
tag_invoke(deserialize_tag, std::type_identity<T>, ondemand::value &val) {
7582
ondemand::object obj;
@@ -79,27 +86,17 @@ tag_invoke(deserialize_tag, std::type_identity<T>, ondemand::value &val) {
7986
}
8087
T t;
8188
[:json_builder::expand(std::meta::nonstatic_data_members_of(^T)):] >> [&]<auto mem> {
82-
auto it = obj[to_string_view(std::meta::identifier_of(mem))];
89+
auto it = obj[(std::string_view)std::meta::identifier_of(mem)];
8390
using MemberType = typename std::remove_reference_t<decltype(t.[:mem:])>;
8491

8592
if constexpr (std::is_same_v<MemberType, int>) {
86-
auto int_result = it.get_int64();
87-
if (int_result.error()) throw std::runtime_error("Error getting int64");
88-
t.[:mem:] = static_cast<int>(int_result.value());
89-
} else if constexpr (std::is_same_v<MemberType, double>) {
90-
auto double_result = it.get_double();
91-
if (double_result.error()) throw std::runtime_error("Error getting double");
92-
t.[:mem:] = double_result.value();
93+
int64_t val;
94+
if(auto err = it.get(val); err) { return err; }
95+
t.[:mem:] = static_cast<int>(val);
9396
} else if constexpr (std::is_same_v<MemberType, std::string>) {
94-
auto string_result = it.get_string();
95-
if (string_result.error()) throw std::runtime_error("Error getting string");
96-
t.[:mem:] = std::string(string_result.value());
97-
} else if constexpr (std::is_same_v<MemberType, bool>) {
98-
auto bool_result = it.get_bool();
99-
if (bool_result.error()) throw std::runtime_error("Error getting bool");
100-
t.[:mem:] = bool_result.value();
97+
if(auto err = it.get_string(t.[:mem:]); err) { return err; }
10198
} else {
102-
t.[:mem:] = it.template get<MemberType>().value();
99+
if(auto err = it.get(t.[:mem:]); err) { return err; }
103100
}
104101
};
105102
return t;
@@ -112,34 +109,33 @@ int main() {
112109
std::string json_str = R"({"values": [1, 2, 3]})";
113110
ondemand::parser parser;
114111
auto doc = parser.iterate(json_str);
115-
116-
auto result = doc["values"].get<std::vector<int>>();
117-
if (result.error()) {
118-
std::cerr << "Error parsing JSON: " << result.error() << std::endl;
119-
return 1;
112+
std::vector<int> result;
113+
if(auto err = doc["values"].get<std::vector<int>>().get(result); err) {
114+
std::cerr << "Error parsing JSON: " << simdjson::error_message(err) << std::endl;
115+
return EXIT_FAILURE;
120116
}
121-
122-
std::vector<int> z = result.value();
123-
for (const int &x : z) {
117+
for (const int x : result) {
124118
std::cout << x << std::endl;
125119
}
126120

127-
// Test for user-defined type MyStruct
128-
std::string json_str3 = R"({"id": 1, "name": "example", "values": [1, 2, 3]})";
121+
/////////////
122+
/// Notice how we won't parse directly the *document* but a value inside the document.
123+
/// That's because the document is not an instance of a value in simdjson, and so the
124+
/// current patch would require a bit of extra work to make it work with both values
125+
/// and documents
126+
//////////////
127+
std::string json_str3 = R"({"toto":{"id": 1, "name": "example", "values": [4, 42, 43]}})";
129128
ondemand::parser parser3;
130129
auto doc3 = parser3.iterate(json_str3);
131130

132-
auto result3 = doc3.get<MyStruct>();
133-
if (result3.error()) {
134-
std::cerr << "Error parsing JSON: " << result3.error() << std::endl;
135-
return 1;
131+
MyStruct result3;
132+
if(auto err = doc3["toto"].get(result3); err) {
133+
std::cerr << "Error parsing JSON: " << simdjson::error_message(err) << std::endl;
134+
return EXIT_FAILURE;
136135
}
137-
138-
MyStruct my_struct = result3.value();
139-
std::cout << "ID: " << my_struct.id << ", Name: " << my_struct.name << ", Values: ";
140-
for (const int &x : my_struct.values) {
141-
std::cout << x << " ";
136+
std::cout << "ID: " << result3.id << ", Name: " << result3.name ;
137+
for (const int x : result3.values) {
138+
std::cout << x << std::endl;
142139
}
143-
std::cout << std::endl;
144-
return 0;
140+
return EXIT_SUCCESS;
145141
}

0 commit comments

Comments
 (0)