dstream.hpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. //
  2. // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Official repository: https://github.com/boostorg/beast
  8. //
  9. #ifndef BOOST_BEAST_UNIT_TEST_DSTREAM_HPP
  10. #define BOOST_BEAST_UNIT_TEST_DSTREAM_HPP
  11. #include <boost/config.hpp>
  12. #include <ios>
  13. #include <memory>
  14. #include <ostream>
  15. #include <sstream>
  16. #include <streambuf>
  17. #include <string>
  18. #ifdef BOOST_WINDOWS
  19. #include <boost/winapi/basic_types.hpp>
  20. #include <boost/winapi/debugapi.hpp>
  21. #endif
  22. namespace boost {
  23. namespace beast {
  24. namespace unit_test {
  25. #ifdef BOOST_WINDOWS
  26. namespace detail {
  27. template<class CharT, class Traits, class Allocator>
  28. class dstream_buf
  29. : public std::basic_stringbuf<CharT, Traits, Allocator>
  30. {
  31. using ostream = std::basic_ostream<CharT, Traits>;
  32. ostream& os_;
  33. bool dbg_;
  34. template<class T>
  35. void write(T const*) = delete;
  36. void write(char const* s)
  37. {
  38. if(dbg_)
  39. boost::winapi::OutputDebugStringA(s);
  40. os_ << s;
  41. }
  42. void write(wchar_t const* s)
  43. {
  44. if(dbg_)
  45. boost::winapi::OutputDebugStringW(s);
  46. os_ << s;
  47. }
  48. public:
  49. explicit
  50. dstream_buf(ostream& os)
  51. : os_(os)
  52. , dbg_(boost::winapi::IsDebuggerPresent() != 0)
  53. {
  54. }
  55. ~dstream_buf()
  56. {
  57. sync();
  58. }
  59. int
  60. sync() override
  61. {
  62. write(this->str().c_str());
  63. this->str("");
  64. return 0;
  65. }
  66. };
  67. } // detail
  68. /** std::ostream with Visual Studio IDE redirection.
  69. Instances of this stream wrap a specified `std::ostream`
  70. (such as `std::cout` or `std::cerr`). If the IDE debugger
  71. is attached when the stream is created, output will be
  72. additionally copied to the Visual Studio Output window.
  73. */
  74. template<
  75. class CharT,
  76. class Traits = std::char_traits<CharT>,
  77. class Allocator = std::allocator<CharT>
  78. >
  79. class basic_dstream
  80. : public std::basic_ostream<CharT, Traits>
  81. {
  82. detail::dstream_buf<
  83. CharT, Traits, Allocator> buf_;
  84. public:
  85. /** Construct a stream.
  86. @param os The output stream to wrap.
  87. */
  88. explicit
  89. basic_dstream(std::ostream& os)
  90. : std::basic_ostream<CharT, Traits>(&buf_)
  91. , buf_(os)
  92. {
  93. if(os.flags() & std::ios::unitbuf)
  94. std::unitbuf(*this);
  95. }
  96. };
  97. using dstream = basic_dstream<char>;
  98. using dwstream = basic_dstream<wchar_t>;
  99. #else
  100. using dstream = std::ostream&;
  101. using dwstream = std::wostream&;
  102. #endif
  103. } // unit_test
  104. } // beast
  105. } // boost
  106. #endif