aboutsummaryrefslogtreecommitdiffstats
path: root/nihil.util/capture_stream.ccm
diff options
context:
space:
mode:
Diffstat (limited to 'nihil.util/capture_stream.ccm')
-rw-r--r--nihil.util/capture_stream.ccm62
1 files changed, 62 insertions, 0 deletions
diff --git a/nihil.util/capture_stream.ccm b/nihil.util/capture_stream.ccm
new file mode 100644
index 0000000..7ec39a9
--- /dev/null
+++ b/nihil.util/capture_stream.ccm
@@ -0,0 +1,62 @@
+/*
+ * 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;
+ 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