3232#include < fcitx-utils/metastring.h>
3333#include < fcitx-utils/misc.h>
3434#include < fcitx-utils/tuplehelpers.h>
35+ #include < source_location> // IWYU pragma: keep
3536#include < span>
37+ #include < syncstream>
3638
3739namespace fcitx {
3840
@@ -110,12 +112,12 @@ class FCITXUTILS_EXPORT LogMessageBuilder {
110112
111113 LogMessageBuilder &self () { return *this ; }
112114
113- inline LogMessageBuilder &operator <<(const std::string &s) {
115+ LogMessageBuilder &operator <<(const std::string &s) {
114116 *this << s.c_str ();
115117 return *this ;
116118 }
117119
118- inline LogMessageBuilder &operator <<(const Key &key) {
120+ LogMessageBuilder &operator <<(const Key &key) {
119121 out_ << " Key(" << key.toString ()
120122 << " states=" << key.states ().toInteger () << " )" ;
121123 return *this ;
@@ -143,7 +145,7 @@ class FCITXUTILS_EXPORT LogMessageBuilder {
143145 FCITX_SIMPLE_LOG (T)
144146
145147 template <typename T>
146- inline LogMessageBuilder &operator <<(const std::optional<T> &opt) {
148+ LogMessageBuilder &operator <<(const std::optional<T> &opt) {
147149 *this << " optional(has_value=" << opt.has_value () << " " ;
148150 if (opt.has_value ()) {
149151 *this << *opt;
@@ -153,43 +155,43 @@ class FCITXUTILS_EXPORT LogMessageBuilder {
153155 }
154156
155157 template <typename T>
156- inline LogMessageBuilder &operator <<(const std::unique_ptr<T> &ptr) {
158+ LogMessageBuilder &operator <<(const std::unique_ptr<T> &ptr) {
157159 *this << " unique_ptr(" << ptr.get () << " )" ;
158160 return *this ;
159161 }
160162
161163 template <typename T>
162- inline LogMessageBuilder &operator <<(const std::vector<T> &vec) {
164+ LogMessageBuilder &operator <<(const std::vector<T> &vec) {
163165 *this << " [" ;
164166 printRange (vec.begin (), vec.end ());
165167 *this << " ]" ;
166168 return *this ;
167169 }
168170
169171 template <typename T>
170- inline LogMessageBuilder &operator <<(const std::span<T> &vec) {
172+ LogMessageBuilder &operator <<(const std::span<T> &vec) {
171173 *this << " span[" ;
172174 printRange (vec.begin (), vec.end ());
173175 *this << " ]" ;
174176 return *this ;
175177 }
176178
177179 template <typename T>
178- inline LogMessageBuilder &operator <<(const std::list<T> &lst) {
180+ LogMessageBuilder &operator <<(const std::list<T> &lst) {
179181 *this << " list[" ;
180182 printRange (lst.begin (), lst.end ());
181183 *this << " ]" ;
182184 return *this ;
183185 }
184186
185187 template <typename K, typename V>
186- inline LogMessageBuilder &operator <<(const std::pair<K, V> &pair) {
188+ LogMessageBuilder &operator <<(const std::pair<K, V> &pair) {
187189 *this << " (" << pair.first << " , " << pair.second << " )" ;
188190 return *this ;
189191 }
190192
191193 template <typename ... Args>
192- inline LogMessageBuilder &operator <<(const std::tuple<Args...> &tuple) {
194+ LogMessageBuilder &operator <<(const std::tuple<Args...> &tuple) {
193195 typename MakeSequence<sizeof ...(Args)>::type a;
194196 *this << " (" ;
195197 printWithIndices (a, tuple);
@@ -198,65 +200,63 @@ class FCITXUTILS_EXPORT LogMessageBuilder {
198200 }
199201
200202 template <typename K, typename V>
201- inline LogMessageBuilder &operator <<(const std::unordered_map<K, V> &vec) {
203+ LogMessageBuilder &operator <<(const std::unordered_map<K, V> &vec) {
202204 *this << " {" ;
203205 printRange (vec.begin (), vec.end ());
204206 *this << " }" ;
205207 return *this ;
206208 }
207209
208210 template <typename V>
209- inline LogMessageBuilder &operator <<(const std::unordered_set<V> &vec) {
211+ LogMessageBuilder &operator <<(const std::unordered_set<V> &vec) {
210212 *this << " {" ;
211213 printRange (vec.begin (), vec.end ());
212214 *this << " }" ;
213215 return *this ;
214216 }
215217
216218 template <typename K, typename V>
217- inline LogMessageBuilder &operator <<(const std::map<K, V> &vec) {
219+ LogMessageBuilder &operator <<(const std::map<K, V> &vec) {
218220 *this << " {" ;
219221 printRange (vec.begin (), vec.end ());
220222 *this << " }" ;
221223 return *this ;
222224 }
223225
224226 template <typename V>
225- inline LogMessageBuilder &operator <<(const std::set<V> &vec) {
227+ LogMessageBuilder &operator <<(const std::set<V> &vec) {
226228 *this << " {" ;
227229 printRange (vec.begin (), vec.end ());
228230 *this << " }" ;
229231 return *this ;
230232 }
231233
232234 template <typename K, typename V>
233- inline LogMessageBuilder &operator <<(const std::multimap<K, V> &vec) {
235+ LogMessageBuilder &operator <<(const std::multimap<K, V> &vec) {
234236 *this << " {" ;
235237 printRange (vec.begin (), vec.end ());
236238 *this << " }" ;
237239 return *this ;
238240 }
239241
240242 template <typename V>
241- inline LogMessageBuilder &operator <<(const std::multiset<V> &vec) {
243+ LogMessageBuilder &operator <<(const std::multiset<V> &vec) {
242244 *this << " {" ;
243245 printRange (vec.begin (), vec.end ());
244246 *this << " }" ;
245247 return *this ;
246248 }
247249
248250 template <typename K, typename V>
249- inline LogMessageBuilder &
250- operator <<(const std::unordered_multimap<K, V> &vec) {
251+ LogMessageBuilder &operator <<(const std::unordered_multimap<K, V> &vec) {
251252 *this << " {" ;
252253 printRange (vec.begin (), vec.end ());
253254 *this << " }" ;
254255 return *this ;
255256 }
256257
257258 template <typename V>
258- inline LogMessageBuilder &
259- operator <<(const std::unordered_multiset<V> &vec) {
259+ LogMessageBuilder &operator <<(const std::unordered_multiset<V> &vec) {
260260 *this << " {" ;
261261 printRange (vec.begin (), vec.end ());
262262 *this << " }" ;
@@ -288,33 +288,44 @@ class FCITXUTILS_EXPORT LogMessageBuilder {
288288
289289 std::ostream &out_;
290290};
291- } // namespace fcitx
292291
293- #ifdef FCITX_USE_NO_METASTRING_FILENAME
294- #define FCITX_LOG_FILENAME_WRAP ::fcitx::fs::baseName (__FILE__).data()
295- #else
296- #define FCITX_LOG_FILENAME_WRAP \
297- fcitx::MetaStringBasenameType<fcitxMakeMetaString(__FILE__)>::data()
298- #endif
292+ template <typename MetaStringFileName, int N>
293+ class LogMessageBuilderWrapper {
294+ public:
295+ LogMessageBuilderWrapper (LogLevel l)
296+ : out_(Log::logStream()),
297+ builder_ (out_, l, MetaStringFileName::data(), N) {}
298+
299+ LogMessageBuilder &self () { return builder_; }
300+
301+ private:
302+ std::osyncstream out_;
303+ LogMessageBuilder builder_;
304+ };
305+
306+ } // namespace fcitx
299307
308+ // Use meta string for file name to avoid having full path in binary.
300309#define FCITX_LOGC_IF (CATEGORY, LEVEL, CONDITION ) \
301310 for (bool fcitxLogEnabled = \
302311 (CONDITION) && CATEGORY().fatalWrapper(::fcitx::LogLevel::LEVEL); \
303312 fcitxLogEnabled; \
304313 fcitxLogEnabled = CATEGORY().fatalWrapper2(::fcitx::LogLevel::LEVEL)) \
305- ::fcitx::LogMessageBuilder (::fcitx::Log::logStream(), \
306- ::fcitx::LogLevel::LEVEL, \
307- FCITX_LOG_FILENAME_WRAP, __LINE__) \
314+ ::fcitx::LogMessageBuilderWrapper< \
315+ fcitx::MetaStringBasenameType<fcitxMakeMetaString( \
316+ std::source_location::current ().file_name())>, \
317+ std::source_location::current().line()>(::fcitx::LogLevel::LEVEL) \
308318 .self()
309319
310320#define FCITX_LOGC (CATEGORY, LEVEL ) \
311321 for (bool fcitxLogEnabled = \
312322 CATEGORY ().fatalWrapper(::fcitx::LogLevel::LEVEL); \
313323 fcitxLogEnabled; \
314324 fcitxLogEnabled = CATEGORY().fatalWrapper2(::fcitx::LogLevel::LEVEL)) \
315- ::fcitx::LogMessageBuilder (::fcitx::Log::logStream(), \
316- ::fcitx::LogLevel::LEVEL, \
317- FCITX_LOG_FILENAME_WRAP, __LINE__) \
325+ ::fcitx::LogMessageBuilderWrapper< \
326+ fcitx::MetaStringBasenameType<fcitxMakeMetaString( \
327+ std::source_location::current ().file_name())>, \
328+ std::source_location::current().line()>(::fcitx::LogLevel::LEVEL) \
318329 .self()
319330
320331#define FCITX_LOG (LEVEL ) FCITX_LOGC(::fcitx::Log::defaultCategory, LEVEL)
0 commit comments