From 3ab1e4c504f2175227fdf408db52a7dc3f490b7d Mon Sep 17 00:00:00 2001 From: qicosmos Date: Sat, 15 Jul 2023 22:38:05 +0800 Subject: [PATCH] Update iguana (#368) --- include/ylt/struct_xml/xml_reader.h | 10 ++ include/ylt/struct_xml/xml_writer.h | 4 +- include/ylt/thirdparty/iguana/reflection.hpp | 2 +- include/ylt/thirdparty/iguana/xml_reader.hpp | 2 +- include/ylt/thirdparty/iguana/xml_writer.hpp | 100 +++++++++++-------- src/struct_xml/examples/main.cpp | 20 +++- 6 files changed, 92 insertions(+), 46 deletions(-) diff --git a/include/ylt/struct_xml/xml_reader.h b/include/ylt/struct_xml/xml_reader.h index 05b9f5540..d5488e0c3 100644 --- a/include/ylt/struct_xml/xml_reader.h +++ b/include/ylt/struct_xml/xml_reader.h @@ -14,6 +14,7 @@ * limitations under the License. */ #pragma once +#include #include namespace struct_xml { @@ -32,4 +33,13 @@ template > using xml_attr_t = iguana::xml_attr_t; +template +inline constexpr std::string_view type_string() { + return iguana::type_string(); +} + +template +inline constexpr std::string_view enum_string() { + return iguana::enum_string(); +} } // namespace struct_xml \ No newline at end of file diff --git a/include/ylt/struct_xml/xml_writer.h b/include/ylt/struct_xml/xml_writer.h index c8c3f75ce..dbe964e3c 100644 --- a/include/ylt/struct_xml/xml_writer.h +++ b/include/ylt/struct_xml/xml_writer.h @@ -17,9 +17,9 @@ #include namespace struct_xml { -template +template inline void to_xml(T &&t, Stream &s) { - iguana::to_xml(std::forward(t), s); + iguana::to_xml(std::forward(t), s); } } // namespace struct_xml \ No newline at end of file diff --git a/include/ylt/thirdparty/iguana/reflection.hpp b/include/ylt/thirdparty/iguana/reflection.hpp index 42ed4bb59..5712c786b 100644 --- a/include/ylt/thirdparty/iguana/reflection.hpp +++ b/include/ylt/thirdparty/iguana/reflection.hpp @@ -17,10 +17,10 @@ #include #include -#include "../frozen/string.h" #include "detail/itoa.hpp" #include "detail/string_stream.hpp" #include "detail/traits.hpp" +#include "frozen/string.h" #include "frozen/unordered_map.h" namespace iguana::detail { diff --git a/include/ylt/thirdparty/iguana/xml_reader.hpp b/include/ylt/thirdparty/iguana/xml_reader.hpp index e5e8d0ae6..a65e1f549 100644 --- a/include/ylt/thirdparty/iguana/xml_reader.hpp +++ b/include/ylt/thirdparty/iguana/xml_reader.hpp @@ -306,7 +306,7 @@ IGUANA_INLINE void parse_item(T &value, It &&it, It &&end, key_set.append(key).append(", "); } } - if (skip_till_key(value, it, end)) { + if (skip_till_key(value, it, end)) [[unlikely]] { match_close_tag(it, end, name); parse_done = true; return; diff --git a/include/ylt/thirdparty/iguana/xml_writer.hpp b/include/ylt/thirdparty/iguana/xml_writer.hpp index 6084f893e..e5bb10c67 100644 --- a/include/ylt/thirdparty/iguana/xml_writer.hpp +++ b/include/ylt/thirdparty/iguana/xml_writer.hpp @@ -6,19 +6,28 @@ namespace iguana { -template +template IGUANA_INLINE void render_xml_value(Stream &ss, T &&t, std::string_view name); -template -inline void render_tail(Stream &ss, std::string_view str) { +template +IGUANA_INLINE void render_tail(Stream &ss, std::string_view str) { + if constexpr (pretty) { + ss.append(spaces, '\t'); + } ss.push_back('<'); ss.push_back('/'); ss.append(str.data(), str.size()); ss.push_back('>'); + if constexpr (pretty) { + ss.push_back('\n'); + } } -template +template inline void render_head(Stream &ss, std::string_view str) { + if constexpr (pretty) { + ss.append(spaces, '\t'); + } ss.push_back('<'); ss.append(str.data(), str.size()); ss.push_back('>'); @@ -48,8 +57,11 @@ IGUANA_INLINE void render_value(Stream &ss, const T &value) { } } -template +template inline void render_xml_attr(Stream &ss, const T &value, std::string_view name) { + if constexpr (pretty) { + ss.append(spaces, '\t'); + } ss.push_back('<'); ss.append(name.data(), name.size()); for (auto [k, v] : value) { @@ -63,61 +75,62 @@ inline void render_xml_attr(Stream &ss, const T &value, std::string_view name) { ss.push_back('>'); } -template -IGUANA_INLINE void render_xml_value(Stream &ss, const T &value, - std::string_view name) { - render_xml_attr(ss, value.attr(), name); - render_xml_value(ss, value.value(), name); - render_tail(ss, name); -} - -template +template IGUANA_INLINE void render_xml_value(Stream &ss, const T &value, std::string_view name) { render_value(ss, value); - render_tail(ss, name); + render_tail(ss, name); } -template +template IGUANA_INLINE void render_xml_value(Stream &ss, const T &value, std::string_view name) { if (value) { - render_xml_value(ss, *value, name); + render_xml_value(ss, *value, name); } else { - render_tail(ss, name); + render_tail(ss, name); } } -template +template IGUANA_INLINE void render_xml_value(Stream &ss, const T &value, std::string_view name) { if (value) { - render_xml_value(ss, *value, name); + render_xml_value(ss, *value, name); } else { - render_tail(ss, name); + render_tail(ss, name); } } -template +template +IGUANA_INLINE void render_xml_value(Stream &ss, const T &value, + std::string_view name) { + render_xml_attr(ss, value.attr(), name); + render_xml_value(ss, value.value(), name); +} + +template 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; for (const auto &v : value) { if constexpr (attr_t) { - render_xml_attr(ss, v.attr(), name); - render_xml_value(ss, v.value(), name); + render_xml_value(ss, v, name); } else { - render_head(ss, name); - render_xml_value(ss, v, name); + render_head(ss, name); + render_xml_value(ss, v, name); } } } -template +template IGUANA_INLINE void render_xml_value(Stream &ss, T &&t, std::string_view name) { + if constexpr (pretty) { + ss.push_back('\n'); + } for_each(std::forward(t), [&](const auto &v, auto i) IGUANA__INLINE_LAMBDA { using M = decltype(iguana_reflect_members(std::forward(t))); @@ -129,38 +142,43 @@ IGUANA_INLINE void render_xml_value(Stream &ss, T &&t, std::string_view name) { get_name, Idx>().size()); static_assert(Idx < Count); if constexpr (sequence_container_t) { - render_xml_value(ss, t.*v, tag_name); + render_xml_value(ss, t.*v, tag_name); } else if constexpr (attr_t) { - render_xml_attr(ss, (t.*v).attr(), tag_name); - render_xml_value(ss, (t.*v).value(), tag_name); + render_xml_value(ss, t.*v, tag_name); } else if constexpr (cdata_t) { - ss.append(""); + if constexpr (pretty) { + ss.append(spaces + 1, '\t'); + ss.append("\n"); + } + else { + ss.append(""); + } } else { - render_head(ss, tag_name); - render_xml_value(ss, t.*v, tag_name); + render_head(ss, tag_name); + render_xml_value(ss, t.*v, tag_name); } }); - render_tail(ss, name); + render_tail(ss, name); } -template +template IGUANA_INLINE void to_xml(T &&t, Stream &s) { using value_type = typename std::decay_t::value_type; + static_assert(refletable, "value_type must be refletable"); constexpr std::string_view root_name = std::string_view( get_name().data(), get_name().size()); - render_xml_attr(s, std::forward(t).attr(), root_name); - render_xml_value(s, std::forward(t).value(), root_name); + render_xml_value(s, std::forward(t), root_name); } -template +template IGUANA_INLINE void to_xml(T &&t, Stream &s) { constexpr std::string_view root_name = std::string_view( get_name>().data(), get_name>().size()); - render_head(s, root_name); - render_xml_value(s, std::forward(t), root_name); + render_head(s, root_name); + render_xml_value(s, std::forward(t), root_name); } -} // namespace iguana \ No newline at end of file +} // namespace iguana diff --git a/src/struct_xml/examples/main.cpp b/src/struct_xml/examples/main.cpp index 2815b2712..24b48d517 100644 --- a/src/struct_xml/examples/main.cpp +++ b/src/struct_xml/examples/main.cpp @@ -165,7 +165,24 @@ void basic_usage() { std::string str; struct_xml::to_xml(p, str); - std::cout << str; + std::cout << str << "\n"; + + std::string pretty_xml_str; + struct_xml::to_xml(p, pretty_xml_str); + + std::cout << pretty_xml_str; +} + +enum class Color { red, black }; + +enum Size { small, large }; + +class my_message {}; + +void type_to_string() { + static_assert(struct_xml::type_string() == "my_message"); + static_assert(struct_xml::enum_string() == "Color::red"); + static_assert(struct_xml::enum_string() == "small"); } void get_error() { @@ -216,6 +233,7 @@ void required_field() { int main() { basic_usage(); + type_to_string(); nested_xml(); attribute(); get_error();