#ifndef BOOST_PARSER_DETAIL_VS_OUTPUT_STREAM_HPP #define BOOST_PARSER_DETAIL_VS_OUTPUT_STREAM_HPP #include #include #include #include #include namespace boost::parser::detail { template> class basic_debugbuf : public std::basic_stringbuf { public: virtual ~basic_debugbuf() { sync_impl(); } protected: int sync_impl() { output_debug_string(this->str().c_str()); this->str(std::basic_string()); // Clear the string buffer return 0; } int sync() override { return sync_impl(); } void output_debug_string(const CharT * text); }; template<> inline void basic_debugbuf::output_debug_string(const char * text) { // Save in-memory logging buffer to a log file on error (from MSDN // example). std::wstring dest; int convert_result = MultiByteToWideChar( CP_UTF8, 0, text, static_cast(std::strlen(text)), nullptr, 0); if (convert_result <= 0) { // cannot convert to wide-char -> use ANSI API ::OutputDebugStringA(text); } else { dest.resize(convert_result + 10); convert_result = MultiByteToWideChar( CP_UTF8, 0, text, static_cast(std::strlen(text)), dest.data(), static_cast(dest.size())); if (convert_result <= 0) { // cannot convert to wide-char -> use ANSI API ::OutputDebugStringA(text); } else { ::OutputDebugStringW(dest.c_str()); } } } template> class basic_debug_ostream : public std::basic_ostream { public: basic_debug_ostream() : std::basic_ostream( new basic_debugbuf()) {} ~basic_debug_ostream() { delete this->rdbuf(); } }; inline basic_debug_ostream vs_cout; // } #endif