Rewrote threaded log code to be more idiomatic.
[invirt/third/libt4.git] / threaded_log.h
1 #ifndef threaded_log_h
2 #define threaded_log_h
3
4 #include "types.h"
5
6 extern mutex cerr_mutex;
7 extern map<thread::id, int> thread_name_map;
8 extern int next_thread_num;
9 extern map<const void *, int> instance_name_map;
10 extern int next_instance_num;
11 extern char log_thread_prefix;
12
13 struct locked_ostream {
14     ostream & s;
15     lock l;
16     ~locked_ostream() { s << endl; }
17     template <typename U>
18     locked_ostream & operator<<(U && u) { s << u; return *this; }
19
20     typedef std::ostream& (*ostream_manipulator)(ostream&);
21     locked_ostream & operator<<(ostream_manipulator manip) { s << manip; return *this; }
22 };
23
24 locked_ostream && _log_prefix(locked_ostream && f, const string & file, const string & func);
25 locked_ostream && _log_member(locked_ostream && f, const void *ptr);
26 #define _log_nonmember(f, ptr) f
27
28 #define _LOG(_context_) _context_(_log_prefix(locked_ostream{cerr, lock(cerr_mutex)}, __FILE__, __func__), (const void *)this)
29
30 #define LOG_NONMEMBER _LOG(_log_nonmember)
31 #define LOG           _LOG(_log_member)
32
33 extern int DEBUG_LEVEL;
34
35 #define IF_LEVEL(level) if(DEBUG_LEVEL >= abs(level))
36
37 #endif