As Thoreau said: "Simplify, simplify, simplify..."
The trouble with writing something in an hour or two that works is that you then have find your subconscious mind is chewing it over all the time that you're working on something else.
So it is whilst working on message_queue I couldn't resist fiddling with the logging services:
- the io namespace is gone
- serializor_policy is gone
- only the null_serializor remains renamed null_log
- ready for asycn_log
- logger now takes an output stream policy and is, consequently, more flexible
- works directly with any ostream decendent
- logger template overloads operator()
- logger doesn't need a stringstream any longer
- I've left the stamps alone, for now...
So now the logger is easier to use and more flexible:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
log::logger<std::ostream> clog(std::cout, { new log::line_number_stamp(), | |
new log::line_number_stamp(10), | |
new log::unix_time_stamp()}); | |
std::ofstream file("test.log"); | |
log::logger<std::ofstream> flog(file, { new log::line_number_stamp(), | |
new log::line_number_stamp(10), | |
new log::unix_time_stamp()}); | |
log::null_log black_hole; | |
log::logger<log::null_log> nlog(black_hole); | |
for (int i = 0; i < 10; ++i) { | |
clog("hello ", "world ", 1,1,1); | |
flog("hello ", "file " "world ", 1,2,3); | |
nlog("hello ", "null " "world ", 1,2,3); | |
} |
It is a smaller, more coherent and more pleasing piece of code:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace log { | |
template<typename T> | |
class logger { | |
using initializer_list = std::initializer_list<stamp_policy*>; | |
public: | |
logger(T& _stream): stream(_stream) {} | |
logger(T& _stream, initializer_list _stamps): | |
stream(_stream), | |
stamps(_stamps) {} | |
template<typename...Args> | |
void operator() (Args...args) { | |
for(auto stamp: stamps) | |
stream << stamp->str(); | |
do_write(args...); | |
} | |
virtual ~logger() { | |
for (auto stamp: stamps) | |
delete(stamp); | |
} | |
private: | |
void do_write() { | |
stream << "\n"; | |
} | |
template<typename First, typename...Next> | |
void do_write(First first, Next...next) { | |
stream << first; | |
do_write(next...); | |
} | |
initializer_list stamps; | |
T& stream; | |
}; | |
} |
Subsequent log streams will be much more easily implemented as can be seen from null_log:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace log { | |
struct null_log { | |
template<typename T> | |
const null_log& operator << (const T& t) const { | |
return *this; | |
} | |
}; | |
} |
No comments:
Post a Comment