#pragma once #ifndef _NB_SMARTSTREAM #define _NB_SMARTSTREAM #include #include #include #include #include #include #include #include namespace nb { template class SmartStream; template class SmartStream, Mixins...> : public virtual Mixins... { using StreamType = std::basic_ostream; protected: StreamType* const _stream; public: SmartStream(StreamType& stream) : _stream(&stream) {} StreamType* getStream() const { return _stream; } using Mixins::process...; template > static void process(SmartStream& stream, const U& val, StreamFmt* fmtas=nullptr) { *(stream._stream) << val; } template friend SmartStream& operator<<(SmartStream& stream, const U& val) { SmartStream::process(stream, val); return stream; } }; struct SmartText { int x; }; struct SmartStreamFormatter { template static void process(SmartStream& stream, const SmartText& val, StreamType* fmtas = nullptr) { *(stream.getStream()) << val.x; } }; } /*namespace nb { using RGB = std::array; class TerminalBufferController { template friend void switchCoutBuf(T); private: static auto terminal_buffer = std::cout.rdbuf(); TerminalBufferController(); }; std::string toANSI(const RGB& color) { return "\x1b[38;2;"+std::to_string(color[0])+";"+std::to_string(color[1])+ ";"+std::to_string(color[2])+"m"; } std::string toANSI(const unsigned int& color) { return "\x1b[38;5;"+std::to_string(color)+"m"; } template void switchCoutBuf(T val) { } /* class TextStream { virtual void write(std::) }; struct SmartTextBase { virtual std::string toString(std::ostream&) const = 0; virtual ~SmartTextBase() = default; }; template struct SmartText; template struct SmartText : SmartTextBase { explicit SmartText(const U& val) : msg(val) {} SmartText(const SmartText&) = default; template std::string toString(std::basic_ostream& stream) const { return static_cast(*this).toString(stream); } std::string toString(std::ostream& stream) const override { return static_cast(*this).toString(stream); } U msg; }; template struct SmartText : SmartTextBase { explicit SmartText(const U& val) : msg(val) {} SmartText(const SmartText&) = default; template std::string toString(std::basic_ostream& stream) const { std::stringstream sstr; auto stream_buf = stream.rdbuf(sstr.rdbuf()); stream << msg; stream.rdbuf(stream_buf); return sstr.str(); } std::string toString(std::ostream& stream) const override { std::stringstream sstr; auto stream_buf = stream.rdbuf(sstr.rdbuf()); stream << msg; stream.rdbuf(stream_buf); return sstr.str(); } U msg; }; template struct SmartText : SmartTextBase { template SmartText(char const(&val) [N]) : msg(val) {} SmartText(const std::string& val) : msg(val) {} SmartText(const char* val) : msg(val) {} SmartText(const SmartText&) = default; template std::string toString(std::basic_ostream& stream) const { return static_cast(*this).toString(stream); } std::string toString(std::ostream& stream) const override { return static_cast(*this).toString(stream); } std::string msg; }; template <> struct SmartText : SmartTextBase { template SmartText(char const(&val) [N]) : msg(val) {} SmartText(const std::string& val) : msg(val) {} SmartText(const char* val) : msg(val) {} SmartText(const SmartText&) = default; template std::string toString(std::basic_ostream& stream) const { std::stringstream sstr; auto stream_buf = stream.rdbuf(sstr.rdbuf()); stream << msg; stream.rdbuf(stream_buf); return sstr.str(); } std::string toString(std::ostream& stream) const override { std::stringstream sstr; auto stream_buf = stream.rdbuf(sstr.rdbuf()); stream << msg; stream.rdbuf(stream_buf); return sstr.str(); } std::string msg; }; template std::basic_ostream& operator<<(std::basic_ostream& stream, const SmartTextBase& smt) { stream << smt.toString(stream); return stream; } template struct TerminalColor : public SmartText> { typedef SmartText> Base; using Base::msg; explicit TerminalColor(unsigned int color, const U& val) : Base(val), colorSequence(toANSI(color)) { } explicit TerminalColor(const RGB& color, const U& val) : Base(val), colorSequence(toANSI(color)) { } TerminalColor(const TerminalColor&) = default; const std::string colorSequence; template std::string toString(std::basic_ostream& stream) const { std::stringstream sstr; auto stream_buf = stream.rdbuf(sstr.rdbuf()); if (&stream == &std::cout) { stream << colorSequence << msg << "\x1b[0m"; } else { stream << msg; } stream.rdbuf(stream_buf); return sstr.str(); } }; template std::vector> variadicToBaseVec(std::vector> vec, const U& val) { static_assert(std::is_base_of::value, "Push value type must be base of vector base type."); vec.push(static_cast>(std::make_shared(val))); return vec; } template std::vector> variadicToBaseVec(std::vector> vec, const U&... val) { vec.push(static_cast>(std::make_shared(val...))); return variadicToBaseVec(vec, val...); } struct SmartGroup : public SmartText>, SmartGroup> { using SmartVec = std::vector>; typedef SmartText Base; using Base::msg; SmartGroup(const SmartGroup&) = default; template explicit SmartGroup(const Types&... vals) : Base(variadicToBaseVec({}, vals...)) {} template void push(const T& val) { msg = variadicToBaseVec(msg, val); } template SmartGroup operator+(const T& val) { SmartGroup ret(*this); ret.push(val); return ret; } template std::string toString(std::basic_ostream& stream) const { std::stringstream sstr; auto stream_buf = stream.rdbuf(sstr.rdbuf()); for (const std::shared_ptr& st : msg) { stream << st; } stream.rdbuf(stream_buf); return sstr.str(); } }; template SmartGroup operator+(const SmartText& lhs, const SmartText& rhs) { return SmartGroup(lhs, rhs); } } */ #endif // _NB_SMARTSTREAM