diff options
Diffstat (limited to 'nihil.core/capture_stream.ccm')
| -rw-r--r-- | nihil.core/capture_stream.ccm | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/nihil.core/capture_stream.ccm b/nihil.core/capture_stream.ccm new file mode 100644 index 0000000..5ab4f2d --- /dev/null +++ b/nihil.core/capture_stream.ccm @@ -0,0 +1,55 @@ +// This source code is released into the public domain. +export module nihil.core:capture_stream; + +import nihil.std; + +namespace nihil { + +// Capture output written to a stream and redirect it to an internal string +// buffer. Call .str() to get the data written. Call .release() to stop +// capturing (or simply delete the capture_stream object). +export template<typename Char, typename Traits> +struct capture_stream { + capture_stream(std::basic_ostream<Char, Traits> &stream) + : m_stream(&stream) + { + m_old_streambuf = m_stream->rdbuf(); + m_stream->rdbuf(m_buffer.rdbuf()); + } + + ~capture_stream() + { + if (m_old_streambuf == nullptr) + return; + m_stream->rdbuf(m_old_streambuf); + } + + /* + * Release this capture, returning the stream to its previous state. + */ + auto release(this capture_stream &self) -> void + { + if (self.m_old_streambuf == nullptr) + throw std::logic_error( + "release() called on empty capture_stream"); + + self.m_stream->rdbuf(self.m_old_streambuf); + self.m_old_streambuf = nullptr; + } + + /* + * Get the data which has been written to the stream. + */ + [[nodiscard]] auto str(this capture_stream const &self) + -> std::basic_string_view<Char, Traits> + { + return self.m_buffer.view(); + } + +private: + std::basic_ostringstream<Char, Traits> m_buffer; + std::basic_ostream<Char, Traits> *m_stream; + std::streambuf *m_old_streambuf; +}; + +} // namespace nihil |
