Skip to content

Commit

Permalink
Merge pull request #251 from qicosmos/fix_variant
Browse files Browse the repository at this point in the history
  • Loading branch information
qicosmos authored Apr 10, 2024
2 parents b442ba3 + 6a02beb commit cc352a9
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 11 deletions.
42 changes: 37 additions & 5 deletions iguana/json_reader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -499,13 +499,45 @@ IGUANA_INLINE void skip_object_value(It &&it, It &&end) {
}
}

template <typename value_type, typename U, typename It>
IGUANA_INLINE bool from_json_variant_impl(U &value, It it, It end, It &temp_it,
It &temp_end) {
try {
value_type val;
from_json_impl(val, it, end);
value = val;
temp_it = it;
temp_end = end;
return true;
} catch (std::exception &ex) {
return false;
}
}

template <size_t Idx, typename T>
using variant_element_t = std::remove_reference_t<decltype(std::get<Idx>(
std::declval<std::remove_reference_t<T>>()))>;

template <typename U, typename It, size_t... Idx>
IGUANA_INLINE void from_json_variant(U &value, It &it, It &end,
std::index_sequence<Idx...>) {
bool r = false;
It temp_it = it;
It temp_end = end;
((void)(!r && (r = from_json_variant_impl<
variant_element_t<Idx, std::remove_reference_t<U>>>(
value, it, end, temp_it, temp_end),
true)),
...);
it = temp_it;
end = temp_end;
}

template <typename U, typename It, std::enable_if_t<variant_v<U>, int> = 0>
IGUANA_INLINE void from_json_impl(U &value, It &&it, It &&end) {
std::visit(
[&](auto &val) {
from_json_impl(val, it, end);
},
value);
from_json_variant(value, it, end,
std::make_index_sequence<
std::variant_size_v<std::remove_reference_t<U>>>{});
}
} // namespace detail

Expand Down
15 changes: 9 additions & 6 deletions test/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,10 @@ REFLECTION(inner_struct, x, y, z);
struct nest_t {
std::string name;
my_space::inner_struct value;
std::variant<int, std::string> var;
std::variant<int, std::string, double> var;
std::variant<int, std::string, my_space::inner_struct> var2;
};
REFLECTION(nest_t, name, value, var);
REFLECTION(nest_t, name, value, var, var2);

struct point_t1 {
int x;
Expand All @@ -199,14 +200,16 @@ TEST_CASE("test double to int") {
}

TEST_CASE("test variant") {
std::variant<int, std::string> var;
var = 1;
nest_t v{"Hi", {1, 2, 3}, var}, v2;
std::variant<int, std::string, double> var;
var = "test";
nest_t v{"Hi", {1, 2, 3}, var, my_space::inner_struct{2, 4, 6}};
std::string s;
iguana::to_json(v, s);
std::cout << s << std::endl;

nest_t v2;
iguana::from_json(v2, s);
CHECK(v.name == v2.name);
CHECK(v.var == v2.var);
}

TEST_CASE("test from issues") {
Expand Down

0 comments on commit cc352a9

Please sign in to comment.