diff --git a/iguana/json_reader.hpp b/iguana/json_reader.hpp index a8fee7bb..b41b19c8 100644 --- a/iguana/json_reader.hpp +++ b/iguana/json_reader.hpp @@ -499,13 +499,45 @@ IGUANA_INLINE void skip_object_value(It &&it, It &&end) { } } +template +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 +using variant_element_t = std::remove_reference_t( + std::declval>()))>; + +template +IGUANA_INLINE void from_json_variant(U &value, It &it, It &end, + std::index_sequence) { + bool r = false; + It temp_it = it; + It temp_end = end; + ((void)(!r && (r = from_json_variant_impl< + variant_element_t>>( + value, it, end, temp_it, temp_end), + true)), + ...); + it = temp_it; + end = temp_end; +} + template , 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>>{}); } } // namespace detail diff --git a/test/test.cpp b/test/test.cpp index 616e3441..3200ca9a 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -175,9 +175,10 @@ REFLECTION(inner_struct, x, y, z); struct nest_t { std::string name; my_space::inner_struct value; - std::variant var; + std::variant var; + std::variant var2; }; -REFLECTION(nest_t, name, value, var); +REFLECTION(nest_t, name, value, var, var2); struct point_t1 { int x; @@ -199,14 +200,16 @@ TEST_CASE("test double to int") { } TEST_CASE("test variant") { - std::variant var; - var = 1; - nest_t v{"Hi", {1, 2, 3}, var}, v2; + std::variant 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") {