diff options
| author | Lexi Winter <lexi@le-fay.org> | 2025-06-29 00:42:31 +0100 |
|---|---|---|
| committer | Lexi Winter <lexi@le-fay.org> | 2025-06-29 00:42:31 +0100 |
| commit | d24315268c11d435bb9accbce87b7f46dda6ed3e (patch) | |
| tree | 66589cb6a15fa74d4b09683105c583e4a5c222b4 /nihil.util/capture_stream.ccm | |
| parent | 7741a9698d29f79aca3e47495dcdf87c7a712f42 (diff) | |
| download | nihil-d24315268c11d435bb9accbce87b7f46dda6ed3e.tar.gz nihil-d24315268c11d435bb9accbce87b7f46dda6ed3e.tar.bz2 | |
cli: improve command dispatch a bit
Diffstat (limited to 'nihil.util/capture_stream.ccm')
| -rw-r--r-- | nihil.util/capture_stream.ccm | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/nihil.util/capture_stream.ccm b/nihil.util/capture_stream.ccm new file mode 100644 index 0000000..3333505 --- /dev/null +++ b/nihil.util/capture_stream.ccm @@ -0,0 +1,61 @@ +/* + * This source code is released into the public domain. + */ + +module; + +#include <iostream> + +export module nihil.util:capture_stream; + +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; + release(); + } + + /* + * 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 |
