+ Tee(ios& s, ofstream& f) : stream(s), file(f), stream_buf(s.rdbuf()) {}
+ ~Tee() { set(false); }
+
+ void set(bool b) { stream.rdbuf(b ? this : stream_buf); }
+
+private:
+ int_type overflow(int_type c) {
+
+ if (traits_type::eq_int_type(c, traits_type::eof()))
+ return traits_type::not_eof(c);
+
+ c = stream_buf->sputc(traits_type::to_char_type(c));
+
+ if (!traits_type::eq_int_type(c, traits_type::eof()))
+ c = file.rdbuf()->sputc(traits_type::to_char_type(c));
+
+ return c;
+ }
+
+ int sync() {
+
+ int c = stream_buf->pubsync();
+
+ if (c != -1)
+ c = file.rdbuf()->pubsync();
+
+ return c;
+ }
+
+ int underflow() { return traits_type::not_eof(stream_buf->sgetc()); }
+
+ int uflow() {
+
+ int c = stream_buf->sbumpc();
+
+ if (!traits_type::eq_int_type(c, traits_type::eof()))
+ file.rdbuf()->sputc(traits_type::to_char_type(c));
+
+ return traits_type::not_eof(c);
+ }
+
+ ios& stream;
+ ofstream& file;
+ streambuf* stream_buf;
+};
+
+class Logger {
+public:
+ Logger() : in(cin, file), out(cout, file) {}
+ ~Logger() { set(false); }
+
+ void set(bool b) {
+
+ if (b && !file.is_open())
+ {
+ file.open("io_log.txt", ifstream::out | ifstream::app);
+ in.set(true);
+ out.set(true);
+ }
+ else if (!b && file.is_open())
+ {
+ out.set(false);
+ in.set(false);
+ file.close();
+ }
+ }
+
+private:
+ Tee in, out;
+ ofstream file;
+};
+
+void logger_set(bool b) {
+
+ static Logger l;
+ l.set(b);