From 5a427767b92abbd9e0310eaddcc87e7eaec5485e Mon Sep 17 00:00:00 2001 From: Horror Proton <107091537+horror-proton@users.noreply.github.com> Date: Sun, 10 Jul 2022 22:40:49 +0800 Subject: [PATCH] feat: support range-expressions in log argument --- src/MeoAssistant/AsstUtils.hpp | 7 ++++ src/MeoAssistant/Logger.hpp | 72 ++++++++++++++++++++++++---------- 2 files changed, 58 insertions(+), 21 deletions(-) mode change 100644 => 100755 src/MeoAssistant/AsstUtils.hpp mode change 100644 => 100755 src/MeoAssistant/Logger.hpp diff --git a/src/MeoAssistant/AsstUtils.hpp b/src/MeoAssistant/AsstUtils.hpp old mode 100644 new mode 100755 index 6071c9e1cf..4000d398cc --- a/src/MeoAssistant/AsstUtils.hpp +++ b/src/MeoAssistant/AsstUtils.hpp @@ -307,4 +307,11 @@ namespace asst::utils // } // return str; //} + + template + struct integral_constant_at_template_instantiation : std::integral_constant {}; } + +// delete instantiation of template with message, when static_assert(false, Message) does not work +#define ASST_STATIC_ASSERT_FALSE(Message, ...) \ +static_assert(::asst::utils::integral_constant_at_template_instantiation::value, Message) diff --git a/src/MeoAssistant/Logger.hpp b/src/MeoAssistant/Logger.hpp old mode 100644 new mode 100755 index 03eaa7771d..22564b7444 --- a/src/MeoAssistant/Logger.hpp +++ b/src/MeoAssistant/Logger.hpp @@ -162,30 +162,60 @@ namespace asst #endif } - template - struct stream_put_converted_impl - { - static constexpr Stream& apply(Stream& s, T&& value) - { - s << std::forward(value); - return s; - } - }; + template + struct has_stream_insertion_operator : std::false_type {}; template - struct stream_put_converted_impl>> + struct has_stream_insertion_operator< + Stream, T, + std::void_t() << std::declval())>> + : std::true_type { - static constexpr Stream& apply(Stream& s, T&& value) - { -#ifdef _WIN32 - s << utils::utf8_to_ansi(std::forward(value)); -#else - s << std::forward(value); -#endif - return s; - } }; + template + struct is_range_expression : std::false_type {}; + + template + struct is_range_expression()))>::iterator_category, + std::forward_iterator_tag + > + >> : std::true_type + { + }; + + template + static Stream& stream_put(Stream& s, T&& v) + { + if constexpr(std::is_constructible_v) { + if constexpr (ToAnsi) s << utils::utf8_to_ansi(std::forward(v)); + else s << std::string(std::forward(v)); + return s; + } else if constexpr (has_stream_insertion_operator::value) { + s << std::forward(v); + return s; + } else if constexpr (is_range_expression::value) { + s << "["; + std::string_view comma{}; + for (const auto& elem : std::forward(v)) { + s << comma; + stream_put(s, elem); + comma = ","; + } + s << "]"; + return s; + } else { + ASST_STATIC_ASSERT_FALSE( + "\nunsupported type, one of following required \n" + "\t1. those can be converted to string;\n" + "\t2. those can be inserted to stream with operator<< directly;\n" + "\t3. container or nested container containing one of 1. 2. or 3. and iterable with range-based for", + Stream, T); + } + } + template struct stream_put_line_impl; @@ -202,7 +232,7 @@ namespace asst { static constexpr Stream& apply(Stream& s, Only&& only) { - stream_put_converted_impl::apply(s, std::forward(only)); + stream_put(s, std::forward(only)); s << std::endl; return s; } @@ -213,7 +243,7 @@ namespace asst { static constexpr Stream& apply(Stream& s, First f, Rest... rs) { - stream_put_converted_impl::apply(s, std::forward(f)); + stream_put(s, std::forward(f)); s << " "; stream_put_line_impl::apply(s, std::forward(rs)...); return s;