#include <iostream>
#include <mutex>
#include <memory>
#include <thread>
namespace test
{
struct GuardStream
{
GuardStream() = delete;
GuardStream(const GuardStream&) = delete;
void operator=(const GuardStream&) = delete;
GuardStream(std::ostream& ostream, std::recursive_mutex& mutex)
: m_stream(ostream),
m_gmtx(mutex)
{
}
~GuardStream()
{
m_stream.flush();
}
template<typename T>
void write(const T& x)
{
m_stream << x;
}
std::ostream& m_stream;
std::lock_guard<std::recursive_mutex> m_gmtx;
};
class Logger;
struct WrappedStream
{
WrappedStream() = delete;
void operator=(const WrappedStream&) = delete;
WrappedStream(std::ostream& ostream, std::recursive_mutex& mutex, Logger& log)
: m_gstream( std::make_unique<GuardStream>(ostream, mutex)), logger(log)
{
}
WrappedStream(const WrappedStream& rhs): logger(rhs.logger)
{
m_gstream.swap(rhs.m_gstream);
}
template<typename T>
WrappedStream& operator<<(const T& x)
{
m_gstream->write(x);
return *this;
}
WrappedStream operator<< (WrappedStream pFn(Logger&))
{
return pFn(logger);
}
mutable std::unique_ptr<GuardStream> m_gstream;
Logger& logger;
};
struct Logger
{
explicit Logger(std::ostream& ostream) : ostream_(ostream)
{
}
WrappedStream flush()
{
return WrappedStream(ostream_, mutex_, *this) << "flush";
}
template<typename T>
WrappedStream operator<<(const T& x)
{
return WrappedStream(ostream_, mutex_, *this) << x;
}
std::ostream& ostream_;
std::recursive_mutex mutex_;
};
namespace io
{
inline WrappedStream endl(Logger& rhs)
{
return rhs.flush();
}
}
Logger wrap_cout(std::cout);
}
int main()
{
test::wrap_cout << "Thread [" << std::this_thread::get_id() << "] put message: elapsed time: " << 1 << test::io::endl;
test::wrap_cout << test::io::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bXV0ZXg+CiNpbmNsdWRlIDxtZW1vcnk+CiNpbmNsdWRlIDx0aHJlYWQ+CgpuYW1lc3BhY2UgdGVzdAp7CiAKICAgIHN0cnVjdCBHdWFyZFN0cmVhbQogICAgewogICAgICAgIEd1YXJkU3RyZWFtKCkgPSBkZWxldGU7CiAgICAgICAgR3VhcmRTdHJlYW0oY29uc3QgR3VhcmRTdHJlYW0mKSA9IGRlbGV0ZTsKICAgICAgICB2b2lkIG9wZXJhdG9yPShjb25zdCBHdWFyZFN0cmVhbSYpID0gZGVsZXRlOwogCiAgICAgICAgR3VhcmRTdHJlYW0oc3RkOjpvc3RyZWFtJiBvc3RyZWFtLCBzdGQ6OnJlY3Vyc2l2ZV9tdXRleCYgbXV0ZXgpCiAgICAgICAgOiBtX3N0cmVhbShvc3RyZWFtKSwKICAgICAgICAgIG1fZ210eChtdXRleCkKICAgICAgICB7CiAgICAgICAgfQogCiAgICAgICAgfkd1YXJkU3RyZWFtKCkKICAgICAgICB7CiAgICAgICAgICAgIG1fc3RyZWFtLmZsdXNoKCk7CiAgICAgICAgfQogCiAgICAgICAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KICAgICAgICB2b2lkIHdyaXRlKGNvbnN0IFQmIHgpCiAgICAgICAgewogICAgICAgICAgICBtX3N0cmVhbSA8PCB4OwogICAgICAgIH0KICAgICAgICBzdGQ6Om9zdHJlYW0mIG1fc3RyZWFtOwogICAgICAgIHN0ZDo6bG9ja19ndWFyZDxzdGQ6OnJlY3Vyc2l2ZV9tdXRleD4gbV9nbXR4OwogICAgfTsKIAogICAgY2xhc3MgTG9nZ2VyOwogICAgCiAgICBzdHJ1Y3QgV3JhcHBlZFN0cmVhbQogICAgewogICAgICAgIFdyYXBwZWRTdHJlYW0oKSA9IGRlbGV0ZTsKICAgICAgICB2b2lkIG9wZXJhdG9yPShjb25zdCBXcmFwcGVkU3RyZWFtJikgPSBkZWxldGU7CiAgICAgICAgCgkJV3JhcHBlZFN0cmVhbShzdGQ6Om9zdHJlYW0mIG9zdHJlYW0sIHN0ZDo6cmVjdXJzaXZlX211dGV4JiBtdXRleCwgTG9nZ2VyJiBsb2cpCiAgICAgICAgCTogbV9nc3RyZWFtKCBzdGQ6Om1ha2VfdW5pcXVlPEd1YXJkU3RyZWFtPihvc3RyZWFtLCBtdXRleCkpLCBsb2dnZXIobG9nKQogICAgICAgIHsKICAgICAgICB9CiAKICAgICAgICBXcmFwcGVkU3RyZWFtKGNvbnN0IFdyYXBwZWRTdHJlYW0mIHJocyk6IGxvZ2dlcihyaHMubG9nZ2VyKQogICAgICAgIHsKICAgICAgICAgICAgbV9nc3RyZWFtLnN3YXAocmhzLm1fZ3N0cmVhbSk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CiAgICAgICAgV3JhcHBlZFN0cmVhbSYgb3BlcmF0b3I8PChjb25zdCBUJiB4KQogICAgICAgIHsKICAgICAgICAgICAgbV9nc3RyZWFtLT53cml0ZSh4KTsKICAgICAgICAgICAgcmV0dXJuICp0aGlzOwogICAgICAgIH0KICAgICAgICBXcmFwcGVkU3RyZWFtIG9wZXJhdG9yPDwgKFdyYXBwZWRTdHJlYW0gcEZuKExvZ2dlciYpKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHBGbihsb2dnZXIpOwogICAgICAgIH0KIAogICAgICAgIG11dGFibGUgc3RkOjp1bmlxdWVfcHRyPEd1YXJkU3RyZWFtPiBtX2dzdHJlYW07CiAgICAgICAgTG9nZ2VyJiBsb2dnZXI7CiAgICB9OwogCiAgICBzdHJ1Y3QgTG9nZ2VyCiAgICB7CiAKICAgICAgICBleHBsaWNpdCBMb2dnZXIoc3RkOjpvc3RyZWFtJiBvc3RyZWFtKSA6IG9zdHJlYW1fKG9zdHJlYW0pCiAgICAgICAgewogICAgICAgIH0KIAogICAgICAgIFdyYXBwZWRTdHJlYW0gZmx1c2goKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIFdyYXBwZWRTdHJlYW0ob3N0cmVhbV8sIG11dGV4XywgKnRoaXMpIDw8ICJmbHVzaCI7CiAgICAgICAgfQogCiAgICAgICAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KICAgICAgICBXcmFwcGVkU3RyZWFtIG9wZXJhdG9yPDwoY29uc3QgVCYgeCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBXcmFwcGVkU3RyZWFtKG9zdHJlYW1fLCBtdXRleF8sICp0aGlzKSA8PCB4OwogICAgICAgIH0KIAogICAgICAgIHN0ZDo6b3N0cmVhbSYgb3N0cmVhbV87CiAgICAgICAgc3RkOjpyZWN1cnNpdmVfbXV0ZXggbXV0ZXhfOwogICAgfTsKIAogICAgbmFtZXNwYWNlIGlvCiAgICB7CiAgICAgICAgaW5saW5lIFdyYXBwZWRTdHJlYW0gZW5kbChMb2dnZXImIHJocykKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiByaHMuZmx1c2goKTsKICAgICAgICB9CiAgICB9CiAKICAgIExvZ2dlciB3cmFwX2NvdXQoc3RkOjpjb3V0KTsKfQoKaW50IG1haW4oKQp7Cgl0ZXN0Ojp3cmFwX2NvdXQgPDwgIlRocmVhZCBbIiA8PCBzdGQ6OnRoaXNfdGhyZWFkOjpnZXRfaWQoKSA8PCAiXSBwdXQgbWVzc2FnZTogZWxhcHNlZCB0aW1lOiAiIDw8IDEgPDwgdGVzdDo6aW86OmVuZGw7Cgl0ZXN0Ojp3cmFwX2NvdXQgPDwgdGVzdDo6aW86OmVuZGw7Cn0K