#include <string>
#include <iostream>
#include <sstream>
#include <thread>
#include <memory>
#include <mutex>
namespace test
{
struct GuardStream
{
GuardStream() = delete;
GuardStream(const GuardStream&) = delete;
void operator=(const GuardStream&) = delete;
GuardStream(std::ostream& ostream, std::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::mutex> m_gmtx;
};
struct WrappedStream
{
WrappedStream() = delete;
void operator=(const WrappedStream&) = delete;
WrappedStream(std::ostream& ostream, std::mutex& mutex)
: m_gstream( std::make_unique<GuardStream>(ostream, mutex))
{
}
WrappedStream(const WrappedStream& rhs)
{
m_gstream.swap(rhs.m_gstream);
}
template<typename T>
WrappedStream& operator<<(const T& x)
{
m_gstream->write(x);
return *this;
}
mutable std::unique_ptr<GuardStream> m_gstream;
};
struct Logger
{
explicit Logger(std::ostream& ostream) : ostream_(ostream)
{
}
WrappedStream flush()
{
return WrappedStream(ostream_, mutex_) << "flush";
}
template<typename T>
WrappedStream operator<<(const T& x)
{
return WrappedStream(ostream_, mutex_) << x;
}
std::ostream& ostream_;
std::mutex mutex_;
};
template<class T>
inline auto operator<< (WrappedStream& stream, const T& pFn) -> decltype(pFn(stream))
{
return pFn(stream);
}
//template<class T>
//auto operator<< (WrappedStream<std::wostringstream>& stream, const T& pFn) -> decltype(pFn(stream))
//{
// return pFn(stream);
//}
inline WrappedStream operator<<(Logger& logger, std::function<WrappedStream(Logger&)>& s)
{
return s(logger);
}
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;
return 0;
}
I2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3N0cmVhbT4KI2luY2x1ZGUgPHRocmVhZD4KI2luY2x1ZGUgPG1lbW9yeT4KI2luY2x1ZGUgPG11dGV4PgoKbmFtZXNwYWNlIHRlc3QKewoKCXN0cnVjdCBHdWFyZFN0cmVhbQoJewoJCUd1YXJkU3RyZWFtKCkgPSBkZWxldGU7CgkJR3VhcmRTdHJlYW0oY29uc3QgR3VhcmRTdHJlYW0mKSA9IGRlbGV0ZTsKCQl2b2lkIG9wZXJhdG9yPShjb25zdCBHdWFyZFN0cmVhbSYpID0gZGVsZXRlOwoKCQlHdWFyZFN0cmVhbShzdGQ6Om9zdHJlYW0mIG9zdHJlYW0sIHN0ZDo6bXV0ZXgmIG11dGV4KSAKCQk6IG1fc3RyZWFtKG9zdHJlYW0pLAoJCSAgbV9nbXR4KG11dGV4KQoJCXsKCQl9CgoJCX5HdWFyZFN0cmVhbSgpCgkJewoJCQltX3N0cmVhbS5mbHVzaCgpOwoJCX0KCgkJdGVtcGxhdGU8dHlwZW5hbWUgVD4KCQl2b2lkIHdyaXRlKGNvbnN0IFQmIHgpCgkJewoJCQltX3N0cmVhbSA8PCB4OwoJCX0KCQlzdGQ6Om9zdHJlYW0mIG1fc3RyZWFtOwoJCXN0ZDo6bG9ja19ndWFyZDxzdGQ6Om11dGV4PiBtX2dtdHg7Cgl9OwoKCXN0cnVjdCBXcmFwcGVkU3RyZWFtCgl7CgkJV3JhcHBlZFN0cmVhbSgpID0gZGVsZXRlOwoJCXZvaWQgb3BlcmF0b3I9KGNvbnN0IFdyYXBwZWRTdHJlYW0mKSA9IGRlbGV0ZTsKCQlXcmFwcGVkU3RyZWFtKHN0ZDo6b3N0cmVhbSYgb3N0cmVhbSwgc3RkOjptdXRleCYgbXV0ZXgpCgkJOiBtX2dzdHJlYW0oIHN0ZDo6bWFrZV91bmlxdWU8R3VhcmRTdHJlYW0+KG9zdHJlYW0sIG11dGV4KSkKCQl7CgkJfQoKCQlXcmFwcGVkU3RyZWFtKGNvbnN0IFdyYXBwZWRTdHJlYW0mIHJocykKCQl7CgkJCW1fZ3N0cmVhbS5zd2FwKHJocy5tX2dzdHJlYW0pOwoJCX0KCgkJdGVtcGxhdGU8dHlwZW5hbWUgVD4KCQlXcmFwcGVkU3RyZWFtJiBvcGVyYXRvcjw8KGNvbnN0IFQmIHgpCgkJewoJCQltX2dzdHJlYW0tPndyaXRlKHgpOwoJCQlyZXR1cm4gKnRoaXM7CgkJfQoJCW11dGFibGUgc3RkOjp1bmlxdWVfcHRyPEd1YXJkU3RyZWFtPiBtX2dzdHJlYW07Cgl9OwoKCXN0cnVjdCBMb2dnZXIgCgl7CgoJCWV4cGxpY2l0IExvZ2dlcihzdGQ6Om9zdHJlYW0mIG9zdHJlYW0pIDogb3N0cmVhbV8ob3N0cmVhbSkKCQl7CgkJfQoKCQlXcmFwcGVkU3RyZWFtIGZsdXNoKCkKCQl7CgkJCXJldHVybiBXcmFwcGVkU3RyZWFtKG9zdHJlYW1fLCBtdXRleF8pIDw8ICJmbHVzaCI7CgkJfQoKCQl0ZW1wbGF0ZTx0eXBlbmFtZSBUPiAKCQlXcmFwcGVkU3RyZWFtIG9wZXJhdG9yPDwoY29uc3QgVCYgeCkKCQl7CgkJCXJldHVybiBXcmFwcGVkU3RyZWFtKG9zdHJlYW1fLCBtdXRleF8pIDw8IHg7CgkJfQoKCQlzdGQ6Om9zdHJlYW0mIG9zdHJlYW1fOwoJCXN0ZDo6bXV0ZXggbXV0ZXhfOwoJfTsKCgl0ZW1wbGF0ZTxjbGFzcyBUPgoJaW5saW5lIGF1dG8gb3BlcmF0b3I8PCAoV3JhcHBlZFN0cmVhbSYgc3RyZWFtLCBjb25zdCBUJiBwRm4pIC0+IGRlY2x0eXBlKHBGbihzdHJlYW0pKQoJewoJCXJldHVybiBwRm4oc3RyZWFtKTsKCX0KCgkvL3RlbXBsYXRlPGNsYXNzIFQ+CgkvL2F1dG8gb3BlcmF0b3I8PCAoV3JhcHBlZFN0cmVhbTxzdGQ6Ondvc3RyaW5nc3RyZWFtPiYgc3RyZWFtLCBjb25zdCBUJiBwRm4pIC0+IGRlY2x0eXBlKHBGbihzdHJlYW0pKQoJLy97CgkvLwlyZXR1cm4gcEZuKHN0cmVhbSk7CgkvL30KCglpbmxpbmUgV3JhcHBlZFN0cmVhbSBvcGVyYXRvcjw8KExvZ2dlciYgbG9nZ2VyLCBzdGQ6OmZ1bmN0aW9uPFdyYXBwZWRTdHJlYW0oTG9nZ2VyJik+JiBzKQoJewoJCXJldHVybiBzKGxvZ2dlcik7Cgl9CgoJbmFtZXNwYWNlIGlvCgl7CgkJaW5saW5lIFdyYXBwZWRTdHJlYW0gZW5kbChMb2dnZXImIHJocykKCQl7CgkJCXJldHVybiByaHMuZmx1c2goKTsKCQl9Cgl9CgoJTG9nZ2VyIHdyYXBfY291dChzdGQ6OmNvdXQpOwp9IAoKaW50IG1haW4oKSAKewoJdGVzdDo6d3JhcF9jb3V0IDw8ICJUaHJlYWQgWyIgPDwgc3RkOjp0aGlzX3RocmVhZDo6Z2V0X2lkKCkgPDwgIl0gcHV0IG1lc3NhZ2U6IGVsYXBzZWQgdGltZTogIiA8PCAxIDw8IHRlc3Q6OmlvOjplbmRsOwoJcmV0dXJuIDA7Cn0=