diff --git a/iguana/detail/pb_type.hpp b/iguana/detail/pb_type.hpp index 1b268cce..2d17cb8e 100644 --- a/iguana/detail/pb_type.hpp +++ b/iguana/detail/pb_type.hpp @@ -88,7 +88,7 @@ inline bool operator<(const sfixed64_t& lhs, const sfixed64_t& rhs) { return lhs.val < rhs.val; } -template +template > constexpr bool is_pb_type_v = std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || diff --git a/iguana/dynamic.hpp b/iguana/dynamic.hpp index 86f0a177..98fccdd1 100644 --- a/iguana/dynamic.hpp +++ b/iguana/dynamic.hpp @@ -35,6 +35,14 @@ struct base_impl : public base { from_xml_adl((iguana_adl_t*)nullptr, *(static_cast(this)), str); } + void to_yaml(std::string& str) override { + to_yaml_adl((iguana_adl_t*)nullptr, *(static_cast(this)), str); + } + + void from_yaml(std::string_view str) override { + from_yaml_adl((iguana_adl_t*)nullptr, *(static_cast(this)), str); + } + iguana::detail::field_info get_field_info(std::string_view name) override { static constexpr auto map = iguana::get_members(); iguana::detail::field_info info{}; diff --git a/iguana/reflection.hpp b/iguana/reflection.hpp index e1524e60..9579ce8e 100644 --- a/iguana/reflection.hpp +++ b/iguana/reflection.hpp @@ -567,6 +567,8 @@ struct base { virtual void from_xml(std::string_view str) {} virtual void to_json(std::string &str) {} virtual void from_json(std::string_view str) {} + virtual void to_yaml(std::string &str) {} + virtual void from_yaml(std::string_view str) {} virtual std::vector get_fields_name() { return {}; } virtual iguana::detail::field_info get_field_info(std::string_view name) { return {}; diff --git a/iguana/util.hpp b/iguana/util.hpp index 3f6768a9..2d89e74d 100644 --- a/iguana/util.hpp +++ b/iguana/util.hpp @@ -297,8 +297,8 @@ IGUANA_INLINE void write_string_with_escape(const Ch* it, SizeType length, template IGUANA_INLINE constexpr bool has_duplicate(const std::array& arr) { - for (int i = 0; i < arr.size(); i++) { - for (int j = i + 1; j < arr.size(); j++) { + for (size_t i = 0; i < arr.size(); i++) { + for (size_t j = i + 1; j < arr.size(); j++) { if (arr[i] == arr[j]) { return true; } diff --git a/iguana/xml_reader.hpp b/iguana/xml_reader.hpp index 2047eadc..8b9c908f 100644 --- a/iguana/xml_reader.hpp +++ b/iguana/xml_reader.hpp @@ -9,20 +9,20 @@ namespace iguana { namespace detail { template , int> = 0> -IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, - std::string_view name); +IGUANA_INLINE void xml_parse_item(U &value, It &&it, It &&end, + std::string_view name); template , int> = 0> -IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, - std::string_view name); +IGUANA_INLINE void xml_parse_item(U &value, It &&it, It &&end, + std::string_view name); template , int> = 0> -IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, - std::string_view name); +IGUANA_INLINE void xml_parse_item(U &value, It &&it, It &&end, + std::string_view name); template , int> = 0> -IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, - std::string_view name); +IGUANA_INLINE void xml_parse_item(U &value, It &&it, It &&end, + std::string_view name); template , int> = 0> IGUANA_INLINE void xml_parse_value(U &&value, It &&begin, It &&end) { @@ -127,8 +127,8 @@ IGUANA_INLINE void parse_attr(U &&value, It &&it, It &&end) { } template , int> = 0> -IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, - std::string_view name) { +IGUANA_INLINE void xml_parse_item(U &value, It &&it, It &&end, + std::string_view name) { skip_till<'>'>(it, end); ++it; skip_sapces_and_newline(it, end); @@ -139,16 +139,16 @@ 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, - std::string_view name) { - parse_item(value.val, it, end, name); +IGUANA_INLINE void xml_parse_item(U &value, It &&it, It &&end, + std::string_view name) { + xml_parse_item(value.val, it, end, name); } template , int> = 0> -IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, - std::string_view name) { - parse_item(value.emplace_back(), it, end, name); +IGUANA_INLINE void xml_parse_item(U &value, It &&it, It &&end, + std::string_view name) { + xml_parse_item(value.emplace_back(), it, end, name); skip_sapces_and_newline(it, end); while (it != end) { match<'<'>(it, end); @@ -166,27 +166,27 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, it = start - 1; return; } - parse_item(value.emplace_back(), it, end, name); + xml_parse_item(value.emplace_back(), it, end, name); skip_sapces_and_newline(it, end); } } template , int> = 0> -IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, - std::string_view name) { +IGUANA_INLINE void xml_parse_item(U &value, It &&it, It &&end, + std::string_view name) { throw std::bad_function_call(); } template , int> = 0> -IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, - std::string_view name) { +IGUANA_INLINE void xml_parse_item(U &value, It &&it, It &&end, + std::string_view name) { throw std::bad_function_call(); } template , int>> -IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, - std::string_view name) { +IGUANA_INLINE void xml_parse_item(U &value, It &&it, It &&end, + std::string_view name) { using value_type = typename std::remove_reference_t::value_type; skip_till<'>'>(it, end); if (*(it - 1) == '/') @@ -211,13 +211,13 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, match_close_tag(it, end, name); } else { - parse_item(value.emplace(), it, end, name); + xml_parse_item(value.emplace(), it, end, name); } } template , int>> -IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, - std::string_view name) { +IGUANA_INLINE void xml_parse_item(U &value, It &&it, It &&end, + std::string_view name) { if constexpr (unique_ptr_v) { value = std::make_unique::element_type>(); } @@ -225,14 +225,14 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, value = std::make_shared::element_type>(); } - parse_item(*value, it, end, name); + xml_parse_item(*value, it, end, name); } template , int>> -IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, - std::string_view name) { +IGUANA_INLINE void xml_parse_item(U &value, It &&it, It &&end, + std::string_view name) { parse_attr(value.attr(), it, end); - parse_item(value.value(), it, end, name); + xml_parse_item(value.value(), it, end, name); } // /> or skip and until the @@ -393,8 +393,8 @@ IGUANA_INLINE void check_required(std::string_view key_set) { } template , int>> -IGUANA_INLINE void parse_item(T &value, It &&it, It &&end, - std::string_view name) { +IGUANA_INLINE void xml_parse_item(T &value, It &&it, It &&end, + std::string_view name) { using U = std::decay_t; constexpr auto cdata_idx = get_type_index(); skip_till<'>'>(it, end); @@ -425,7 +425,7 @@ IGUANA_INLINE void parse_item(T &value, It &&it, It &&end, if (parse_done || key != st_key) IGUANA_UNLIKELY { return; } if constexpr (!cdata_v) { - parse_item(value.*member_ptr, it, end, key); + xml_parse_item(value.*member_ptr, it, end, key); if constexpr (iguana::has_iguana_required_arr_v) { key_set.append(key).append(", "); } @@ -459,7 +459,7 @@ IGUANA_INLINE void parse_item(T &value, It &&it, It &&end, "type must be memberptr"); using V = std::remove_reference_t; if constexpr (!cdata_v) { - parse_item(value.*member_ptr, it, end, key); + xml_parse_item(value.*member_ptr, it, end, key); if constexpr (iguana::has_iguana_required_arr_v) { key_set.append(key).append(", "); } @@ -497,7 +497,7 @@ IGUANA_INLINE void from_xml(U &value, It &&it, It &&end) { std::string_view key = std::string_view{&*start, static_cast(std::distance(start, it))}; detail::parse_attr(value.attr(), it, end); - detail::parse_item(value.value(), it, end, key); + detail::xml_parse_item(value.value(), it, end, key); } template , int> = 0> @@ -507,7 +507,7 @@ IGUANA_INLINE void from_xml(U &value, It &&it, It &&end) { skip_till_greater_or_space(it, end); std::string_view key = std::string_view{&*start, static_cast(std::distance(start, it))}; - detail::parse_item(value, it, end, key); + detail::xml_parse_item(value, it, end, key); } template , int> = 0> +IGUANA_INLINE void yaml_parse_item(U &value, It &&it, It &&end, + size_t min_spaces) { + throw std::bad_function_call(); +} + +template , int> = 0> +IGUANA_INLINE void yaml_parse_value(U &value, It &&value_begin, + It &&value_end) { + throw std::bad_function_call(); +} + template , int> = 0> IGUANA_INLINE void parse_escape_str(U &value, It &&it, It &&end) { auto start = it; @@ -105,10 +119,12 @@ IGUANA_INLINE void parse_block_str(U &value, It &&it, It &&end, template , int> = 0> -IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces); +IGUANA_INLINE void yaml_parse_item(U &value, It &&it, It &&end, + size_t min_spaces); template , int> = 0> -IGUANA_INLINE void parse_value(U &value, It &&value_begin, It &&value_end) { +IGUANA_INLINE void yaml_parse_value(U &value, It &&value_begin, + It &&value_end) { if (value_begin == value_end) IGUANA_UNLIKELY { return; } auto size = std::distance(value_begin, value_end); @@ -116,10 +132,17 @@ IGUANA_INLINE void parse_value(U &value, It &&value_begin, It &&value_end) { detail::from_chars(start, start + size, value); } +template , int> = 0> +IGUANA_INLINE void yaml_parse_value(U &value, It &&value_begin, + It &&value_end) { + yaml_parse_value(value.val, value_begin, value_end); +} + // string_view should be used for string with ' " ? template , int> = 0> -IGUANA_INLINE void parse_value(U &value, It &&value_begin, It &&value_end) { +IGUANA_INLINE void yaml_parse_value(U &value, It &&value_begin, + It &&value_end) { using T = std::decay_t; auto start = value_begin; auto end = value_end; @@ -152,19 +175,21 @@ IGUANA_INLINE void parse_value(U &value, It &&value_begin, It &&value_end) { } template , int> = 0> -IGUANA_INLINE void parse_value(U &value, It &&value_begin, It &&value_end) { +IGUANA_INLINE void yaml_parse_value(U &value, It &&value_begin, + It &&value_end) { if (static_cast(std::distance(value_begin, value_end)) != 1) IGUANA_UNLIKELY { throw std::runtime_error("Expected one character"); } value = *value_begin; } template , int> = 0> -IGUANA_INLINE void parse_value(U &value, It &&value_begin, It &&value_end) { +IGUANA_INLINE void yaml_parse_value(U &value, It &&value_begin, + It &&value_end) { static constexpr auto str_to_enum = get_enum_map>(); if constexpr (bool_v) { // not defined a specialization template using T = std::underlying_type_t>; - parse_value(reinterpret_cast(value), value_begin, value_end); + yaml_parse_value(reinterpret_cast(value), value_begin, value_end); } else { auto enum_names = std::string_view( @@ -181,7 +206,8 @@ IGUANA_INLINE void parse_value(U &value, It &&value_begin, It &&value_end) { } template , int> = 0> -IGUANA_INLINE void parse_value(U &&value, It &&value_begin, It &&value_end) { +IGUANA_INLINE void yaml_parse_value(U &&value, It &&value_begin, + It &&value_end) { auto bool_v = std::string_view( &*value_begin, static_cast(std::distance(value_begin, value_end))); @@ -196,12 +222,14 @@ IGUANA_INLINE void parse_value(U &&value, It &&value_begin, It &&value_end) { } template , int> = 0> -IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces) { +IGUANA_INLINE void yaml_parse_item(U &value, It &&it, It &&end, + size_t min_spaces) { from_yaml(value, it, end, min_spaces); } template , int> = 0> -IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces) { +IGUANA_INLINE void yaml_parse_item(U &value, It &&it, It &&end, + size_t min_spaces) { using T = std::decay_t; if constexpr (string_v) { if (skip_space_till_end(it, end)) @@ -224,27 +252,36 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces) { skip_space_and_lines(it, end, min_spaces); auto start = it; auto value_end = skip_till_newline(it, end); - parse_value(value, start, value_end); + yaml_parse_value(value, start, value_end); } } else { skip_space_and_lines(it, end, min_spaces); auto start = it; auto value_end = skip_till_newline(it, end); - parse_value(value, start, value_end); + yaml_parse_value(value, start, value_end); } } +template , int> = 0> +IGUANA_INLINE void yaml_parse_item(U &value, It &&it, It &&end, + size_t min_spaces) { + yaml_parse_item(value.val, it, end, min_spaces); +} + template , int> = 0> -IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces); +IGUANA_INLINE void yaml_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); +IGUANA_INLINE void yaml_parse_item(U &value, It &&it, It &&end, + size_t min_spaces); // minspaces : The minimum indentation template , int> = 0> -IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces) { +IGUANA_INLINE void yaml_parse_item(U &value, It &&it, It &&end, + size_t min_spaces) { value.clear(); auto spaces = skip_space_and_lines(it, end, min_spaces); using value_type = typename std::remove_cv_t::value_type; @@ -260,12 +297,12 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces) { if constexpr (plain_v) { auto start = it; auto value_end = yaml_skip_till<',', ']'>(it, end); - parse_value(value.emplace_back(), start, value_end); + yaml_parse_value(value.emplace_back(), start, value_end); if (*(it - 1) == ']') IGUANA_UNLIKELY { return; } } else { - parse_item(value.emplace_back(), it, end, spaces + 1); + yaml_parse_item(value.emplace_back(), it, end, spaces + 1); skip_space_and_lines(it, end, min_spaces); if (*it == ',') IGUANA_LIKELY { ++it; } @@ -289,15 +326,15 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces) { subspaces = skip_space_and_lines(it, end, spaces + 1); if constexpr (string_v) { // except string_v because of scalar blocks - parse_item(value.emplace_back(), it, end, spaces + 1); + yaml_parse_item(value.emplace_back(), it, end, spaces + 1); } else if constexpr (plain_v) { auto start = it; auto value_end = skip_till_newline(it, end); - parse_value(value.emplace_back(), start, value_end); + yaml_parse_value(value.emplace_back(), start, value_end); } else { - parse_item(value.emplace_back(), it, end, subspaces); + yaml_parse_item(value.emplace_back(), it, end, subspaces); } } } @@ -306,7 +343,8 @@ 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) { +IGUANA_INLINE void yaml_parse_item(U &value, It &&it, It &&end, + size_t min_spaces) { auto spaces = skip_space_and_lines(it, end, min_spaces); if (*it == '[') { ++it; @@ -317,10 +355,10 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces) { if constexpr (plain_v) { auto start = it; auto value_end = yaml_skip_till<',', ']'>(it, end); - parse_value(v, start, value_end); + yaml_parse_value(v, start, value_end); } else { - parse_item(v, it, end, spaces + 1); + yaml_parse_item(v, it, end, spaces + 1); skip_space_and_lines(it, end, min_spaces); ++it; // skip , } @@ -337,15 +375,15 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces) { [[maybe_unused]] auto subspaces = skip_space_and_lines(it, end, spaces + 1); if constexpr (string_v) { - parse_item(v, it, end, spaces + 1); + yaml_parse_item(v, it, end, spaces + 1); } else if constexpr (plain_v) { auto start = it; auto value_end = skip_till_newline(it, end); - parse_value(v, start, value_end); + yaml_parse_value(v, start, value_end); } else { - parse_item(v, it, end, subspaces); + yaml_parse_item(v, it, end, subspaces); } }); } @@ -355,7 +393,8 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces) { } template , int>> -IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces) { +IGUANA_INLINE void yaml_parse_item(U &value, It &&it, It &&end, + size_t min_spaces) { using T = std::remove_reference_t; using key_type = typename T::key_type; using value_type = typename T::mapped_type; @@ -372,17 +411,17 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces) { auto start = it; auto value_end = yaml_skip_till<':'>(it, end); key_type key; - parse_value(key, start, value_end); + yaml_parse_value(key, start, value_end); subspaces = skip_space_and_lines(it, end, min_spaces); if constexpr (plain_v) { start = it; value_end = yaml_skip_till<',', '}'>(it, end); - parse_value(value[key], start, value_end); + yaml_parse_value(value[key], start, value_end); if (*(it - 1) == '}') IGUANA_UNLIKELY { return; } } else { - parse_item(value[key], it, end, min_spaces); + yaml_parse_item(value[key], it, end, min_spaces); subspaces = skip_space_and_lines(it, end, min_spaces); if (*it == ',') IGUANA_LIKELY { ++it; } @@ -401,15 +440,15 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces) { auto start = it; auto value_end = yaml_skip_till<':'>(it, end); key_type key; - parse_value(key, start, value_end); + yaml_parse_value(key, start, value_end); subspaces = skip_space_and_lines(it, end, min_spaces); if constexpr (plain_v && !string_v) { start = it; value_end = skip_till_newline(it, end); - parse_value(value[key], start, value_end); + yaml_parse_value(value[key], start, value_end); } else { - parse_item(value[key], it, end, spaces + 1); + yaml_parse_item(value[key], it, end, spaces + 1); } subspaces = skip_space_and_lines(it, end, min_spaces); } @@ -417,7 +456,8 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces) { } template , int>> -IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces) { +IGUANA_INLINE void yaml_parse_item(U &value, It &&it, It &&end, + size_t min_spaces) { using T = std::remove_reference_t; if constexpr (unique_ptr_v) { value = std::make_unique(); @@ -427,11 +467,12 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces) { } static_assert(!string_v, "smart_ptr is not allowed"); - parse_item(*value, it, end, min_spaces); + yaml_parse_item(*value, it, end, min_spaces); } template , int>> -IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces) { +IGUANA_INLINE void yaml_parse_item(U &value, It &&it, It &&end, + size_t min_spaces) { using T = std::remove_reference_t; using value_type = typename T::value_type; auto spaces = skip_space_and_lines(it, end, min_spaces); @@ -454,7 +495,7 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces) { } if constexpr (string_v || !plain_v) { it = start; - parse_item(value.emplace(), it, end, min_spaces); + yaml_parse_item(value.emplace(), it, end, min_spaces); } else { if (value_end == end) @@ -462,7 +503,7 @@ IGUANA_INLINE void parse_item(U &value, It &&it, It &&end, size_t min_spaces) { // if value_end isn't touched value_end = skip_till_newline(it, end); } - parse_value(value.emplace(), start, value_end); + yaml_parse_value(value.emplace(), start, value_end); } } @@ -506,7 +547,8 @@ IGUANA_INLINE void from_yaml(T &value, It &&it, It &&end, size_t min_spaces) { [&](auto &&member_ptr) IGUANA__INLINE_LAMBDA { using V = std::decay_t; if constexpr (std::is_member_pointer_v) { - detail::parse_item(value.*member_ptr, it, end, spaces + 1); + detail::yaml_parse_item(value.*member_ptr, it, end, + spaces + 1); } else { static_assert(!sizeof(V), "type not supported"); @@ -535,7 +577,7 @@ IGUANA_INLINE void from_yaml(T &value, It &&it, It &&end, size_t min_spaces) { template , int> = 0> IGUANA_INLINE void from_yaml(T &value, It &&it, It &&end) { - detail::parse_item(value, it, end, 0); + detail::yaml_parse_item(value, it, end, 0); } template @@ -567,4 +609,10 @@ IGUANA_INLINE void from_yaml(T &value, const View &view, } } +template +IGUANA_INLINE void from_yaml_adl(iguana_adl_t *p, T &t, + std::string_view pb_str) { + iguana::from_yaml(t, pb_str); +} + } // namespace iguana diff --git a/iguana/yaml_util.hpp b/iguana/yaml_util.hpp index b1b93a6a..920a9918 100644 --- a/iguana/yaml_util.hpp +++ b/iguana/yaml_util.hpp @@ -4,6 +4,10 @@ #include "util.hpp" namespace iguana { + +template +constexpr inline bool yaml_not_support_v = variant_v; + // return true when it==end template IGUANA_INLINE bool skip_space_till_end(It &&it, It &&end) { diff --git a/iguana/yaml_writer.hpp b/iguana/yaml_writer.hpp index a0794f2c..1feed6d4 100644 --- a/iguana/yaml_writer.hpp +++ b/iguana/yaml_writer.hpp @@ -5,6 +5,12 @@ namespace iguana { +template , int> = 0> +IGUANA_INLINE void render_yaml_value(Stream &ss, T &&t, size_t min_spaces = 0) { + throw std::bad_function_call(); +} + template , int> = 0> IGUANA_INLINE void to_yaml(T &&t, Stream &s, size_t min_spaces = 0); @@ -41,6 +47,12 @@ IGUANA_INLINE void render_yaml_value(Stream &ss, T value, size_t min_spaces) { ss.push_back('\n'); } +template , int> = 0> +IGUANA_INLINE void render_yaml_value(Stream &ss, T value, size_t min_spaces) { + render_yaml_value(ss, value.val, min_spaces); +} + template IGUANA_INLINE void render_yaml_value(Stream &ss, char value, size_t min_spaces) { @@ -191,4 +203,9 @@ IGUANA_INLINE void to_yaml(T &&t, Stream &s) { static_assert(!sizeof(T), "don't suppport this type"); } +template +IGUANA_INLINE void to_yaml_adl(iguana_adl_t *p, const T &t, + std::string &pb_str) { + to_yaml(t, pb_str); +} } // namespace iguana diff --git a/test/test_pb.cpp b/test/test_pb.cpp index 1e06a492..5e919fa8 100644 --- a/test/test_pb.cpp +++ b/test/test_pb.cpp @@ -295,6 +295,16 @@ TEST_CASE("test reflection") { std::cout << s.x << " " << s.y << "\n"; CHECK(st->x == s.x); CHECK(st->y == s.y); + + std::string yaml; + t->to_yaml(yaml); + std::cout << yaml << "\n"; + + s = {}; + s.from_yaml(yaml); + std::cout << s.x << " " << s.y << "\n"; + CHECK(st->x == s.x); + CHECK(st->y == s.y); } auto t = iguana::create_instance("numer_st"); t->set_field_value("a", true);