#pragma once #include #include namespace lsp { class stream { public: virtual ~stream() = default; virtual bool fail() = 0; virtual bool bad() = 0; virtual bool eof() = 0; virtual bool good() = 0; virtual void clear() = 0; virtual std::string what() = 0; virtual bool need_to_clear_the_state() { return false; } bool operator!() { return bad(); } }; class istream : public stream { public: virtual int get() = 0; virtual ~istream() = default; virtual istream& read(char* str, std::streamsize count) = 0; }; template class base_istream : public istream { public: explicit base_istream(T& _t) :_impl(_t) { } int get() override { return _impl.get(); } bool fail() override { return _impl.fail(); } bool bad() override { return _impl.bad(); } bool eof() override { return _impl.eof(); } bool good() override { return _impl.good(); } istream& read(char* str, std::streamsize count) override { _impl.read(str, count); return *this; } void clear() override { _impl.clear(); } T& _impl; }; class ostream : public stream { public: virtual ~ostream() = default; virtual ostream& write(const std::string&) = 0; virtual ostream& write(std::streamsize) = 0; virtual ostream& flush() = 0; }; template class base_ostream : public ostream { public: explicit base_ostream(T& _t) :_impl(_t) { } bool fail() override { return _impl.fail(); } bool good() override { return _impl.good(); } bool bad() override { return _impl.bad(); } bool eof() override { return _impl.eof(); } ostream& write(const std::string& c) override { _impl << c; return *this; } ostream& write(std::streamsize _s) override { _impl << std::to_string(_s); return *this; } ostream& flush() override { _impl.flush(); return *this; } void clear() override { _impl.clear(); } protected: T& _impl; }; template class base_iostream : public istream, public ostream { public: explicit base_iostream(T& _t) :_impl(_t) { } int get() override { return _impl.get(); } bool fail() override { return _impl.fail(); } bool bad() override { return _impl.bad(); } bool eof() override { return _impl.eof(); } bool good() override { return _impl.good(); } istream& read(char* str, std::streamsize count) override { _impl.read(str, count); return *this; } ostream& write(const std::string& c) override { _impl << c; return *this; } ostream& write(std::streamsize _s) override { _impl << std::to_string(_s); return *this; } ostream& flush() override { _impl.flush(); return *this; } void clear() override { _impl.clear(); } protected: T& _impl; }; }