diff --git a/include/ylt/thirdparty/iguana/json_reader.hpp b/include/ylt/thirdparty/iguana/json_reader.hpp index 16f34a802..ba02397ad 100644 --- a/include/ylt/thirdparty/iguana/json_reader.hpp +++ b/include/ylt/thirdparty/iguana/json_reader.hpp @@ -13,6 +13,9 @@ template , int> = 0> IGUANA_INLINE void parse_item(U &value, It &&it, It &&end); +template , int> = 0> +IGUANA_INLINE void parse_item(U &value, It &&it, It &&end); + template , int> = 0> IGUANA_INLINE void parse_item(U &value, It &&it, It &&end) { from_json(value, it, end); @@ -445,7 +448,7 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end) { } } -template , int> = 0> +template , int>> IGUANA_INLINE void parse_item(U &value, It &&it, It &&end) { skip_ws(it, end); if (it < end && *it == '"') @@ -458,7 +461,12 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end) { } else { using value_type = typename std::remove_reference_t::element_type; - value = std::make_unique(); + if constexpr (unique_ptr_v) { + value = std::make_unique(); + } + else { + value = std::make_shared(); + } parse_item(*value, it, end); } } @@ -632,7 +640,7 @@ template void parse(jvalue &result, It &&it, It &&end); template -inline void parse_array(jarray &result, It &&it, It &&end) { +inline void parse(jarray &result, It &&it, It &&end) { skip_ws(it, end); match<'['>(it, end); if (*it == ']') @@ -660,7 +668,7 @@ inline void parse_array(jarray &result, It &&it, It &&end) { } template -inline void parse_object(jobject &result, It &&it, It &&end) { +inline void parse(jobject &result, It &&it, It &&end) { skip_ws(it, end); match<'{'>(it, end); if (*it == '}') @@ -740,11 +748,11 @@ inline void parse(jvalue &result, It &&it, It &&end) { break; case '[': result.template emplace(); - parse_array(std::get(result), it, end); + parse(std::get(result), it, end); break; case '{': { result.template emplace(); - parse_object(std::get(result), it, end); + parse(std::get(result), it, end); break; } default: @@ -754,6 +762,7 @@ inline void parse(jvalue &result, It &&it, It &&end) { skip_ws(it, end); } +// when Is_view is true, parse str as string_view template inline void parse(jvalue &result, It &&it, It &&end, std::error_code &ec) { try { diff --git a/include/ylt/thirdparty/iguana/json_writer.hpp b/include/ylt/thirdparty/iguana/json_writer.hpp index d8cad6fe0..3d77ff638 100644 --- a/include/ylt/thirdparty/iguana/json_writer.hpp +++ b/include/ylt/thirdparty/iguana/json_writer.hpp @@ -24,7 +24,7 @@ template , int> = 0> + std::enable_if_t, int> = 0> IGUANA_INLINE void render_json_value(Stream &ss, const T &v); template , int>> +template , int>> IGUANA_INLINE void render_json_value(Stream &ss, const T &v) { if (v) { render_json_value(ss, *v); diff --git a/include/ylt/thirdparty/iguana/util.hpp b/include/ylt/thirdparty/iguana/util.hpp index 79ebe8bf1..b16c98ed2 100644 --- a/include/ylt/thirdparty/iguana/util.hpp +++ b/include/ylt/thirdparty/iguana/util.hpp @@ -122,6 +122,13 @@ template constexpr inline bool unique_ptr_v = is_template_instant_of>::value; +template +constexpr inline bool shared_ptr_v = + is_template_instant_of>::value; + +template +constexpr inline bool smart_ptr_v = shared_ptr_v || unique_ptr_v; + template struct is_variant : std::false_type {}; @@ -134,7 +141,7 @@ constexpr inline bool variant_v = is_variant>::value; template constexpr inline bool non_refletable_v = container_v || c_array_v || tuple_v || optional_v || - unique_ptr_v || std::is_fundamental_v> || + smart_ptr_v || std::is_fundamental_v> || variant_v; template @@ -144,6 +151,29 @@ template constexpr inline bool plain_v = string_container_v || num_v || char_v || bool_v || enum_v; +template +struct underline_type { + using type = T; +}; + +template +struct underline_type> { + using type = typename underline_type::type; +}; + +template +struct underline_type> { + using type = typename underline_type::type; +}; + +template +struct underline_type> { + using type = typename underline_type::type; +}; + +template +using underline_type_t = typename underline_type>::type; + template IGUANA_INLINE void match(It &&it, It &&end) { const auto n = static_cast(std::distance(it, end)); diff --git a/include/ylt/thirdparty/iguana/xml_reader.hpp b/include/ylt/thirdparty/iguana/xml_reader.hpp index f6cae0be0..385b0a0e2 100644 --- a/include/ylt/thirdparty/iguana/xml_reader.hpp +++ b/include/ylt/thirdparty/iguana/xml_reader.hpp @@ -12,7 +12,7 @@ template , int> = 0> IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, std::string_view name); -template , int> = 0> +template , int> = 0> IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, std::string_view name); @@ -178,10 +178,16 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, } } -template , int>> +template , int>> IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, std::string_view name) { - value = std::make_unique::element_type>(); + if constexpr (unique_ptr_v) { + value = std::make_unique::element_type>(); + } + else { + value = std::make_shared::element_type>(); + } + parse_item(*value, it, end, name); } diff --git a/include/ylt/thirdparty/iguana/xml_writer.hpp b/include/ylt/thirdparty/iguana/xml_writer.hpp index ba915725f..9d73b9288 100644 --- a/include/ylt/thirdparty/iguana/xml_writer.hpp +++ b/include/ylt/thirdparty/iguana/xml_writer.hpp @@ -119,7 +119,7 @@ IGUANA_INLINE void render_xml_value(Stream &ss, const T &value, } template , int> = 0> + std::enable_if_t, int> = 0> IGUANA_INLINE void render_xml_value(Stream &ss, const T &value, std::string_view name) { if (value) { @@ -142,7 +142,8 @@ template , int>> IGUANA_INLINE void render_xml_value(Stream &ss, const T &value, std::string_view name) { - using value_type = typename std::remove_cvref_t::value_type; + using value_type = + underline_type_t::value_type>; for (const auto &v : value) { if constexpr (attr_v) { render_xml_value(ss, v, name); @@ -163,7 +164,7 @@ IGUANA_INLINE void render_xml_value(Stream &ss, T &&t, std::string_view name) { for_each(std::forward(t), [&](const auto &v, auto i) IGUANA__INLINE_LAMBDA { using M = decltype(iguana_reflect_type(std::forward(t))); - using value_type = std::remove_cvref_t; + using value_type = underline_type_t; constexpr auto Idx = decltype(i)::value; constexpr auto Count = M::value(); constexpr std::string_view tag_name = diff --git a/include/ylt/thirdparty/iguana/yaml_reader.hpp b/include/ylt/thirdparty/iguana/yaml_reader.hpp index ea0f31213..5cb40ff34 100644 --- a/include/ylt/thirdparty/iguana/yaml_reader.hpp +++ b/include/ylt/thirdparty/iguana/yaml_reader.hpp @@ -241,7 +241,7 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces) { template , int> = 0> IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces); -template , int> = 0> +template , int> = 0> IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces); // minspaces : The minimum indentation @@ -418,12 +418,17 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces) { } } -template , int>> +template , int>> IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces) { using T = std::remove_reference_t; - value = std::make_unique(); + if constexpr (unique_ptr_v) { + value = std::make_unique(); + } + else { + value = std::make_shared(); + } static_assert(!string_v, - "unique_ptr is not allowed"); + "smart_ptr is not allowed"); parse_item(*value, it, end, min_spaces); } diff --git a/include/ylt/thirdparty/iguana/yaml_writer.hpp b/include/ylt/thirdparty/iguana/yaml_writer.hpp index 8b8f3264c..b6228b99a 100644 --- a/include/ylt/thirdparty/iguana/yaml_writer.hpp +++ b/include/ylt/thirdparty/iguana/yaml_writer.hpp @@ -80,7 +80,7 @@ IGUANA_INLINE void render_yaml_value(Stream &ss, const T &val, size_t min_spaces); template , int> = 0> + std::enable_if_t, int> = 0> IGUANA_INLINE void render_yaml_value(Stream &ss, const T &val, size_t min_spaces); @@ -132,7 +132,7 @@ IGUANA_INLINE void render_yaml_value(Stream &ss, const T &val, } } -template , int>> +template , int>> IGUANA_INLINE void render_yaml_value(Stream &ss, const T &val, size_t min_spaces) { if (!val) { @@ -174,7 +174,7 @@ template , int> = 0> IGUANA_INLINE void to_yaml(T &&t, Stream &s) { if constexpr (tuple_v || map_container_v || sequence_container_v || - optional_v || unique_ptr_v) + optional_v || smart_ptr_v) render_yaml_value(s, std::forward(t), 0); else static_assert(!sizeof(T), "don't suppport this type"); diff --git a/src/struct_xml/examples/main.cpp b/src/struct_xml/examples/main.cpp index 0e7e534b3..dc0b6e7b5 100644 --- a/src/struct_xml/examples/main.cpp +++ b/src/struct_xml/examples/main.cpp @@ -255,7 +255,32 @@ void test_inner_object() { assert(obj1.get_name() == "tom"); } +struct shared_object { + std::shared_ptr>> vec; + std::string b; + std::shared_ptr c; + std::vector> d; +}; +REFLECTION(shared_object, vec, b, c, d); + +void test_sp() { + auto vec = std::make_shared>>(); + vec->push_back(std::make_unique(42)); + vec->push_back(std::make_unique(21)); + shared_object contents{std::move(vec), + "test", + std::make_shared(24), + {std::make_shared(1), std::make_shared(4)}}; + std::string str; + iguana::to_xml(contents, str); + + shared_object cont; + iguana::from_xml(cont, str); // throw exception. + std::cout << cont.b << "\n"; +} + int main() { + test_sp(); basic_usage(); type_to_string(); nested_xml();