#pragma once #include #include #include #include namespace ovdl::detail { template> class BasicCallbackStreamBuffer : public std::basic_streambuf { public: using base_type = std::basic_streambuf; using callback_type = Callback; using char_type = typename base_type::char_type; using int_type = typename base_type::int_type; BasicCallbackStreamBuffer(Callback cb, void* user_data = nullptr) : _callback(cb), _user_data(user_data) {} protected: std::streamsize xsputn(const char_type* s, std::streamsize n) override { if constexpr (std::is_same_v) { _callback(s, n, _user_data); return n; } else { return _callback(s, n, _user_data); // returns the number of characters successfully written. } }; int_type overflow(int_type ch) override { if constexpr (std::is_same_v) { _callback(&ch, 1, _user_data); return 1; } else { return _callback(&ch, 1, _user_data); // returns the number of characters successfully written. } } private: Callback _callback; void* _user_data; }; template class CallbackStreamBuffer : public BasicCallbackStreamBuffer { public: using base_type = BasicCallbackStreamBuffer; using callback_type = Callback; using char_type = typename base_type::char_type; using int_type = typename base_type::int_type; CallbackStreamBuffer(Callback cb, void* user_data = nullptr) : base_type(cb, user_data) {} }; template class CallbackWStreamBuffer : public BasicCallbackStreamBuffer { public: using base_type = BasicCallbackStreamBuffer; using callback_type = Callback; using char_type = typename base_type::char_type; using int_type = typename base_type::int_type; CallbackWStreamBuffer(Callback cb, void* user_data = nullptr) : base_type(cb, user_data) {} }; template> class BasicCallbackStream : public std::basic_ostream { public: using base_type = std::basic_ostream; BasicCallbackStream(Callback cb, void* user_data = nullptr) : m_sbuf(cb, user_data), std::basic_ios(&m_sbuf), std::basic_ostream(&m_sbuf) { std::basic_ios::init(&m_sbuf); } private: BasicCallbackStreamBuffer m_sbuf; }; template class CallbackStream : public BasicCallbackStream { public: using base_type = BasicCallbackStream; CallbackStream(Callback cb, void* user_data = nullptr) : base_type(cb, user_data) { } }; template class CallbackWStream : public BasicCallbackStream { public: using base_type = BasicCallbackStream; CallbackWStream(Callback cb, void* user_data = nullptr) : base_type(cb, user_data) { } }; }