Skip to content

Commit 9d55b40

Browse files
Trying to use reflection + generic implementation of ondemand::value::get() without success...
1 parent 5347a93 commit 9d55b40

1 file changed

Lines changed: 73 additions & 4 deletions

File tree

examples/example3.cpp

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
11
#include "simdjson.h"
2+
#include "simdjson/json_builder/json_builder.h"
23
#include <string>
34
#include <vector>
45
#include <iostream>
56
#include <type_traits>
67

78
using namespace simdjson;
89

10+
// Example user-defined type
11+
struct MyStruct {
12+
int id;
13+
std::string name;
14+
std::vector<int> values;
15+
};
16+
17+
// Example of simple user-defined type
18+
struct MySimpleStruct {
19+
int id;
20+
std::string name;
21+
};
22+
923
namespace simdjson {
1024

1125
template <typename T>
@@ -16,7 +30,7 @@ concept PushableContainer =
1630
!std::is_same_v<T, std::string_view> &&
1731
!std::is_same_v<T, const char*>;
1832

19-
// Specialize tag_invoke for std::vector<int>
33+
// Specialize tag_invoke for containers
2034
template <typename T>
2135
requires PushableContainer<T>
2236
simdjson_result<T>
@@ -52,11 +66,49 @@ tag_invoke(deserialize_tag, std::type_identity<T>, ondemand::value &val) {
5266
}
5367

5468
return vec;
69+
}
70+
71+
template <typename T>
72+
requires json_builder::UserDefinedType<T>
73+
simdjson_result<T>
74+
tag_invoke(deserialize_tag, std::type_identity<T>, ondemand::value &val) {
75+
ondemand::object obj;
76+
auto error = val.get_object().get(obj);
77+
if (error) {
78+
return error;
79+
}
80+
T t;
81+
[:json_builder::expand(std::meta::nonstatic_data_members_of(^T)):] >> [&]<auto mem> {
82+
auto it = obj[to_string_view(std::meta::identifier_of(mem))];
83+
using MemberType = typename std::remove_reference_t<decltype(t.[:mem:])>;
84+
85+
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+
} 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();
101+
} else {
102+
t.[:mem:] = it.template get<MemberType>().value();
103+
}
104+
};
105+
return t;
55106
}
56107

57-
} // namespace simdjson
108+
} // simdjson
58109

59110
int main() {
111+
// Test for std::vector<int>
60112
std::string json_str = R"({"values": [1, 2, 3]})";
61113
ondemand::parser parser;
62114
auto doc = parser.iterate(json_str);
@@ -67,10 +119,27 @@ int main() {
67119
return 1;
68120
}
69121

70-
std::vector<int> my_struct = result.value();
71-
for (const int &x : my_struct) {
122+
std::vector<int> z = result.value();
123+
for (const int &x : z) {
72124
std::cout << x << std::endl;
73125
}
74126

127+
// Test for user-defined type MyStruct
128+
std::string json_str3 = R"({"id": 1, "name": "example", "values": [1, 2, 3]})";
129+
ondemand::parser parser3;
130+
auto doc3 = parser3.iterate(json_str3);
131+
132+
auto result3 = doc3.get<MyStruct>();
133+
if (result3.error()) {
134+
std::cerr << "Error parsing JSON: " << result3.error() << std::endl;
135+
return 1;
136+
}
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 << " ";
142+
}
143+
std::cout << std::endl;
75144
return 0;
76145
}

0 commit comments

Comments
 (0)