@@ -53,6 +53,9 @@ struct MAA_UTILS_API separator
5353 std::string_view str;
5454};
5555
56+ template <typename T>
57+ concept has_output_operator = requires { std::declval<std::ostream&>() << std::declval<T>(); };
58+
5659class MAA_UTILS_API LogStream
5760{
5861public:
@@ -103,9 +106,25 @@ class MAA_UTILS_API LogStream
103106 template <typename T>
104107 void stream (T&& value, const separator& sep)
105108 {
106- json::value j (std::forward<T>(value));
107- // 直接 dumps 的 string 会多一对双引号,有点难看
108- buffer_ << (j.is_string () ? j.as_string () : j.dumps ()) << sep.str ;
109+ if constexpr (std::is_constructible_v<json::value, T>) {
110+ json::value j (std::forward<T>(value));
111+ // 直接 dumps 的 string 会多一对双引号,有点难看
112+ buffer_ << (j.is_string () ? j.as_string () : j.dumps ()) << sep.str ;
113+ }
114+ else if constexpr (std::is_constructible_v<json::array, T>) {
115+ json::array j (std::forward<T>(value));
116+ buffer_ << j.dumps () << sep.str ;
117+ }
118+ else if constexpr (std::is_constructible_v<json::object, T>) {
119+ json::object j (std::forward<T>(value));
120+ buffer_ << j.dumps () << sep.str ;
121+ }
122+ else if constexpr (has_output_operator<T>) {
123+ buffer_ << std::forward<T>(value) << sep.str ;
124+ }
125+ else {
126+ static_assert (false , " Unsupported type for LogStream::stream" );
127+ }
109128 }
110129
111130 template <typename ... args_t >
@@ -116,7 +135,7 @@ class MAA_UTILS_API LogStream
116135#else
117136 int pid = ::getpid ();
118137#endif
119- auto tid = static_cast <uint16_t >(std::hash<std::thread::id> {}(std::this_thread::get_id ()));
138+ auto tid = static_cast <uint16_t >(std::hash<std::thread::id> { }(std::this_thread::get_id ()));
120139
121140 std::string props = std::format (" [{}][{}][Px{}][Tx{}]" , format_now (), level_str (), pid, tid);
122141 for (auto && arg : { args... }) {
0 commit comments