Instantly share code, notes, and snippets.

Embed
What would you like to do?
#ifndef LOGGER_HPP
#define LOGGER_HPP
#include <iostream>
#include <sstream>
#include <boost/none_t.hpp>
enum log_level {
error = 1,
warn = 2,
debug = 3,
info = 4,
trace = 5
};
inline std::ostream& operator<<(std::ostream& p_ostream, const log_level& log) {
switch (log) {
case error: p_ostream << "error"; break;
case warn: p_ostream << "warn"; break;
case debug: p_ostream << "debug"; break;
case info: p_ostream << "info"; break;
case trace: p_ostream << "trace"; break;
default: p_ostream << "unknown"; break;
}
return p_ostream;
}
namespace logger {
template<typename log_type, typename log_level, log_level log, unsigned level>
class logger_impl
{
public:
logger_impl(const std::string& file, unsigned line, const std::string& function) {
if (log <= level) {
//compatible with gcc output
stream_ << file << ":" << line << ":0: " << log << ": " << function << ": ";
}
}
~logger_impl() {
if (log <= level) {
log_type::log(stream_.str());
}
}
std::ostream& get_stream() {
return stream_;
}
private:
std::ostringstream stream_;
};
template<typename, typename log_level, log_level, unsigned>
class logger_null_stream_impl
{
template<typename T>
class null_buffer: public std::basic_streambuf<T> {
std::streambuf::int_type overflow(std::streambuf::int_type) {
return 0;
}
};
public:
logger_null_stream_impl(const std::string&, unsigned, const std::string&)
: null_log_(&null_buffer_)
{ }
std::ostream& get_stream() {
return null_log_;
}
private:
null_buffer<char> null_buffer_;
std::ostream null_log_;
};
class clog
{
public:
static void log(const std::string& log) {
std::clog << log << std::endl;
}
};
} // namespace logger
#ifndef LOG_LEVEL
# define LOG_LEVEL 3 //error, warn, debug
#endif
#ifndef LOG_TYPE
# define LOG_TYPE ::logger::clog
#endif
#define LOG_INVOKER(logger_impl, log_type, log_level_type, given_level, show_level)\
logger_impl<log_type, log_level_type, given_level, show_level>(__FILE__, __LINE__, __FUNCTION__).get_stream()
#ifdef NDEBUG
# define LOG(given_level)\
LOG_INVOKER(::logger::logger_null_stream_impl, ::boost::none_t, ::log_level, given_level, LOG_LEVEL)
#else
# define LOG(given_level)\
LOG_INVOKER(::logger::logger_impl, LOG_TYPE, ::log_level, given_level, LOG_LEVEL)
#endif
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment