#include <string>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <mutex>
#include <ctime>
enum class lvl {
MAX,
FATAL,
IMPORTANT,
ERROR,
WARNING,
MESSAGE,
SPAM,
MIN
};
class log {
public:
log(lvl level = lvl::MESSAGE) {
this->level = level;
}
/*
* destroys the logline object. this destructor will output the
* logline's accumulated content, in a thread-safe way.
*/
~log() {
//thread-safety etc
std::unique_lock<mutex> lock(globalmutex);
//in this simplified class, we just output the whole line to
//stdout, but in the real version there is a log of
//manipulation of global data structures happening right here.
if(level < lvl::WARNING) {
cout << '[' << time(NULL) << "] ";
cout << sstr.str() << endl;
}
}
//for writing normal types
template<typename T>
log &operator<<(T x) {
sstr << x;
return *this;
}
//for writing function pointers, such as endl or setw(5).
template<typename T>
log &operator<<(T &(*x)(T &)) {
sstr << x;
return *this;
}
private:
//this particular log line's level.
lvl level;
//accumulates all input.
std::stringstream sstr;
//to ensure thread-safety
static std::mutex globalmutex;
};
int main() {
log(lvl::SPAM) << "main method initialized";
log(lvl::MESSAGE) << "the time is: " << time(NULL);
log(lvl::SPAM) << "main method de-initializing";
}