#ifndef LOG_HPP #define LOG_HPP // could not be hackier, but C++ is annoying #define protected public #include #undef protected #include #include #include namespace log { struct LoggerBuffer : public std::streambuf { LoggerBuffer(std::streambuf* buffer, const std::string& name) : _buffer(buffer), _prefix(name + ": "), _prefix_next(true) { } int_type overflow(int_type c=EOF) { if (_prefix_next) { _buffer->sputn(_prefix.c_str(), _prefix.length()); _prefix_next = false; } if (c == '\n') { _prefix_next = true; } return _buffer->overflow(c); } private: std::streambuf* _buffer; std::string _prefix; bool _prefix_next; }; struct Logger : public std::ostream { Logger(std::streambuf* buffer, const std::string& name) : std::ostream(NULL), _buffer(buffer, name) { } bool enabled() const { return rdbuf() != NULL; } bool enabled(bool v) { bool ret = enabled(); rdbuf(v ? &_buffer : NULL); return ret; } private: LoggerBuffer _buffer; }; Logger info(std::cout.rdbuf(), "info"); Logger trace(std::cerr.rdbuf(), "trace"); Logger strategy(std::cerr.rdbuf(), "strategy"); Logger fixpoint(std::cerr.rdbuf(), "fixpoint"); Logger debug(std::cerr.rdbuf(), "debug"); } #endif