fork download
  1. #include <string>
  2. #include <iostream>
  3. #include <sstream>
  4. #include <thread>
  5. #include <memory>
  6. #include <mutex>
  7.  
  8. namespace test
  9. {
  10.  
  11. struct GuardStream
  12. {
  13. GuardStream() = delete;
  14. GuardStream(const GuardStream&) = delete;
  15. void operator=(const GuardStream&) = delete;
  16.  
  17. GuardStream(std::ostream& ostream, std::mutex& mutex)
  18. : m_stream(ostream),
  19. m_gmtx(mutex)
  20. {
  21. }
  22.  
  23. ~GuardStream()
  24. {
  25. m_stream.flush();
  26. }
  27.  
  28. template<typename T>
  29. void write(const T& x)
  30. {
  31. m_stream << x;
  32. }
  33. std::ostream& m_stream;
  34. std::lock_guard<std::mutex> m_gmtx;
  35. };
  36.  
  37. struct WrappedStream
  38. {
  39. WrappedStream() = delete;
  40. void operator=(const WrappedStream&) = delete;
  41. WrappedStream(std::ostream& ostream, std::mutex& mutex)
  42. : m_gstream( std::make_unique<GuardStream>(ostream, mutex))
  43. {
  44. }
  45.  
  46. WrappedStream(const WrappedStream& rhs)
  47. {
  48. m_gstream.swap(rhs.m_gstream);
  49. }
  50.  
  51. template<typename T>
  52. WrappedStream& operator<<(const T& x)
  53. {
  54. m_gstream->write(x);
  55. return *this;
  56. }
  57. mutable std::unique_ptr<GuardStream> m_gstream;
  58. };
  59.  
  60. struct Logger
  61. {
  62.  
  63. explicit Logger(std::ostream& ostream) : ostream_(ostream)
  64. {
  65. }
  66.  
  67. WrappedStream flush()
  68. {
  69. return WrappedStream(ostream_, mutex_) << "flush";
  70. }
  71.  
  72. template<typename T>
  73. WrappedStream operator<<(const T& x)
  74. {
  75. return WrappedStream(ostream_, mutex_) << x;
  76. }
  77.  
  78. std::ostream& ostream_;
  79. std::mutex mutex_;
  80. };
  81.  
  82. template<class T>
  83. inline auto operator<< (WrappedStream& stream, const T& pFn) -> decltype(pFn(stream))
  84. {
  85. return pFn(stream);
  86. }
  87.  
  88. //template<class T>
  89. //auto operator<< (WrappedStream<std::wostringstream>& stream, const T& pFn) -> decltype(pFn(stream))
  90. //{
  91. // return pFn(stream);
  92. //}
  93.  
  94. inline WrappedStream operator<<(Logger& logger, std::function<WrappedStream(Logger&)>& s)
  95. {
  96. return s(logger);
  97. }
  98.  
  99. namespace io
  100. {
  101. inline WrappedStream endl(Logger& rhs)
  102. {
  103. return rhs.flush();
  104. }
  105. }
  106.  
  107. Logger wrap_cout(std::cout);
  108. }
  109.  
  110. int main()
  111. {
  112. test::wrap_cout << "Thread [" << std::this_thread::get_id() << "] put message: elapsed time: " << 1 << test::io::endl;
  113. return 0;
  114. }
Success #stdin #stdout 0s 4380KB
stdin
Standard input is empty
stdout
Thread [47154141996992] put message: elapsed time: 11