Skip to content

Instantly share code, notes, and snippets.

@mrdomino mrdomino/log_if.h
Last active Dec 19, 2015

Embed
What would you like to do?
#include <cstdlib>
#include <exception>
#include <iostream>
#include <sstream>
#include <utility>
#define LOG_IF(TEST, LEVEL) \
if (!(TEST)) { \
} else if (_::minLevel > (LEVEL)) { \
if ((LEVEL) == FATAL) abort(); \
} else ::_::Log(LEVEL)
// XX cheez
#define FATAL 5
namespace _ {
int minLevel = 0;
template <typename F>
class FixExceptions {
public:
inline FixExceptions(F&& f) {
if (std::uncaught_exception()) {
try {
std::forward<F>(f)();
} catch (...) {}
} else std::forward<F>(f)();
}
};
template <typename F>
void fixExceptions(F&& f) {
// ancillary detail. C++ multi-exception terminate is dumb.
_::FixExceptions<F>(std::forward<F>(f));
}
class DtorAbortIf {
// Kill the process when this goes out of scope
public:
inline DtorAbortIf(const bool aborting): aborting(aborting) {}
inline ~DtorAbortIf() {
if (aborting) abort();
}
private:
const bool aborting;
};
class Log {
public:
inline Log(const int level): fatal(level == FATAL) {}
inline ~Log() noexcept(false) {
fixExceptions([&] {
DtorAbortIf x(fatal);
std::cerr << ss.str() << std::endl;
});
}
template <typename T>
inline Log& operator<<(T&& t) {
ss << std::forward<T>(t);
return *this;
}
private:
std::ostringstream ss;
const bool fatal;
};
} // namespace _
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.