#include <iostream>
#include <set>
#include <algorithm>
template<typename CharT = char,
typename CharTraits = std::char_traits<CharT> >
class Logger : public std::basic_ostream<CharT, CharTraits>,
private std::basic_streambuf<CharT, CharTraits>
{
typedef std::basic_streambuf<CharT, CharTraits> streambuf_type;
typedef std::basic_ostream<CharT, CharTraits> ostream_type;
std::set<streambuf_type*> mStreambufs;
public:
typedef CharT char_type;
typedef CharTraits traits_type;
typedef typename std::set<streambuf_type*>::iterator iterator;
typedef typename std::set<streambuf_type*>::const_iterator const_iterator;
Logger():
ostream_type{this} {}
iterator begin() { return mStreambufs.begin(); }
iterator end() { return mStreambufs.end(); }
const_iterator begin() const { return mStreambufs.cbegin(); }
const_iterator end() const { return mStreambufs.cend(); }
std::pair<iterator, bool> add( streambuf_type* ptr ) { return mStreambufs.insert(ptr); }
std::pair<iterator, bool> add( ostream_type& ptr ) { return add(ptr.rdbuf()); }
void erase( iterator i ) { mStreambufs.erase(i); }
protected:
virtual typename traits_type::int_type overflow( typename traits_type::int_type c = traits_type::eof() ) override
{
typename traits_type::int_type rval = traits_type::not_eof(c);
if( !traits_type::eq_int_type( rval, c ) ) /// EOF - no characters to be written. Return success.
return rval;
for( auto ptr : *this )
if( traits_type::eq_int_type( ptr->sputc( traits_type::to_char_type(c) ), traits_type::eof() ) )
rval = traits_type::eof(); // if one streambuf returns a value indicating failure, all other streambufs are done and EOF is returned.
return rval;
}
};
#include <fstream>
int main()
{
Logger<> logger;
logger.add( std::cout );
logger << "Hallo Welt!\nWie gehts?" << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c2V0PgojaW5jbHVkZSA8YWxnb3JpdGhtPgoKdGVtcGxhdGU8dHlwZW5hbWUgQ2hhclQgPSBjaGFyLAogICAgICAgICB0eXBlbmFtZSBDaGFyVHJhaXRzID0gc3RkOjpjaGFyX3RyYWl0czxDaGFyVD4gPgpjbGFzcyBMb2dnZXIgOiBwdWJsaWMgc3RkOjpiYXNpY19vc3RyZWFtPENoYXJULCBDaGFyVHJhaXRzPiwKICAgICAgICAgICAgICAgcHJpdmF0ZSBzdGQ6OmJhc2ljX3N0cmVhbWJ1ZjxDaGFyVCwgQ2hhclRyYWl0cz4KewogICAgdHlwZWRlZiBzdGQ6OmJhc2ljX3N0cmVhbWJ1ZjxDaGFyVCwgQ2hhclRyYWl0cz4gc3RyZWFtYnVmX3R5cGU7CiAgICB0eXBlZGVmIHN0ZDo6YmFzaWNfb3N0cmVhbTxDaGFyVCwgQ2hhclRyYWl0cz4gb3N0cmVhbV90eXBlOwoKICAgIHN0ZDo6c2V0PHN0cmVhbWJ1Zl90eXBlKj4gbVN0cmVhbWJ1ZnM7CgpwdWJsaWM6CgogICAgdHlwZWRlZiBDaGFyVCBjaGFyX3R5cGU7CiAgICB0eXBlZGVmIENoYXJUcmFpdHMgdHJhaXRzX3R5cGU7CgogICAgdHlwZWRlZiB0eXBlbmFtZSBzdGQ6OnNldDxzdHJlYW1idWZfdHlwZSo+OjppdGVyYXRvciBpdGVyYXRvcjsKICAgIHR5cGVkZWYgdHlwZW5hbWUgc3RkOjpzZXQ8c3RyZWFtYnVmX3R5cGUqPjo6Y29uc3RfaXRlcmF0b3IgY29uc3RfaXRlcmF0b3I7CgogICAgTG9nZ2VyKCk6CiAgICAgICAgb3N0cmVhbV90eXBle3RoaXN9IHt9CgogICAgaXRlcmF0b3IgYmVnaW4oKSB7IHJldHVybiBtU3RyZWFtYnVmcy5iZWdpbigpOyB9CiAgICBpdGVyYXRvciBlbmQoKSB7IHJldHVybiBtU3RyZWFtYnVmcy5lbmQoKTsgfQogICAgY29uc3RfaXRlcmF0b3IgYmVnaW4oKSBjb25zdCB7IHJldHVybiBtU3RyZWFtYnVmcy5jYmVnaW4oKTsgfQogICAgY29uc3RfaXRlcmF0b3IgZW5kKCkgY29uc3QgeyByZXR1cm4gbVN0cmVhbWJ1ZnMuY2VuZCgpOyB9CgogICAgc3RkOjpwYWlyPGl0ZXJhdG9yLCBib29sPiBhZGQoIHN0cmVhbWJ1Zl90eXBlKiBwdHIgKSB7IHJldHVybiBtU3RyZWFtYnVmcy5pbnNlcnQocHRyKTsgfQogICAgc3RkOjpwYWlyPGl0ZXJhdG9yLCBib29sPiBhZGQoIG9zdHJlYW1fdHlwZSYgcHRyICkgeyByZXR1cm4gYWRkKHB0ci5yZGJ1ZigpKTsgfQoKICAgIHZvaWQgZXJhc2UoIGl0ZXJhdG9yIGkgKSB7ICBtU3RyZWFtYnVmcy5lcmFzZShpKTsgfQoKcHJvdGVjdGVkOgoKICAgIHZpcnR1YWwgdHlwZW5hbWUgdHJhaXRzX3R5cGU6OmludF90eXBlIG92ZXJmbG93KCB0eXBlbmFtZSB0cmFpdHNfdHlwZTo6aW50X3R5cGUgYyA9IHRyYWl0c190eXBlOjplb2YoKSApIG92ZXJyaWRlCiAgICB7CiAgICAgICAgdHlwZW5hbWUgdHJhaXRzX3R5cGU6OmludF90eXBlIHJ2YWwgPSB0cmFpdHNfdHlwZTo6bm90X2VvZihjKTsKCiAgICAgICAgaWYoICF0cmFpdHNfdHlwZTo6ZXFfaW50X3R5cGUoIHJ2YWwsIGMgKSApIC8vLyBFT0YgLSBubyBjaGFyYWN0ZXJzIHRvIGJlIHdyaXR0ZW4uIFJldHVybiBzdWNjZXNzLgogICAgICAgICAgICByZXR1cm4gcnZhbDsKCiAgICAgICAgZm9yKCBhdXRvIHB0ciA6ICp0aGlzICkKICAgICAgICAgICAgaWYoIHRyYWl0c190eXBlOjplcV9pbnRfdHlwZSggcHRyLT5zcHV0YyggdHJhaXRzX3R5cGU6OnRvX2NoYXJfdHlwZShjKSApLCB0cmFpdHNfdHlwZTo6ZW9mKCkgKSApCiAgICAgICAgICAgICAgICBydmFsID0gdHJhaXRzX3R5cGU6OmVvZigpOyAvLyBpZiBvbmUgc3RyZWFtYnVmIHJldHVybnMgYSB2YWx1ZSBpbmRpY2F0aW5nIGZhaWx1cmUsIGFsbCBvdGhlciBzdHJlYW1idWZzIGFyZSBkb25lIGFuZCBFT0YgaXMgcmV0dXJuZWQuCgogICAgICAgIHJldHVybiBydmFsOwogICAgfQp9OwoKI2luY2x1ZGUgPGZzdHJlYW0+CgppbnQgbWFpbigpCnsKICAgIExvZ2dlcjw+IGxvZ2dlcjsKICAgIGxvZ2dlci5hZGQoIHN0ZDo6Y291dCApOwoKICAgIGxvZ2dlciA8PCAiSGFsbG8gV2VsdCFcbldpZSBnZWh0cz8iIDw8IHN0ZDo6ZW5kbDsKfQ==