1 /*
2 Loguru logging library for C++, by Emil Ernerfeldt.
3 www.github.com/emilk/loguru
4 If you find Loguru useful, please let me know on twitter or in a mail!
5 Twitter: @ernerfeldt
6 Mail:    emil.ernerfeldt@gmail.com
7 Website: www.ilikebigbits.com
8 
9 # License
10 	This software is in the public domain. Where that dedication is not
11 	recognized, you are granted a perpetual, irrevocable license to
12 	copy, modify and distribute it as you see fit.
13 
14 # Inspiration
15 	Much of Loguru was inspired by GLOG, https://code.google.com/p/google-glog/.
16 	The choice of public domain is fully due Sean T. Barrett
17 	and his wonderful stb libraries at https://github.com/nothings/stb.
18 
19 # Version history
20 	* Version 0.1.0 - 2015-03-22 - Works great on Mac.
21 	* Version 0.2.0 - 2015-09-17 - Removed the only dependency.
22 	* Version 0.3.0 - 2015-10-02 - Drop-in replacement for most of GLOG
23 	* Version 0.4.0 - 2015-10-07 - Single-file!
24 	* Version 0.5.0 - 2015-10-17 - Improved file logging
25 	* Version 0.6.0 - 2015-10-24 - Add stack traces
26 	* Version 0.7.0 - 2015-10-27 - Signals
27 	* Version 0.8.0 - 2015-10-30 - Color logging.
28 	* Version 0.9.0 - 2015-11-26 - ABORT_S and proper handling of FATAL
29 	* Version 1.0.0 - 2016-02-14 - ERROR_CONTEXT
30 	* Version 1.1.0 - 2016-02-19 - -v OFF, -v INFO etc
31 	* Version 1.1.1 - 2016-02-20 - textprintf vs strprintf
32 	* Version 1.1.2 - 2016-02-22 - Remove g_alsologtostderr
33 	* Version 1.1.3 - 2016-02-29 - ERROR_CONTEXT as linked list
34 	* Version 1.2.0 - 2016-03-19 - Add get_thread_name()
35 	* Version 1.2.1 - 2016-03-20 - Minor fixes
36 	* Version 1.2.2 - 2016-03-29 - Fix issues with set_fatal_handler throwing an exception
37 	* Version 1.2.3 - 2016-05-16 - Log current working directory in loguru::init().
38 	* Version 1.2.4 - 2016-05-18 - Custom replacement for -v in loguru::init() by bjoernpollex
39 	* Version 1.2.5 - 2016-05-18 - Add ability to print ERROR_CONTEXT of parent thread.
40 	* Version 1.2.6 - 2016-05-19 - Bug fix regarding VLOG verbosity argument lacking ().
41 	* Version 1.2.7 - 2016-05-23 - Fix PATH_MAX problem.
42 	* Version 1.2.8 - 2016-05-26 - Add shutdown() and remove_all_callbacks()
43 	* Version 1.2.9 - 2016-06-09 - Use a monotonic clock for uptime.
44 	* Version 1.3.0 - 2016-07-20 - Fix issues with callback flush/close not being called.
45 	* Version 1.3.1 - 2016-07-20 - Add LOGURU_UNSAFE_SIGNAL_HANDLER to toggle stacktrace on signals.
46 	* Version 1.3.2 - 2016-07-20 - Add loguru::arguments()
47 	* Version 1.4.0 - 2016-09-15 - Semantic versioning + add loguru::create_directories
48 	* Version 1.4.1 - 2016-09-29 - Customize formating with LOGURU_FILENAME_WIDTH
49 	* Version 1.5.0 - 2016-12-22 - LOGURU_USE_FMTLIB by kolis and LOGURU_WITH_FILEABS by scinart
50 	* Version 1.5.1 - 2017-08-08 - Terminal colors on Windows 10 thanks to looki
51 	* Version 1.6.0 - 2018-01-03 - Add LOGURU_RTTI and LOGURU_STACKTRACES settings
52 	* Version 1.7.0 - 2018-01-03 - Add ability to turn off the preamble with loguru::g_preamble
53 	* Version 1.7.1 - 2018-04-05 - Add function get_fatal_handler
54 	* Version 1.7.2 - 2018-04-22 - Fix a bug where large file names could cause stack corruption (thanks @ccamporesi)
55 	* Version 1.8.0 - 2018-04-23 - Shorten long file names to keep preamble fixed width
56 	* Version 1.9.0 - 2018-09-22 - Adjust terminal colors, add LOGURU_VERBOSE_SCOPE_ENDINGS, add LOGURU_SCOPE_TIME_PRECISION, add named log levels
57 	* Version 2.0.0 - 2018-09-22 - Split loguru.hpp into loguru.hpp and loguru.cpp
58 	* Version 2.1.0 - 2019-09-23 - Update fmtlib + add option to loguru::init to NOT set main thread name.
59 
60 # Compiling
61 	Just include <loguru.hpp> where you want to use Loguru.
62 	Then, in one .cpp file #include <loguru.cpp>
63 	Make sure you compile with -std=c++11 -lstdc++ -lpthread -ldl
64 
65 # Usage
66 	For details, please see the official documentation at emilk.github.io/loguru
67 
68 	#include <loguru.hpp>
69 
70 	int main(int argc, char* argv[]) {
71 		loguru::init(argc, argv);
72 
73 		// Put every log message in "everything.log":
74 		loguru::add_file("everything.log", loguru::Append, loguru::Verbosity_MAX);
75 
76 		LOG_F(INFO, "The magic number is %d", 42);
77 	}
78 
79 */
80 
81 // XXX(kitware): // include exports header
82 #include "vtkloguru_export.h"
83 // XXX(kitware): // mangle
84 #define loguru vtkloguru
85 // XXX(kitware): // vtk config defaults
86 #define LOGURU_WITH_STREAMS 1
87 
88 #if defined(LOGURU_IMPLEMENTATION)
89 	#error "You are defining LOGURU_IMPLEMENTATION. This is for older versions of Loguru. You should now instead include loguru.cpp (or build it and link with it)"
90 #endif
91 
92 // Disable all warnings from gcc/clang:
93 #if defined(__clang__)
94 	#pragma clang system_header
95 #elif defined(__GNUC__)
96 	#pragma GCC system_header
97 #endif
98 
99 #ifndef LOGURU_HAS_DECLARED_FORMAT_HEADER
100 #define LOGURU_HAS_DECLARED_FORMAT_HEADER
101 
102 // Semantic versioning. Loguru version can be printed with printf("%d.%d.%d", LOGURU_VERSION_MAJOR, LOGURU_VERSION_MINOR, LOGURU_VERSION_PATCH);
103 #define LOGURU_VERSION_MAJOR 2
104 #define LOGURU_VERSION_MINOR 1
105 #define LOGURU_VERSION_PATCH 0
106 
107 #if defined(_MSC_VER)
108 #include <sal.h>	// Needed for _In_z_ etc annotations
109 #endif
110 
111 // ----------------------------------------------------------------------------
112 
113 #ifndef LOGURU_EXPORT
114 	// Define to your project's export declaration if needed for use in a shared library.
115 	#define LOGURU_EXPORT
116 #endif
117 
118 #ifndef LOGURU_SCOPE_TEXT_SIZE
119 	// Maximum length of text that can be printed by a LOG_SCOPE.
120 	// This should be long enough to get most things, but short enough not to clutter the stack.
121 	#define LOGURU_SCOPE_TEXT_SIZE 196
122 #endif
123 
124 #ifndef LOGURU_FILENAME_WIDTH
125 	// Width of the column containing the file name
126 	#define LOGURU_FILENAME_WIDTH 23
127 #endif
128 
129 #ifndef LOGURU_THREADNAME_WIDTH
130 	// Width of the column containing the thread name
131 	#define LOGURU_THREADNAME_WIDTH 16
132 #endif
133 
134 #ifndef LOGURU_SCOPE_TIME_PRECISION
135 	// Resolution of scope timers. 3=ms, 6=us, 9=ns
136 	#define LOGURU_SCOPE_TIME_PRECISION 3
137 #endif
138 
139 #ifndef LOGURU_CATCH_SIGABRT
140 	// Should Loguru catch SIGABRT to print stack trace etc?
141 	#define LOGURU_CATCH_SIGABRT 1
142 #endif
143 
144 #ifndef LOGURU_VERBOSE_SCOPE_ENDINGS
145 	// Show milliseconds and scope name at end of scope.
146 	#define LOGURU_VERBOSE_SCOPE_ENDINGS 1
147 #endif
148 
149 #ifndef LOGURU_REDEFINE_ASSERT
150 	#define LOGURU_REDEFINE_ASSERT 0
151 #endif
152 
153 #ifndef LOGURU_WITH_STREAMS
154 	#define LOGURU_WITH_STREAMS 0
155 #endif
156 
157 #ifndef LOGURU_REPLACE_GLOG
158 	#define LOGURU_REPLACE_GLOG 0
159 #endif
160 
161 #if LOGURU_REPLACE_GLOG
162 	#undef LOGURU_WITH_STREAMS
163 	#define LOGURU_WITH_STREAMS 1
164 #endif
165 
166 #if defined(LOGURU_UNSAFE_SIGNAL_HANDLER)
167 	#error "You are defining LOGURU_UNSAFE_SIGNAL_HANDLER. This is for older versions of Loguru. You should now instead set the unsafe_signal_handler option when you call loguru::init."
168 #endif
169 
170 #if LOGURU_IMPLEMENTATION
171 	#undef LOGURU_WITH_STREAMS
172 	#define LOGURU_WITH_STREAMS 1
173 #endif
174 
175 #ifndef LOGURU_USE_FMTLIB
176 	#define LOGURU_USE_FMTLIB 0
177 #endif
178 
179 #ifndef LOGURU_WITH_FILEABS
180 	#define LOGURU_WITH_FILEABS 0
181 #endif
182 
183 #ifndef LOGURU_RTTI
184 #if defined(__clang__)
185 	#if __has_feature(cxx_rtti)
186 		#define LOGURU_RTTI 1
187 	#endif
188 #elif defined(__GNUG__)
189 	#if defined(__GXX_RTTI)
190 		#define LOGURU_RTTI 1
191 	#endif
192 #elif defined(_MSC_VER)
193 	#if defined(_CPPRTTI)
194 		#define LOGURU_RTTI 1
195 	#endif
196 #endif
197 #endif
198 
199 // --------------------------------------------------------------------
200 // Utility macros
201 
202 #define LOGURU_CONCATENATE_IMPL(s1, s2) s1 ## s2
203 #define LOGURU_CONCATENATE(s1, s2) LOGURU_CONCATENATE_IMPL(s1, s2)
204 
205 #ifdef __COUNTER__
206 #   define LOGURU_ANONYMOUS_VARIABLE(str) LOGURU_CONCATENATE(str, __COUNTER__)
207 #else
208 #   define LOGURU_ANONYMOUS_VARIABLE(str) LOGURU_CONCATENATE(str, __LINE__)
209 #endif
210 
211 #if defined(__clang__) || defined(__GNUC__)
212 	// Helper macro for declaring functions as having similar signature to printf.
213 	// This allows the compiler to catch format errors at compile-time.
214 	#define LOGURU_PRINTF_LIKE(fmtarg, firstvararg) __attribute__((__format__ (__printf__, fmtarg, firstvararg)))
215 	#define LOGURU_FORMAT_STRING_TYPE const char*
216 #elif defined(_MSC_VER)
217 	#define LOGURU_PRINTF_LIKE(fmtarg, firstvararg)
218 	#define LOGURU_FORMAT_STRING_TYPE _In_z_ _Printf_format_string_ const char*
219 #else
220 	#define LOGURU_PRINTF_LIKE(fmtarg, firstvararg)
221 	#define LOGURU_FORMAT_STRING_TYPE const char*
222 #endif
223 
224 // Used to mark log_and_abort for the benefit of the static analyzer and optimizer.
225 #if defined(_MSC_VER)
226 #define LOGURU_NORETURN __declspec(noreturn)
227 #else
228 #define LOGURU_NORETURN __attribute__((noreturn))
229 #endif
230 
231 #if defined(_MSC_VER)
232 #define LOGURU_PREDICT_FALSE(x) (x)
233 #define LOGURU_PREDICT_TRUE(x)  (x)
234 #else
235 #define LOGURU_PREDICT_FALSE(x) (__builtin_expect(x,     0))
236 #define LOGURU_PREDICT_TRUE(x)  (__builtin_expect(!!(x), 1))
237 #endif
238 
239 #if LOGURU_USE_FMTLIB
240 	#include <fmt/format.h>
241 	#define LOGURU_FMT(x) "{:" #x "}"
242 #else
243 	#define LOGURU_FMT(x) "%" #x
244 #endif
245 
246 #ifdef _WIN32
247 	#define STRDUP(str) _strdup(str)
248 #else
249 	#define STRDUP(str) strdup(str)
250 #endif
251 
252 // --------------------------------------------------------------------
253 
254 namespace loguru
255 {
256 	// Simple RAII ownership of a char*.
257 	class LOGURU_EXPORT Text
258 	{
259 	public:
Text(char * owned_str)260 		explicit Text(char* owned_str) : _str(owned_str) {}
261 		~Text();
Text(Text && t)262 		Text(Text&& t)
263 		{
264 			_str = t._str;
265 			t._str = nullptr;
266 		}
267 		Text(Text& t) = delete;
268 		Text& operator=(Text& t) = delete;
269 		void operator=(Text&& t) = delete;
270 
c_str() const271 		const char* c_str() const { return _str; }
empty() const272 		bool empty() const { return _str == nullptr || *_str == '\0'; }
273 
release()274 		char* release()
275 		{
276 			auto result = _str;
277 			_str = nullptr;
278 			return result;
279 		}
280 
281 	private:
282 		char* _str;
283 	};
284 
285 	// Like printf, but returns the formated text.
286 #if LOGURU_USE_FMTLIB
287 	LOGURU_EXPORT
288 	Text vtextprintf(const char* format, fmt::format_args args);
289 
290 	template<typename... Args>
291 	LOGURU_EXPORT
textprintf(LOGURU_FORMAT_STRING_TYPE format,const Args &...args)292 	Text textprintf(LOGURU_FORMAT_STRING_TYPE format, const Args&... args) {
293 		return vtextprintf(format, fmt::make_format_args(args...));
294 	}
295 #else
296 	LOGURU_EXPORT
297 	Text textprintf(LOGURU_FORMAT_STRING_TYPE format, ...) LOGURU_PRINTF_LIKE(1, 2);
298 #endif
299 
300 	// Overloaded for variadic template matching.
301 	LOGURU_EXPORT
302 	Text textprintf();
303 
304 	using Verbosity = int;
305 
306 #undef FATAL
307 #undef ERROR
308 #undef WARNING
309 #undef INFO
310 #undef MAX
311 
312 	enum NamedVerbosity : Verbosity
313 	{
314 		// Used to mark an invalid verbosity. Do not log to this level.
315 		Verbosity_INVALID = -10, // Never do LOG_F(INVALID)
316 
317 		// You may use Verbosity_OFF on g_stderr_verbosity, but for nothing else!
318 		Verbosity_OFF     = -9, // Never do LOG_F(OFF)
319 
320 		// Prefer to use ABORT_F or ABORT_S over LOG_F(FATAL) or LOG_S(FATAL).
321 		Verbosity_FATAL   = -3,
322 		Verbosity_ERROR   = -2,
323 		Verbosity_WARNING = -1,
324 
325 		// Normal messages. By default written to stderr.
326 		Verbosity_INFO    =  0,
327 
328 		// Same as Verbosity_INFO in every way.
329 		Verbosity_0       =  0,
330 
331 		// Verbosity levels 1-9 are generally not written to stderr, but are written to file.
332 		Verbosity_1       = +1,
333 		Verbosity_2       = +2,
334 		Verbosity_3       = +3,
335 		Verbosity_4       = +4,
336 		Verbosity_5       = +5,
337 		Verbosity_6       = +6,
338 		Verbosity_7       = +7,
339 		Verbosity_8       = +8,
340 		Verbosity_9       = +9,
341 
342 		// Don not use higher verbosity levels, as that will make grepping log files harder.
343 		Verbosity_MAX     = +9,
344 	};
345 
346 	struct Message
347 	{
348 		// You would generally print a Message by just concating the buffers without spacing.
349 		// Optionally, ignore preamble and indentation.
350 		Verbosity   verbosity;   // Already part of preamble
351 		const char* filename;    // Already part of preamble
352 		unsigned    line;        // Already part of preamble
353 		const char* preamble;    // Date, time, uptime, thread, file:line, verbosity.
354 		const char* indentation; // Just a bunch of spacing.
355 		const char* prefix;      // Assertion failure info goes here (or "").
356 		const char* message;     // User message goes here.
357 	};
358 
359 	/* Everything with a verbosity equal or greater than g_stderr_verbosity will be
360 	written to stderr. You can set this in code or via the -v argument.
361 	Set to loguru::Verbosity_OFF to write nothing to stderr.
362 	Default is 0, i.e. only log ERROR, WARNING and INFO are written to stderr.
363 	*/
364 	LOGURU_EXPORT extern Verbosity g_stderr_verbosity;
365 	LOGURU_EXPORT extern bool      g_colorlogtostderr; // True by default.
366 	LOGURU_EXPORT extern unsigned  g_flush_interval_ms; // 0 (unbuffered) by default.
367 	LOGURU_EXPORT extern bool      g_preamble; // Prefix each log line with date, time etc? True by default.
368 
369 	/* Specify the verbosity used by loguru to log its info messages including the header
370 	logged when logged::init() is called or on exit. Default is 0 (INFO).
371 	*/
372 	LOGURU_EXPORT extern Verbosity g_internal_verbosity;
373 
374 	// Turn off individual parts of the preamble
375 	LOGURU_EXPORT extern bool      g_preamble_date; // The date field
376 	LOGURU_EXPORT extern bool      g_preamble_time; // The time of the current day
377 	LOGURU_EXPORT extern bool      g_preamble_uptime; // The time since init call
378 	LOGURU_EXPORT extern bool      g_preamble_thread; // The logging thread
379 	LOGURU_EXPORT extern bool      g_preamble_file; // The file from which the log originates from
380 	LOGURU_EXPORT extern bool      g_preamble_verbose; // The verbosity field
381 	LOGURU_EXPORT extern bool      g_preamble_pipe; // The pipe symbol right before the message
382 
383 	// May not throw!
384 	typedef void (*log_handler_t)(void* user_data, const Message& message);
385 	typedef void (*close_handler_t)(void* user_data);
386 	typedef void (*flush_handler_t)(void* user_data);
387 
388 	// May throw if that's how you'd like to handle your errors.
389 	typedef void (*fatal_handler_t)(const Message& message);
390 
391 	// Given a verbosity level, return the level's name or nullptr.
392 	typedef const char* (*verbosity_to_name_t)(Verbosity verbosity);
393 
394 	// Given a verbosity level name, return the verbosity level or
395 	// Verbosity_INVALID if name is not recognized.
396 	typedef Verbosity (*name_to_verbosity_t)(const char* name);
397 
398 	// Runtime options passed to loguru::init
399 	struct Options
400 	{
401 		// This allows you to use something else instead of "-v" via verbosity_flag.
402 		// Set to nullptr to if you don't want Loguru to parse verbosity from the args.'
403 		const char* verbosity_flag = "-v";
404 
405 		// loguru::init will set the name of the calling thread to this.
406 		// If you don't want Loguru to set the name of the main thread,
407 		// set this to nullptr.
408 		// NOTE: on SOME platforms loguru::init will only overwrite the thread name
409 		// if a thread name has not already been set.
410 		// To always set a thread name, use loguru::set_thread_name instead.
411 		const char* main_thread_name = "main thread";
412 
413 		// Make Loguru try to do unsafe but useful things,
414 		// like printing a stack trace, when catching signals.
415 		// This may lead to bad things like deadlocks in certain situations.
416 		bool unsafe_signal_handler = true;
417 	};
418 
419 	/*  Should be called from the main thread.
420 		You don't *need* to call this, but if you do you get:
421 			* Signal handlers installed
422 			* Program arguments logged
423 			* Working dir logged
424 			* Optional -v verbosity flag parsed
425 			* Main thread name set to "main thread"
426 			* Explanation of the preamble (date, threanmae etc) logged
427 
428 		loguru::init() will look for arguments meant for loguru and remove them.
429 		Arguments meant for loguru are:
430 			-v n   Set loguru::g_stderr_verbosity level. Examples:
431 				-v 3        Show verbosity level 3 and lower.
432 				-v 0        Only show INFO, WARNING, ERROR, FATAL (default).
433 				-v INFO     Only show INFO, WARNING, ERROR, FATAL (default).
434 				-v WARNING  Only show WARNING, ERROR, FATAL.
435 				-v ERROR    Only show ERROR, FATAL.
436 				-v FATAL    Only show FATAL.
437 				-v OFF      Turn off logging to stderr.
438 
439 		Tip: You can set g_stderr_verbosity before calling loguru::init.
440 		That way you can set the default but have the user override it with the -v flag.
441 		Note that -v does not affect file logging (see loguru::add_file).
442 
443 		You can you something other than the -v flag by setting the verbosity_flag option.
444 	*/
445 	LOGURU_EXPORT
446 	void init(int& argc, char* argv[], const Options& options = {});
447 
448 	// Will call remove_all_callbacks(). After calling this, logging will still go to stderr.
449 	// You generally don't need to call this.
450 	LOGURU_EXPORT
451 	void shutdown();
452 
453 	// What ~ will be replaced with, e.g. "/home/your_user_name/"
454 	LOGURU_EXPORT
455 	const char* home_dir();
456 
457 	/* Returns the name of the app as given in argv[0] but without leading path.
458 	   That is, if argv[0] is "../foo/app" this will return "app".
459 	*/
460 	LOGURU_EXPORT
461 	const char* argv0_filename();
462 
463 	// Returns all arguments given to loguru::init(), but escaped with a single space as separator.
464 	LOGURU_EXPORT
465 	const char* arguments();
466 
467 	// Returns the path to the current working dir when loguru::init() was called.
468 	LOGURU_EXPORT
469 	const char* current_dir();
470 
471 	// Returns the part of the path after the last / or \ (if any).
472 	LOGURU_EXPORT
473 	const char* filename(const char* path);
474 
475 	// e.g. "foo/bar/baz.ext" will create the directories "foo/" and "foo/bar/"
476 	LOGURU_EXPORT
477 	bool create_directories(const char* file_path_const);
478 
479 	// Writes date and time with millisecond precision, e.g. "20151017_161503.123"
480 	LOGURU_EXPORT
481 	void write_date_time(char* buff, unsigned buff_size);
482 
483 	// Helper: thread-safe version strerror
484 	LOGURU_EXPORT
485 	Text errno_as_text();
486 
487 	/* Given a prefix of e.g. "~/loguru/" this might return
488 	   "/home/your_username/loguru/app_name/20151017_161503.123.log"
489 
490 	   where "app_name" is a sanitized version of argv[0].
491 	*/
492 	LOGURU_EXPORT
493 	void suggest_log_path(const char* prefix, char* buff, unsigned buff_size);
494 
495 	enum FileMode { Truncate, Append };
496 
497 	/*  Will log to a file at the given path.
498 		Any logging message with a verbosity lower or equal to
499 		the given verbosity will be included.
500 		The function will create all directories in 'path' if needed.
501 		If path starts with a ~, it will be replaced with loguru::home_dir()
502 		To stop the file logging, just call loguru::remove_callback(path) with the same path.
503 	*/
504 	LOGURU_EXPORT
505 	bool add_file(const char* path, FileMode mode, Verbosity verbosity);
506 
507 	/*  Will be called right before abort().
508 		You can for instance use this to print custom error messages, or throw an exception.
509 		Feel free to call LOG:ing function from this, but not FATAL ones! */
510 	LOGURU_EXPORT
511 	void set_fatal_handler(fatal_handler_t handler);
512 
513 	// Get the current fatal handler, if any. Default value is nullptr.
514 	LOGURU_EXPORT
515 	fatal_handler_t get_fatal_handler();
516 
517 	/*  Will be called on each log messages with a verbosity less or equal to the given one.
518 		Useful for displaying messages on-screen in a game, for example.
519 		The given on_close is also expected to flush (if desired).
520 	*/
521 	LOGURU_EXPORT
522 	void add_callback(
523 		const char*     id,
524 		log_handler_t   callback,
525 		void*           user_data,
526 		Verbosity       verbosity,
527 		close_handler_t on_close = nullptr,
528 		flush_handler_t on_flush = nullptr);
529 
530 	/*  Set a callback that returns custom verbosity level names. If callback
531 		is nullptr or returns nullptr, default log names will be used.
532 	*/
533 	LOGURU_EXPORT
534 	void set_verbosity_to_name_callback(verbosity_to_name_t callback);
535 
536 	/*  Set a callback that returns the verbosity level matching a name. The
537 		callback should return Verbosity_INVALID if the name is not
538 		recognized.
539 	*/
540 	LOGURU_EXPORT
541 	void set_name_to_verbosity_callback(name_to_verbosity_t callback);
542 
543 	/*  Get a custom name for a specific verbosity, if one exists, or nullptr. */
544 	LOGURU_EXPORT
545 	const char* get_verbosity_name(Verbosity verbosity);
546 
547 	/*  Get the verbosity enum value from a custom 4-character level name, if one exists.
548 		If the name does not match a custom level name, Verbosity_INVALID is returned.
549 	*/
550 	LOGURU_EXPORT
551 	Verbosity get_verbosity_from_name(const char* name);
552 
553 	// Returns true iff the callback was found (and removed).
554 	LOGURU_EXPORT
555 	bool remove_callback(const char* id);
556 
557 	// Shut down all file logging and any other callback hooks installed.
558 	LOGURU_EXPORT
559 	void remove_all_callbacks();
560 
561 	// Returns the maximum of g_stderr_verbosity and all file/custom outputs.
562 	LOGURU_EXPORT
563 	Verbosity current_verbosity_cutoff();
564 
565 #if LOGURU_USE_FMTLIB
566 	// Internal functions
567 	void vlog(Verbosity verbosity, const char* file, unsigned line, LOGURU_FORMAT_STRING_TYPE format, fmt::format_args args);
568 	void raw_vlog(Verbosity verbosity, const char* file, unsigned line, LOGURU_FORMAT_STRING_TYPE format, fmt::format_args args);
569 
570 	// Actual logging function. Use the LOG macro instead of calling this directly.
571 	template <typename... Args>
572 	LOGURU_EXPORT
log(Verbosity verbosity,const char * file,unsigned line,LOGURU_FORMAT_STRING_TYPE format,const Args &...args)573 	void log(Verbosity verbosity, const char* file, unsigned line, LOGURU_FORMAT_STRING_TYPE format, const Args &... args) {
574 	    vlog(verbosity, file, line, format, fmt::make_format_args(args...));
575 	}
576 
577 	// Log without any preamble or indentation.
578 	template <typename... Args>
579 	LOGURU_EXPORT
raw_log(Verbosity verbosity,const char * file,unsigned line,LOGURU_FORMAT_STRING_TYPE format,const Args &...args)580 	void raw_log(Verbosity verbosity, const char* file, unsigned line, LOGURU_FORMAT_STRING_TYPE format, const Args &... args) {
581 	    raw_vlog(verbosity, file, line, format, fmt::make_format_args(args...));
582 	}
583 #else // LOGURU_USE_FMTLIB?
584 	// Actual logging function. Use the LOG macro instead of calling this directly.
585 	LOGURU_EXPORT
586 	void log(Verbosity verbosity, const char* file, unsigned line, LOGURU_FORMAT_STRING_TYPE format, ...) LOGURU_PRINTF_LIKE(4, 5);
587 
588 	// Log without any preamble or indentation.
589 	LOGURU_EXPORT
590 	void raw_log(Verbosity verbosity, const char* file, unsigned line, LOGURU_FORMAT_STRING_TYPE format, ...) LOGURU_PRINTF_LIKE(4, 5);
591 #endif // !LOGURU_USE_FMTLIB
592 
593 	// Helper class for LOG_SCOPE_F
594 	class LOGURU_EXPORT LogScopeRAII
595 	{
596 	public:
LogScopeRAII()597 		LogScopeRAII() : _file(nullptr) {} // No logging
598 		LogScopeRAII(Verbosity verbosity, const char* file, unsigned line, LOGURU_FORMAT_STRING_TYPE format, ...) LOGURU_PRINTF_LIKE(5, 6);
599 		~LogScopeRAII();
600 
601 #if defined(_MSC_VER) && _MSC_VER > 1800
602 		// older MSVC default move ctors close the scope on move. See
603 		// issue #43
LogScopeRAII(LogScopeRAII && other)604 		LogScopeRAII(LogScopeRAII&& other)
605 			: _verbosity(other._verbosity)
606 			, _file(other._file)
607 			, _line(other._line)
608 			, _indent_stderr(other._indent_stderr)
609 			, _start_time_ns(other._start_time_ns)
610 		{
611 			// Make sure the tmp object's destruction doesn't close the scope:
612 			other._file = nullptr;
613 
614 			for (unsigned int i = 0; i < LOGURU_SCOPE_TEXT_SIZE; ++i) {
615 				_name[i] = other._name[i];
616 			}
617 		}
618 #else
619 		LogScopeRAII(LogScopeRAII&&) = default;
620 #endif
621 
622 	private:
623 		LogScopeRAII(const LogScopeRAII&) = delete;
624 		LogScopeRAII& operator=(const LogScopeRAII&) = delete;
625 		void operator=(LogScopeRAII&&) = delete;
626 
627 		Verbosity   _verbosity;
628 		const char* _file; // Set to null if we are disabled due to verbosity
629 		unsigned    _line;
630 		bool        _indent_stderr; // Did we?
631 		long long   _start_time_ns;
632 		char        _name[LOGURU_SCOPE_TEXT_SIZE];
633 	};
634 
635 	// Marked as 'noreturn' for the benefit of the static analyzer and optimizer.
636 	// stack_trace_skip is the number of extrace stack frames to skip above log_and_abort.
637 #if LOGURU_USE_FMTLIB
638 	LOGURU_EXPORT
639 	LOGURU_NORETURN void vlog_and_abort(int stack_trace_skip, const char* expr, const char* file, unsigned line, LOGURU_FORMAT_STRING_TYPE format, fmt::format_args);
640 	template <typename... Args>
641 	LOGURU_EXPORT
log_and_abort(int stack_trace_skip,const char * expr,const char * file,unsigned line,LOGURU_FORMAT_STRING_TYPE format,const Args &...args)642 	LOGURU_NORETURN void log_and_abort(int stack_trace_skip, const char* expr, const char* file, unsigned line, LOGURU_FORMAT_STRING_TYPE format, const Args&... args) {
643 	    vlog_and_abort(stack_trace_skip, expr, file, line, format, fmt::make_format_args(args...));
644 	}
645 #else
646 	LOGURU_EXPORT
647 	LOGURU_NORETURN void log_and_abort(int stack_trace_skip, const char* expr, const char* file, unsigned line, LOGURU_FORMAT_STRING_TYPE format, ...) LOGURU_PRINTF_LIKE(5, 6);
648 #endif
649 	LOGURU_EXPORT
650 	LOGURU_NORETURN void log_and_abort(int stack_trace_skip, const char* expr, const char* file, unsigned line);
651 
652 	// Flush output to stderr and files.
653 	// If g_flush_interval_ms is set to non-zero, this will be called automatically this often.
654 	// If not set, you do not need to call this at all.
655 	LOGURU_EXPORT
656 	void flush();
657 
format_value(const T &)658 	template<class T> inline Text format_value(const T&)                    { return textprintf("N/A");     }
format_value(const char & v)659 	template<>        inline Text format_value(const char& v)               { return textprintf(LOGURU_FMT(c),   v); }
format_value(const int & v)660 	template<>        inline Text format_value(const int& v)                { return textprintf(LOGURU_FMT(d),   v); }
format_value(const unsigned int & v)661 	template<>        inline Text format_value(const unsigned int& v)       { return textprintf(LOGURU_FMT(u),   v); }
format_value(const long & v)662 	template<>        inline Text format_value(const long& v)               { return textprintf(LOGURU_FMT(lu),  v); }
format_value(const unsigned long & v)663 	template<>        inline Text format_value(const unsigned long& v)      { return textprintf(LOGURU_FMT(ld),  v); }
format_value(const long long & v)664 	template<>        inline Text format_value(const long long& v)          { return textprintf(LOGURU_FMT(llu), v); }
format_value(const unsigned long long & v)665 	template<>        inline Text format_value(const unsigned long long& v) { return textprintf(LOGURU_FMT(lld), v); }
format_value(const float & v)666 	template<>        inline Text format_value(const float& v)              { return textprintf(LOGURU_FMT(f),   v); }
format_value(const double & v)667 	template<>        inline Text format_value(const double& v)             { return textprintf(LOGURU_FMT(f),   v); }
668 
669 	/* Thread names can be set for the benefit of readable logs.
670 	   If you do not set the thread name, a hex id will be shown instead.
671 	   These thread names may or may not be the same as the system thread names,
672 	   depending on the system.
673 	   Try to limit the thread name to 15 characters or less. */
674 	LOGURU_EXPORT
675 	void set_thread_name(const char* name);
676 
677 	/* Returns the thread name for this thread.
678 	   On OSX this will return the system thread name (settable from both within and without Loguru).
679 	   On other systems it will return whatever you set in set_thread_name();
680 	   If no thread name is set, this will return a hexadecimal thread id.
681 	   length should be the number of bytes available in the buffer.
682 	   17 is a good number for length.
683 	   right_align_hext_id means any hexadecimal thread id will be written to the end of buffer.
684 	*/
685 	LOGURU_EXPORT
686 	void get_thread_name(char* buffer, unsigned long long length, bool right_align_hext_id);
687 
688 	/* Generates a readable stacktrace as a string.
689 	   'skip' specifies how many stack frames to skip.
690 	   For instance, the default skip (1) means:
691 	   don't include the call to loguru::stacktrace in the stack trace. */
692 	LOGURU_EXPORT
693 	Text stacktrace(int skip = 1);
694 
695 	/*  Add a string to be replaced with something else in the stack output.
696 
697 		For instance, instead of having a stack trace look like this:
698 			0x41f541 some_function(std::basic_ofstream<char, std::char_traits<char> >&)
699 		You can clean it up with:
700 			auto verbose_type_name = loguru::demangle(typeid(std::ofstream).name());
701 			loguru::add_stack_cleanup(verbose_type_name.c_str(); "std::ofstream");
702 		So the next time you will instead see:
703 			0x41f541 some_function(std::ofstream&)
704 
705 		`replace_with_this` must be shorter than `find_this`.
706 	*/
707 	LOGURU_EXPORT
708 	void add_stack_cleanup(const char* find_this, const char* replace_with_this);
709 
710 	// Example: demangle(typeid(std::ofstream).name()) -> "std::basic_ofstream<char, std::char_traits<char> >"
711 	LOGURU_EXPORT
712 	Text demangle(const char* name);
713 
714 	// ------------------------------------------------------------------------
715 	/*
716 	Not all terminals support colors, but if they do, and g_colorlogtostderr
717 	is set, Loguru will write them to stderr to make errors in red, etc.
718 
719 	You also have the option to manually use them, via the function below.
720 
721 	Note, however, that if you do, the color codes could end up in your logfile!
722 
723 	This means if you intend to use them functions you should either:
724 		* Use them on the stderr/stdout directly (bypass Loguru).
725 		* Don't add file outputs to Loguru.
726 		* Expect some \e[1m things in your logfile.
727 
728 	Usage:
729 		printf("%sRed%sGreen%sBold green%sClear again\n",
730 			   loguru::terminal_red(), loguru::terminal_green(),
731 			   loguru::terminal_bold(), loguru::terminal_reset());
732 
733 	If the terminal at hand does not support colors the above output
734 	will just not have funky \e[1m things showing.
735 	*/
736 
737 	// Do the output terminal support colors?
738 	LOGURU_EXPORT
739 	bool terminal_has_color();
740 
741 	// Colors
742 	LOGURU_EXPORT const char* terminal_black();
743 	LOGURU_EXPORT const char* terminal_red();
744 	LOGURU_EXPORT const char* terminal_green();
745 	LOGURU_EXPORT const char* terminal_yellow();
746 	LOGURU_EXPORT const char* terminal_blue();
747 	LOGURU_EXPORT const char* terminal_purple();
748 	LOGURU_EXPORT const char* terminal_cyan();
749 	LOGURU_EXPORT const char* terminal_light_gray();
750 	LOGURU_EXPORT const char* terminal_light_red();
751 	LOGURU_EXPORT const char* terminal_white();
752 
753 	// Formating
754 	LOGURU_EXPORT const char* terminal_bold();
755 	LOGURU_EXPORT const char* terminal_underline();
756 
757 	// You should end each line with this!
758 	LOGURU_EXPORT const char* terminal_reset();
759 
760 	// --------------------------------------------------------------------
761 	// Error context related:
762 
763 	struct StringStream;
764 
765 	// Use this in your EcEntryBase::print_value overload.
766 	LOGURU_EXPORT
767 	void stream_print(StringStream& out_string_stream, const char* text);
768 
769 	class LOGURU_EXPORT EcEntryBase
770 	{
771 	public:
772 		EcEntryBase(const char* file, unsigned line, const char* descr);
773 		~EcEntryBase();
774 		EcEntryBase(const EcEntryBase&) = delete;
775 		EcEntryBase(EcEntryBase&&) = delete;
776 		EcEntryBase& operator=(const EcEntryBase&) = delete;
777 		EcEntryBase& operator=(EcEntryBase&&) = delete;
778 
779 		virtual void print_value(StringStream& out_string_stream) const = 0;
780 
previous() const781 		EcEntryBase* previous() const { return _previous; }
782 
783 	// private:
784 		const char*  _file;
785 		unsigned     _line;
786 		const char*  _descr;
787 		EcEntryBase* _previous;
788 	};
789 
790 	template<typename T>
791 	class EcEntryData : public EcEntryBase
792 	{
793 	public:
794 		using Printer = Text(*)(T data);
795 
EcEntryData(const char * file,unsigned line,const char * descr,T data,Printer && printer)796 		EcEntryData(const char* file, unsigned line, const char* descr, T data, Printer&& printer)
797 			: EcEntryBase(file, line, descr), _data(data), _printer(printer) {}
798 
print_value(StringStream & out_string_stream) const799 		virtual void print_value(StringStream& out_string_stream) const override
800 		{
801 			const auto str = _printer(_data);
802 			stream_print(out_string_stream, str.c_str());
803 		}
804 
805 	private:
806 		T       _data;
807 		Printer _printer;
808 	};
809 
810 	// template<typename Printer>
811 	// class EcEntryLambda : public EcEntryBase
812 	// {
813 	// public:
814 	// 	EcEntryLambda(const char* file, unsigned line, const char* descr, Printer&& printer)
815 	// 		: EcEntryBase(file, line, descr), _printer(std::move(printer)) {}
816 
817 	// 	virtual void print_value(StringStream& out_string_stream) const override
818 	// 	{
819 	// 		const auto str = _printer();
820 	// 		stream_print(out_string_stream, str.c_str());
821 	// 	}
822 
823 	// private:
824 	// 	Printer _printer;
825 	// };
826 
827 	// template<typename Printer>
828 	// EcEntryLambda<Printer> make_ec_entry_lambda(const char* file, unsigned line, const char* descr, Printer&& printer)
829 	// {
830 	// 	return {file, line, descr, std::move(printer)};
831 	// }
832 
833 	template <class T>
834 	struct decay_char_array { using type = T; };
835 
836 	template <unsigned long long  N>
837 	struct decay_char_array<const char(&)[N]> { using type = const char*; };
838 
839 	template <class T>
840 	struct make_const_ptr { using type = T; };
841 
842 	template <class T>
843 	struct make_const_ptr<T*> { using type = const T*; };
844 
845 	template <class T>
846 	struct make_ec_type { using type = typename make_const_ptr<typename decay_char_array<T>::type>::type; };
847 
848 	/* 	A stack trace gives you the names of the function at the point of a crash.
849 		With ERROR_CONTEXT, you can also get the values of select local variables.
850 		Usage:
851 
852 		void process_customers(const std::string& filename)
853 		{
854 			ERROR_CONTEXT("Processing file", filename.c_str());
855 			for (int customer_index : ...)
856 			{
857 				ERROR_CONTEXT("Customer index", customer_index);
858 				...
859 			}
860 		}
861 
862 		The context is in effect during the scope of the ERROR_CONTEXT.
863 		Use loguru::get_error_context() to get the contents of the active error contexts.
864 
865 		Example result:
866 
867 		------------------------------------------------
868 		[ErrorContext]                main.cpp:416   Processing file:    "customers.json"
869 		[ErrorContext]                main.cpp:417   Customer index:     42
870 		------------------------------------------------
871 
872 		Error contexts are printed automatically on crashes, and only on crashes.
873 		This makes them much faster than logging the value of a variable.
874 	*/
875 	#define ERROR_CONTEXT(descr, data)                                             \
876 		const loguru::EcEntryData<loguru::make_ec_type<decltype(data)>::type>      \
877 			LOGURU_ANONYMOUS_VARIABLE(error_context_scope_)(                       \
878 				__FILE__, __LINE__, descr, data,                                   \
879 				static_cast<loguru::EcEntryData<loguru::make_ec_type<decltype(data)>::type>::Printer>(loguru::ec_to_text) ) // For better error messages
880 
881 /*
882 	#define ERROR_CONTEXT(descr, data)                                 \
883 		const auto LOGURU_ANONYMOUS_VARIABLE(error_context_scope_)(    \
884 			loguru::make_ec_entry_lambda(__FILE__, __LINE__, descr,    \
885 				[=](){ return loguru::ec_to_text(data); }))
886 */
887 
888 	using EcHandle = const EcEntryBase*;
889 
890 	/*
891 		Get a light-weight handle to the error context stack on this thread.
892 		The handle is valid as long as the current thread has no changes to its error context stack.
893 		You can pass the handle to loguru::get_error_context on another thread.
894 		This can be very useful for when you have a parent thread spawning several working threads,
895 		and you want the error context of the parent thread to get printed (too) when there is an
896 		error on the child thread. You can accomplish this thusly:
897 
898 		void foo(const char* parameter)
899 		{
900 			ERROR_CONTEXT("parameter", parameter)
901 			const auto parent_ec_handle = loguru::get_thread_ec_handle();
902 
903 			std::thread([=]{
904 				loguru::set_thread_name("child thread");
905 				ERROR_CONTEXT("parent context", parent_ec_handle);
906 				dangerous_code();
907 			}.join();
908 		}
909 
910 	*/
911 	LOGURU_EXPORT
912 	EcHandle get_thread_ec_handle();
913 
914 	// Get a string describing the current stack of error context. Empty string if there is none.
915 	LOGURU_EXPORT
916 	Text get_error_context();
917 
918 	// Get a string describing the error context of the given thread handle.
919 	LOGURU_EXPORT
920 	Text get_error_context_for(EcHandle ec_handle);
921 
922 	// ------------------------------------------------------------------------
923 
924 	LOGURU_EXPORT Text ec_to_text(const char* data);
925 	LOGURU_EXPORT Text ec_to_text(char data);
926 	LOGURU_EXPORT Text ec_to_text(int data);
927 	LOGURU_EXPORT Text ec_to_text(unsigned int data);
928 	LOGURU_EXPORT Text ec_to_text(long data);
929 	LOGURU_EXPORT Text ec_to_text(unsigned long data);
930 	LOGURU_EXPORT Text ec_to_text(long long data);
931 	LOGURU_EXPORT Text ec_to_text(unsigned long long data);
932 	LOGURU_EXPORT Text ec_to_text(float data);
933 	LOGURU_EXPORT Text ec_to_text(double data);
934 	LOGURU_EXPORT Text ec_to_text(long double data);
935 	LOGURU_EXPORT Text ec_to_text(EcHandle);
936 
937 	/*
938 	You can add ERROR_CONTEXT support for your own types by overloading ec_to_text. Here's how:
939 
940 	some.hpp:
941 		namespace loguru {
942 			Text ec_to_text(MySmallType data)
943 			Text ec_to_text(const MyBigType* data)
944 		} // namespace loguru
945 
946 	some.cpp:
947 		namespace loguru {
948 			Text ec_to_text(MySmallType small_value)
949 			{
950 				// Called only when needed, i.e. on a crash.
951 				std::string str = small_value.as_string(); // Format 'small_value' here somehow.
952 				return Text{STRDUP(str.c_str())};
953 			}
954 
955 			Text ec_to_text(const MyBigType* big_value)
956 			{
957 				// Called only when needed, i.e. on a crash.
958 				std::string str = big_value->as_string(); // Format 'big_value' here somehow.
959 				return Text{STRDUP(str.c_str())};
960 			}
961 		} // namespace loguru
962 
963 	Any file that include some.hpp:
964 		void foo(MySmallType small, const MyBigType& big)
965 		{
966 			ERROR_CONTEXT("Small", small); // Copy ´small` by value.
967 			ERROR_CONTEXT("Big",   &big);  // `big` should not change during this scope!
968 			....
969 		}
970 	*/
971 } // namespace loguru
972 
973 // --------------------------------------------------------------------
974 // Logging macros
975 
976 // LOG_F(2, "Only logged if verbosity is 2 or higher: %d", some_number);
977 #define VLOG_F(verbosity, ...)                                                                     \
978 	((verbosity) > loguru::current_verbosity_cutoff()) ? (void)0                                   \
979 									  : loguru::log(verbosity, __FILE__, __LINE__, __VA_ARGS__)
980 
981 // LOG_F(INFO, "Foo: %d", some_number);
982 #define LOG_F(verbosity_name, ...) VLOG_F(loguru::Verbosity_ ## verbosity_name, __VA_ARGS__)
983 
984 #define VLOG_IF_F(verbosity, cond, ...)                                                            \
985 	((verbosity) > loguru::current_verbosity_cutoff() || (cond) == false)                          \
986 		? (void)0                                                                                  \
987 		: loguru::log(verbosity, __FILE__, __LINE__, __VA_ARGS__)
988 
989 #define LOG_IF_F(verbosity_name, cond, ...)                                                        \
990 	VLOG_IF_F(loguru::Verbosity_ ## verbosity_name, cond, __VA_ARGS__)
991 
992 #define VLOG_SCOPE_F(verbosity, ...)                                                               \
993 	loguru::LogScopeRAII LOGURU_ANONYMOUS_VARIABLE(error_context_RAII_) =                          \
994 	((verbosity) > loguru::current_verbosity_cutoff()) ? loguru::LogScopeRAII() :                  \
995 	loguru::LogScopeRAII(verbosity, __FILE__, __LINE__, __VA_ARGS__)
996 
997 // Raw logging - no preamble, no indentation. Slightly faster than full logging.
998 #define RAW_VLOG_F(verbosity, ...)                                                                 \
999 	((verbosity) > loguru::current_verbosity_cutoff()) ? (void)0                                   \
1000 									  : loguru::raw_log(verbosity, __FILE__, __LINE__, __VA_ARGS__)
1001 
1002 #define RAW_LOG_F(verbosity_name, ...) RAW_VLOG_F(loguru::Verbosity_ ## verbosity_name, __VA_ARGS__)
1003 
1004 // Use to book-end a scope. Affects logging on all threads.
1005 #define LOG_SCOPE_F(verbosity_name, ...)                                                           \
1006 	VLOG_SCOPE_F(loguru::Verbosity_ ## verbosity_name, __VA_ARGS__)
1007 
1008 #define LOG_SCOPE_FUNCTION(verbosity_name) LOG_SCOPE_F(verbosity_name, __func__)
1009 
1010 // -----------------------------------------------
1011 // ABORT_F macro. Usage:  ABORT_F("Cause of error: %s", error_str);
1012 
1013 // Message is optional
1014 #define ABORT_F(...) loguru::log_and_abort(0, "ABORT: ", __FILE__, __LINE__, __VA_ARGS__)
1015 
1016 // --------------------------------------------------------------------
1017 // CHECK_F macros:
1018 
1019 #define CHECK_WITH_INFO_F(test, info, ...)                                                         \
1020 	LOGURU_PREDICT_TRUE((test) == true) ? (void)0 : loguru::log_and_abort(0, "CHECK FAILED:  " info "  ", __FILE__,      \
1021 													   __LINE__, ##__VA_ARGS__)
1022 
1023 /* Checked at runtime too. Will print error, then call fatal_handler (if any), then 'abort'.
1024    Note that the test must be boolean.
1025    CHECK_F(ptr); will not compile, but CHECK_F(ptr != nullptr); will. */
1026 #define CHECK_F(test, ...) CHECK_WITH_INFO_F(test, #test, ##__VA_ARGS__)
1027 
1028 #define CHECK_NOTNULL_F(x, ...) CHECK_WITH_INFO_F((x) != nullptr, #x " != nullptr", ##__VA_ARGS__)
1029 
1030 #define CHECK_OP_F(expr_left, expr_right, op, ...)                                                 \
1031 	do                                                                                             \
1032 	{                                                                                              \
1033 		auto val_left = expr_left;                                                                 \
1034 		auto val_right = expr_right;                                                               \
1035 		if (! LOGURU_PREDICT_TRUE(val_left op val_right))                                          \
1036 		{                                                                                          \
1037 			auto str_left = loguru::format_value(val_left);                                        \
1038 			auto str_right = loguru::format_value(val_right);                                      \
1039 			auto fail_info = loguru::textprintf("CHECK FAILED:  " LOGURU_FMT(s) " " LOGURU_FMT(s) " " LOGURU_FMT(s) "  (" LOGURU_FMT(s) " " LOGURU_FMT(s) " " LOGURU_FMT(s) ")  ",           \
1040 				#expr_left, #op, #expr_right, str_left.c_str(), #op, str_right.c_str());           \
1041 			auto user_msg = loguru::textprintf(__VA_ARGS__);                                       \
1042 			loguru::log_and_abort(0, fail_info.c_str(), __FILE__, __LINE__,                        \
1043 			                      LOGURU_FMT(s), user_msg.c_str());                                         \
1044 		}                                                                                          \
1045 	} while (false)
1046 
1047 #ifndef LOGURU_DEBUG_LOGGING
1048 	#ifndef NDEBUG
1049 		#define LOGURU_DEBUG_LOGGING 1
1050 	#else
1051 		#define LOGURU_DEBUG_LOGGING 0
1052 	#endif
1053 #endif
1054 
1055 #if LOGURU_DEBUG_LOGGING
1056 	// Debug logging enabled:
1057 	#define DLOG_F(verbosity_name, ...)     LOG_F(verbosity_name, __VA_ARGS__)
1058 	#define DVLOG_F(verbosity, ...)         VLOG_F(verbosity, __VA_ARGS__)
1059 	#define DLOG_IF_F(verbosity_name, ...)  LOG_IF_F(verbosity_name, __VA_ARGS__)
1060 	#define DVLOG_IF_F(verbosity, ...)      VLOG_IF_F(verbosity, __VA_ARGS__)
1061 	#define DRAW_LOG_F(verbosity_name, ...) RAW_LOG_F(verbosity_name, __VA_ARGS__)
1062 	#define DRAW_VLOG_F(verbosity, ...)     RAW_VLOG_F(verbosity, __VA_ARGS__)
1063 #else
1064 	// Debug logging disabled:
1065 	#define DLOG_F(verbosity_name, ...)
1066 	#define DVLOG_F(verbosity, ...)
1067 	#define DLOG_IF_F(verbosity_name, ...)
1068 	#define DVLOG_IF_F(verbosity, ...)
1069 	#define DRAW_LOG_F(verbosity_name, ...)
1070 	#define DRAW_VLOG_F(verbosity, ...)
1071 #endif
1072 
1073 #define CHECK_EQ_F(a, b, ...) CHECK_OP_F(a, b, ==, ##__VA_ARGS__)
1074 #define CHECK_NE_F(a, b, ...) CHECK_OP_F(a, b, !=, ##__VA_ARGS__)
1075 #define CHECK_LT_F(a, b, ...) CHECK_OP_F(a, b, < , ##__VA_ARGS__)
1076 #define CHECK_GT_F(a, b, ...) CHECK_OP_F(a, b, > , ##__VA_ARGS__)
1077 #define CHECK_LE_F(a, b, ...) CHECK_OP_F(a, b, <=, ##__VA_ARGS__)
1078 #define CHECK_GE_F(a, b, ...) CHECK_OP_F(a, b, >=, ##__VA_ARGS__)
1079 
1080 #ifndef LOGURU_DEBUG_CHECKS
1081 	#ifndef NDEBUG
1082 		#define LOGURU_DEBUG_CHECKS 1
1083 	#else
1084 		#define LOGURU_DEBUG_CHECKS 0
1085 	#endif
1086 #endif
1087 
1088 #if LOGURU_DEBUG_CHECKS
1089 	// Debug checks enabled:
1090 	#define DCHECK_F(test, ...)             CHECK_F(test, ##__VA_ARGS__)
1091 	#define DCHECK_NOTNULL_F(x, ...)        CHECK_NOTNULL_F(x, ##__VA_ARGS__)
1092 	#define DCHECK_EQ_F(a, b, ...)          CHECK_EQ_F(a, b, ##__VA_ARGS__)
1093 	#define DCHECK_NE_F(a, b, ...)          CHECK_NE_F(a, b, ##__VA_ARGS__)
1094 	#define DCHECK_LT_F(a, b, ...)          CHECK_LT_F(a, b, ##__VA_ARGS__)
1095 	#define DCHECK_LE_F(a, b, ...)          CHECK_LE_F(a, b, ##__VA_ARGS__)
1096 	#define DCHECK_GT_F(a, b, ...)          CHECK_GT_F(a, b, ##__VA_ARGS__)
1097 	#define DCHECK_GE_F(a, b, ...)          CHECK_GE_F(a, b, ##__VA_ARGS__)
1098 #else
1099 	// Debug checks disabled:
1100 	#define DCHECK_F(test, ...)
1101 	#define DCHECK_NOTNULL_F(x, ...)
1102 	#define DCHECK_EQ_F(a, b, ...)
1103 	#define DCHECK_NE_F(a, b, ...)
1104 	#define DCHECK_LT_F(a, b, ...)
1105 	#define DCHECK_LE_F(a, b, ...)
1106 	#define DCHECK_GT_F(a, b, ...)
1107 	#define DCHECK_GE_F(a, b, ...)
1108 #endif // NDEBUG
1109 
1110 
1111 #if LOGURU_REDEFINE_ASSERT
1112 	#undef assert
1113 	#ifndef NDEBUG
1114 		// Debug:
1115 		#define assert(test) CHECK_WITH_INFO_F(!!(test), #test) // HACK
1116 	#else
1117 		#define assert(test)
1118 	#endif
1119 #endif // LOGURU_REDEFINE_ASSERT
1120 
1121 #endif // LOGURU_HAS_DECLARED_FORMAT_HEADER
1122 
1123 // ----------------------------------------------------------------------------
1124 // .dP"Y8 888888 88""Yb 888888    db    8b    d8 .dP"Y8
1125 // `Ybo."   88   88__dP 88__     dPYb   88b  d88 `Ybo."
1126 // o.`Y8b   88   88"Yb  88""    dP__Yb  88YbdP88 o.`Y8b
1127 // 8bodP'   88   88  Yb 888888 dP""""Yb 88 YY 88 8bodP'
1128 
1129 #if LOGURU_WITH_STREAMS
1130 #ifndef LOGURU_HAS_DECLARED_STREAMS_HEADER
1131 #define LOGURU_HAS_DECLARED_STREAMS_HEADER
1132 
1133 /* This file extends loguru to enable std::stream-style logging, a la Glog.
1134    It's an optional feature behind the LOGURU_WITH_STREAMS settings
1135    because including it everywhere will slow down compilation times.
1136 */
1137 
1138 #include <cstdarg>
1139 #include <sstream> // Adds about 38 kLoC on clang.
1140 #include <string>
1141 
1142 namespace loguru
1143 {
1144 	// Like sprintf, but returns the formated text.
1145 	LOGURU_EXPORT
1146 	std::string strprintf(LOGURU_FORMAT_STRING_TYPE format, ...) LOGURU_PRINTF_LIKE(1, 2);
1147 
1148 	// Like vsprintf, but returns the formated text.
1149 	LOGURU_EXPORT
1150 	std::string vstrprintf(LOGURU_FORMAT_STRING_TYPE format, va_list) LOGURU_PRINTF_LIKE(1, 0);
1151 
1152 	class LOGURU_EXPORT StreamLogger
1153 	{
1154 	public:
StreamLogger(Verbosity verbosity,const char * file,unsigned line)1155 		StreamLogger(Verbosity verbosity, const char* file, unsigned line) : _verbosity(verbosity), _file(file), _line(line) {}
1156 		~StreamLogger() noexcept(false);
1157 
1158 		template<typename T>
operator <<(const T & t)1159 		StreamLogger& operator<<(const T& t)
1160 		{
1161 			_ss << t;
1162 			return *this;
1163 		}
1164 
1165 		// std::endl and other iomanip:s.
operator <<(std::ostream & (* f)(std::ostream &))1166 		StreamLogger& operator<<(std::ostream&(*f)(std::ostream&))
1167 		{
1168 			f(_ss);
1169 			return *this;
1170 		}
1171 
1172 	private:
1173 		Verbosity   _verbosity;
1174 		const char* _file;
1175 		unsigned    _line;
1176 		std::ostringstream _ss;
1177 	};
1178 
1179 	class LOGURU_EXPORT AbortLogger
1180 	{
1181 	public:
AbortLogger(const char * expr,const char * file,unsigned line)1182 		AbortLogger(const char* expr, const char* file, unsigned line) : _expr(expr), _file(file), _line(line) { }
1183 		LOGURU_NORETURN ~AbortLogger() noexcept(false);
1184 
1185 		template<typename T>
operator <<(const T & t)1186 		AbortLogger& operator<<(const T& t)
1187 		{
1188 			_ss << t;
1189 			return *this;
1190 		}
1191 
1192 		// std::endl and other iomanip:s.
operator <<(std::ostream & (* f)(std::ostream &))1193 		AbortLogger& operator<<(std::ostream&(*f)(std::ostream&))
1194 		{
1195 			f(_ss);
1196 			return *this;
1197 		}
1198 
1199 	private:
1200 		const char*        _expr;
1201 		const char*        _file;
1202 		unsigned           _line;
1203 		std::ostringstream _ss;
1204 	};
1205 
1206 	class LOGURU_EXPORT Voidify
1207 	{
1208 	public:
Voidify()1209 		Voidify() {}
1210 		// This has to be an operator with a precedence lower than << but higher than ?:
operator &(const StreamLogger &)1211 		void operator&(const StreamLogger&) { }
operator &(const AbortLogger &)1212 		void operator&(const AbortLogger&)  { }
1213 	};
1214 
1215 	/*  Helper functions for CHECK_OP_S macro.
1216 		GLOG trick: The (int, int) specialization works around the issue that the compiler
1217 		will not instantiate the template version of the function on values of unnamed enum type. */
1218 	#define DEFINE_CHECK_OP_IMPL(name, op)                                                             \
1219 		template <typename T1, typename T2>                                                            \
1220 		inline std::string* name(const char* expr, const T1& v1, const char* op_str, const T2& v2)     \
1221 		{                                                                                              \
1222 			if (LOGURU_PREDICT_TRUE(v1 op v2)) { return NULL; }                                        \
1223 			std::ostringstream ss;                                                                     \
1224 			ss << "CHECK FAILED:  " << expr << "  (" << v1 << " " << op_str << " " << v2 << ")  ";     \
1225 			return new std::string(ss.str());                                                          \
1226 		}                                                                                              \
1227 		inline std::string* name(const char* expr, int v1, const char* op_str, int v2)                 \
1228 		{                                                                                              \
1229 			return name<int, int>(expr, v1, op_str, v2);                                               \
1230 		}
1231 
1232 	DEFINE_CHECK_OP_IMPL(check_EQ_impl, ==)
1233 	DEFINE_CHECK_OP_IMPL(check_NE_impl, !=)
1234 	DEFINE_CHECK_OP_IMPL(check_LE_impl, <=)
1235 	DEFINE_CHECK_OP_IMPL(check_LT_impl, < )
1236 	DEFINE_CHECK_OP_IMPL(check_GE_impl, >=)
1237 	DEFINE_CHECK_OP_IMPL(check_GT_impl, > )
1238 	#undef DEFINE_CHECK_OP_IMPL
1239 
1240 	/*  GLOG trick: Function is overloaded for integral types to allow static const integrals
1241 		declared in classes and not defined to be used as arguments to CHECK* macros. */
1242 	template <class T>
referenceable_value(const T & t)1243 	inline const T&           referenceable_value(const T&           t) { return t; }
referenceable_value(char t)1244 	inline char               referenceable_value(char               t) { return t; }
referenceable_value(unsigned char t)1245 	inline unsigned char      referenceable_value(unsigned char      t) { return t; }
referenceable_value(signed char t)1246 	inline signed char        referenceable_value(signed char        t) { return t; }
referenceable_value(short t)1247 	inline short              referenceable_value(short              t) { return t; }
referenceable_value(unsigned short t)1248 	inline unsigned short     referenceable_value(unsigned short     t) { return t; }
referenceable_value(int t)1249 	inline int                referenceable_value(int                t) { return t; }
referenceable_value(unsigned int t)1250 	inline unsigned int       referenceable_value(unsigned int       t) { return t; }
referenceable_value(long t)1251 	inline long               referenceable_value(long               t) { return t; }
referenceable_value(unsigned long t)1252 	inline unsigned long      referenceable_value(unsigned long      t) { return t; }
referenceable_value(long long t)1253 	inline long long          referenceable_value(long long          t) { return t; }
referenceable_value(unsigned long long t)1254 	inline unsigned long long referenceable_value(unsigned long long t) { return t; }
1255 } // namespace loguru
1256 
1257 // -----------------------------------------------
1258 // Logging macros:
1259 
1260 // usage:  LOG_STREAM(INFO) << "Foo " << std::setprecision(10) << some_value;
1261 #define VLOG_IF_S(verbosity, cond)                                                                 \
1262 	((verbosity) > loguru::current_verbosity_cutoff() || (cond) == false)                          \
1263 		? (void)0                                                                                  \
1264 		: loguru::Voidify() & loguru::StreamLogger(verbosity, __FILE__, __LINE__)
1265 #define LOG_IF_S(verbosity_name, cond) VLOG_IF_S(loguru::Verbosity_ ## verbosity_name, cond)
1266 #define VLOG_S(verbosity)              VLOG_IF_S(verbosity, true)
1267 #define LOG_S(verbosity_name)          VLOG_S(loguru::Verbosity_ ## verbosity_name)
1268 
1269 // -----------------------------------------------
1270 // ABORT_S macro. Usage:  ABORT_S() << "Causo of error: " << details;
1271 
1272 #define ABORT_S() loguru::Voidify() & loguru::AbortLogger("ABORT: ", __FILE__, __LINE__)
1273 
1274 // -----------------------------------------------
1275 // CHECK_S macros:
1276 
1277 #define CHECK_WITH_INFO_S(cond, info)                                                              \
1278 	LOGURU_PREDICT_TRUE((cond) == true)                                                            \
1279 		? (void)0                                                                                  \
1280 		: loguru::Voidify() & loguru::AbortLogger("CHECK FAILED:  " info "  ", __FILE__, __LINE__)
1281 
1282 #define CHECK_S(cond) CHECK_WITH_INFO_S(cond, #cond)
1283 #define CHECK_NOTNULL_S(x) CHECK_WITH_INFO_S((x) != nullptr, #x " != nullptr")
1284 
1285 #define CHECK_OP_S(function_name, expr1, op, expr2)                                                \
1286 	while (auto error_string = loguru::function_name(#expr1 " " #op " " #expr2,                    \
1287 													 loguru::referenceable_value(expr1), #op,      \
1288 													 loguru::referenceable_value(expr2)))          \
1289 		loguru::AbortLogger(error_string->c_str(), __FILE__, __LINE__)
1290 
1291 #define CHECK_EQ_S(expr1, expr2) CHECK_OP_S(check_EQ_impl, expr1, ==, expr2)
1292 #define CHECK_NE_S(expr1, expr2) CHECK_OP_S(check_NE_impl, expr1, !=, expr2)
1293 #define CHECK_LE_S(expr1, expr2) CHECK_OP_S(check_LE_impl, expr1, <=, expr2)
1294 #define CHECK_LT_S(expr1, expr2) CHECK_OP_S(check_LT_impl, expr1, < , expr2)
1295 #define CHECK_GE_S(expr1, expr2) CHECK_OP_S(check_GE_impl, expr1, >=, expr2)
1296 #define CHECK_GT_S(expr1, expr2) CHECK_OP_S(check_GT_impl, expr1, > , expr2)
1297 
1298 #if LOGURU_DEBUG_LOGGING
1299 	// Debug logging enabled:
1300 	#define DVLOG_IF_S(verbosity, cond)     VLOG_IF_S(verbosity, cond)
1301 	#define DLOG_IF_S(verbosity_name, cond) LOG_IF_S(verbosity_name, cond)
1302 	#define DVLOG_S(verbosity)              VLOG_S(verbosity)
1303 	#define DLOG_S(verbosity_name)          LOG_S(verbosity_name)
1304 #else
1305 	// Debug logging disabled:
1306 	#define DVLOG_IF_S(verbosity, cond)                                                     \
1307 		(true || (verbosity) > loguru::current_verbosity_cutoff() || (cond) == false)       \
1308 			? (void)0                                                                       \
1309 			: loguru::Voidify() & loguru::StreamLogger(verbosity, __FILE__, __LINE__)
1310 
1311 	#define DLOG_IF_S(verbosity_name, cond) DVLOG_IF_S(loguru::Verbosity_ ## verbosity_name, cond)
1312 	#define DVLOG_S(verbosity)              DVLOG_IF_S(verbosity, true)
1313 	#define DLOG_S(verbosity_name)          DVLOG_S(loguru::Verbosity_ ## verbosity_name)
1314 #endif
1315 
1316 #if LOGURU_DEBUG_CHECKS
1317 	// Debug checks enabled:
1318 	#define DCHECK_S(cond)                  CHECK_S(cond)
1319 	#define DCHECK_NOTNULL_S(x)             CHECK_NOTNULL_S(x)
1320 	#define DCHECK_EQ_S(a, b)               CHECK_EQ_S(a, b)
1321 	#define DCHECK_NE_S(a, b)               CHECK_NE_S(a, b)
1322 	#define DCHECK_LT_S(a, b)               CHECK_LT_S(a, b)
1323 	#define DCHECK_LE_S(a, b)               CHECK_LE_S(a, b)
1324 	#define DCHECK_GT_S(a, b)               CHECK_GT_S(a, b)
1325 	#define DCHECK_GE_S(a, b)               CHECK_GE_S(a, b)
1326 #else
1327 // Debug checks disabled:
1328 	#define DCHECK_S(cond)                  CHECK_S(true || (cond))
1329 	#define DCHECK_NOTNULL_S(x)             CHECK_S(true || (x) != nullptr)
1330 	#define DCHECK_EQ_S(a, b)               CHECK_S(true || (a) == (b))
1331 	#define DCHECK_NE_S(a, b)               CHECK_S(true || (a) != (b))
1332 	#define DCHECK_LT_S(a, b)               CHECK_S(true || (a) <  (b))
1333 	#define DCHECK_LE_S(a, b)               CHECK_S(true || (a) <= (b))
1334 	#define DCHECK_GT_S(a, b)               CHECK_S(true || (a) >  (b))
1335 	#define DCHECK_GE_S(a, b)               CHECK_S(true || (a) >= (b))
1336 #endif
1337 
1338 #if LOGURU_REPLACE_GLOG
1339 	#undef LOG
1340 	#undef VLOG
1341 	#undef LOG_IF
1342 	#undef VLOG_IF
1343 	#undef CHECK
1344 	#undef CHECK_NOTNULL
1345 	#undef CHECK_EQ
1346 	#undef CHECK_NE
1347 	#undef CHECK_LT
1348 	#undef CHECK_LE
1349 	#undef CHECK_GT
1350 	#undef CHECK_GE
1351 	#undef DLOG
1352 	#undef DVLOG
1353 	#undef DLOG_IF
1354 	#undef DVLOG_IF
1355 	#undef DCHECK
1356 	#undef DCHECK_NOTNULL
1357 	#undef DCHECK_EQ
1358 	#undef DCHECK_NE
1359 	#undef DCHECK_LT
1360 	#undef DCHECK_LE
1361 	#undef DCHECK_GT
1362 	#undef DCHECK_GE
1363 	#undef VLOG_IS_ON
1364 
1365 	#define LOG            LOG_S
1366 	#define VLOG           VLOG_S
1367 	#define LOG_IF         LOG_IF_S
1368 	#define VLOG_IF        VLOG_IF_S
1369 	#define CHECK(cond)    CHECK_S(!!(cond))
1370 	#define CHECK_NOTNULL  CHECK_NOTNULL_S
1371 	#define CHECK_EQ       CHECK_EQ_S
1372 	#define CHECK_NE       CHECK_NE_S
1373 	#define CHECK_LT       CHECK_LT_S
1374 	#define CHECK_LE       CHECK_LE_S
1375 	#define CHECK_GT       CHECK_GT_S
1376 	#define CHECK_GE       CHECK_GE_S
1377 	#define DLOG           DLOG_S
1378 	#define DVLOG          DVLOG_S
1379 	#define DLOG_IF        DLOG_IF_S
1380 	#define DVLOG_IF       DVLOG_IF_S
1381 	#define DCHECK         DCHECK_S
1382 	#define DCHECK_NOTNULL DCHECK_NOTNULL_S
1383 	#define DCHECK_EQ      DCHECK_EQ_S
1384 	#define DCHECK_NE      DCHECK_NE_S
1385 	#define DCHECK_LT      DCHECK_LT_S
1386 	#define DCHECK_LE      DCHECK_LE_S
1387 	#define DCHECK_GT      DCHECK_GT_S
1388 	#define DCHECK_GE      DCHECK_GE_S
1389 	#define VLOG_IS_ON(verbosity) ((verbosity) <= loguru::current_verbosity_cutoff())
1390 
1391 #endif // LOGURU_REPLACE_GLOG
1392 
1393 #endif // LOGURU_WITH_STREAMS
1394 
1395 #endif // LOGURU_HAS_DECLARED_STREAMS_HEADER
1396