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