#pragma once #include #include #include template struct TDumper { template static inline void Dump(S& s, const T& t) { s.Stream() << t; } }; namespace NDumpPrivate { template inline void Dump(T& t, const V& v) { ::TDumper::Dump(t, v); } template inline T&& operator<<(T&& t, V&& v) { Dump(t, v); return std::forward(t); } struct TADLBase { }; } struct TDumpBase: public ::NDumpPrivate::TADLBase { inline TDumpBase(IOutputStream& out, bool indent) noexcept : Out(&out) , IndentLevel(0) , Indent(indent) { } inline IOutputStream& Stream() const noexcept { return *Out; } void Char(char ch); void Char(wchar16 ch); void String(const TStringBuf& s); void String(const TWtringBuf& s); void Raw(const TStringBuf& s); IOutputStream* Out; size_t IndentLevel; bool Indent; }; struct TIndentScope { inline TIndentScope(TDumpBase& d) : D(&d) { ++(D->IndentLevel); } inline ~TIndentScope() { --(D->IndentLevel); } TDumpBase* D; }; template struct TRawLiteral { const TBasicStringBuf S; }; template static inline TRawLiteral DumpRaw(const TBasicStringBuf& s) noexcept { return {s}; } template static inline TRawLiteral DumpRaw(const TChar* s) noexcept { return {s}; } template struct TDumper> { template static inline void Dump(S& s, const TRawLiteral& v) { s.Raw(v.S); } }; struct TIndentNewLine { }; static inline TIndentNewLine IndentNewLine() noexcept { return {}; } template <> struct TDumper { template static inline void Dump(S& s, const TIndentNewLine&) { if (s.Indent) { s << DumpRaw("\n") << DumpRaw(TString(s.IndentLevel * 4, ' ').data()); } } }; template struct TDumper { template static inline void Dump(S& s, const P* p) { s.Pointer(p); } }; template struct TDumper: public TDumper { }; struct TCharDumper { template static inline void Dump(S& s, const V& v) { s.Char(v); } }; template static inline void OutSequence(S& s, const V& v, const char* openTag, const char* closeTag) { s.ColorScheme.Markup(s); s << DumpRaw(openTag); { TIndentScope scope(s); size_t cnt = 0; for (const auto& x : v) { if (cnt) { s.ColorScheme.Markup(s); s << DumpRaw(", "); } s << IndentNewLine(); s.ColorScheme.Literal(s); s << x; ++cnt; } } s << IndentNewLine(); s.ColorScheme.Markup(s); s << DumpRaw(closeTag); s.ColorScheme.ResetType(s); } struct TAssocDumper { template static inline void Dump(S& s, const V& v) { ::OutSequence(s, v, "{", "}"); } }; struct TSeqDumper { template static inline void Dump(S& s, const V& v) { ::OutSequence(s, v, "[", "]"); } }; struct TStrDumper { template static inline void Dump(S& s, const V& v) { s.ColorScheme.String(s); s.String(v); s.ColorScheme.ResetType(s); } };