summaryrefslogtreecommitdiffhomepage
path: root/log.h
diff options
context:
space:
mode:
Diffstat (limited to 'log.h')
-rw-r--r--log.h85
1 files changed, 85 insertions, 0 deletions
diff --git a/log.h b/log.h
new file mode 100644
index 0000000..cfc4d4c
--- /dev/null
+++ b/log.h
@@ -0,0 +1,85 @@
+#pragma once
+
+#include <iostream>
+#include <ostream>
+#include <sstream>
+#include <string>
+
+class log_stream
+{
+public:
+ log_stream(): m_active(false), m_buffer(), m_log_lines() {}
+
+ void log_lines(int n) {
+ m_log_lines = n;
+ }
+
+ std::string get_log() {
+ return m_buffer.str();
+ }
+
+ // log to buffer
+ void activate()
+ {
+ m_active = true;
+ }
+
+ // log to plain console
+ void deactivate()
+ {
+ m_active = false;
+ }
+
+ template<typename T>
+ log_stream& operator<<(const T& arg) {
+ if (m_active) {
+ m_buffer << arg;
+ trim_buffer();
+ }
+ else
+ {
+ std::cout << arg;
+ }
+ return *this;
+ }
+
+ log_stream& operator<<(
+ std::basic_ostream<char>& (*func)
+ (std::basic_ostream<char>&) ) {
+ if (m_active) {
+ m_buffer << *func;
+ trim_buffer();
+ }
+ else
+ {
+ std::cout << *func;
+ }
+ return *this;
+ }
+
+private:
+ void trim_buffer()
+ {
+ std::string s = m_buffer.str();
+ size_t pos = s.npos;
+ for (int i = 0; i <= m_log_lines; ++i) {
+ pos = s.rfind("\n", pos);
+ if (pos == s.npos) {
+ // too few lines
+ return;
+ }
+ if (pos > 0) {
+ --pos;
+ }
+ }
+
+ m_buffer.str(s.substr((pos <= (s.size() - 2)) ? pos + 2 : pos));
+ }
+
+ bool m_active;
+ std::stringstream m_buffer;
+ int m_log_lines;
+};
+
+extern log_stream log_cout;
+