/*++ Copyright (c) 2021 Microsoft Corporation Module Name: Logging support Abstract: Utilities for logging. Author: Nikolaj Bjorner (nbjorner) 2021-03-19 Jakob Rath 2021-04-6 --*/ #pragma once #include #include #include #include template struct show_deref_t { T const* ptr; }; template std::ostream& operator<<(std::ostream& out, show_deref_t s) { if (s.ptr) return out << *s.ptr; else return out << ""; } template show_deref_t show_deref(T* ptr) { return show_deref_t{ptr}; } template ().get())>::type> show_deref_t show_deref(Ptr const& ptr) { return show_deref_t{ptr.get()}; } template struct repeat { size_t count; T const& obj; repeat(size_t count, T const& obj): count(count), obj(obj) {} }; template std::ostream& operator<<(std::ostream& out, repeat const& r) { for (size_t i = r.count; i-- > 0; ) out << r.obj; return out; } enum class pad_direction { left, right, }; template struct pad { pad_direction dir; unsigned width; T const& obj; pad(pad_direction dir, unsigned width, T const& obj): dir(dir), width(width), obj(obj) {} }; template std::ostream& operator<<(std::ostream& out, pad const& p) { std::stringstream tmp; tmp << p.obj; std::string s = tmp.str(); size_t n = (s.length() < p.width) ? (p.width - s.length()) : 0; switch (p.dir) { case pad_direction::left: out << repeat(n, ' ') << s; break; case pad_direction::right: out << s << repeat(n, ' '); break; } return out; } /// Fill with spaces to the right: /// out << rpad(8, "hello") /// writes "hello ". template pad rpad(unsigned width, T const& obj) { return pad(pad_direction::right, width, obj); } /// Fill with spaces to the left. template pad lpad(unsigned width, T const& obj) { return pad(pad_direction::left, width, obj); }