33 #include "ResourceUsage.hpp" 37 inline std::string capitalize(std::string
const& s) {
46 inline std::string to_string(T
const& o) {
47 std::ostringstream oss;
52 template<std::ostream& os>
53 class MessageHandler_:
public std::ostream {
54 class Buf:
public std::streambuf {
58 Buf(MessageHandler_& mh)
63 virtual void imbue(std::locale
const& loc) {
67 virtual int overflow(
int c) {
68 if (!enabled)
return c;
70 if (lastUser !=
this) {
79 if (c == EOF)
return EOF;
82 if (isspace(c))
return c;
83 for (
int i = mh.indent; i > 0; --i) {
103 static int const INDENT_SIZE = 2;
105 static int indentLevel;
108 static Buf* lastUser;
114 ResourceUsage initialUsage;
115 ResourceUsage prevUsage;
124 : std::ostream(&buf), buf(*this), indent(indentLevel * INDENT_SIZE),
125 beginLine(0), totalSteps(0), stepCount(0),
126 dotCount(0), dotTime(0), stepping(false) {
128 precision(os.precision());
132 virtual ~MessageHandler_() {
133 if (!name.empty()) end(
"aborted");
136 static bool showMessages(
bool flag =
true) {
142 MessageHandler_& begin(std::string
const& s) {
143 if (!enabled)
return *
this;
144 if (!name.empty()) end(
"aborted");
145 name = s.empty() ?
"level-" + std::to_string(indentLevel) : s;
146 indent = indentLevel * INDENT_SIZE;
147 *
this <<
"\n" << capitalize(name);
148 indent = ++indentLevel * INDENT_SIZE;
150 initialUsage.update();
151 prevUsage = initialUsage;
156 MessageHandler_& setSteps(
int steps) {
157 if (!enabled)
return *
this;
161 dotTime = std::time(0);
166 MessageHandler_& step(
char dot =
'-') {
167 if (!enabled)
return *
this;
169 if (!stepping && dotTime + 4 < std::time(0)) {
175 if (stepCount % 50 != column - indent) {
177 for (
int i = stepCount % 50; i > 0; --i) {
183 if (column - indent >= 50) {
185 ResourceUsage diff = usage - prevUsage;
186 *
this << std::setw(3) << std::right
187 << (stepCount * 100 / totalSteps);
188 *
this <<
"% (" << diff.elapsedTime() <<
", " << diff.memory()
195 while (dotCount * totalSteps < stepCount * 10) {
196 if (dotCount == 0) *
this <<
' ';
199 dotTime = std::time(0);
206 MessageHandler_& end(std::string
const& msg =
"", std::string
const& info =
208 if (!enabled)
return *
this;
209 if (name.empty())
return *
this;
211 ResourceUsage rusage = ResourceUsage() - initialUsage;
213 if (beginLine == lineno) {
215 *
this <<
" " << info;
217 else if (msg.empty()) {
223 *
this <<
" in " << rusage <<
".\n";
225 indent = --indentLevel * INDENT_SIZE;
228 indent = --indentLevel * INDENT_SIZE;
231 *
this <<
"\nDone " << name;
234 *
this <<
"\n" << capitalize(msg);
236 if (!info.empty()) *
this <<
" " << info;
237 *
this <<
" in " << rusage <<
".\n";
244 MessageHandler_& end(
size_t n) {
245 if (!enabled)
return *
this;
246 return end(
"",
"<" + to_string(n) +
">");
254 template<std::ostream& os>
255 bool MessageHandler_<os>::enabled =
false;
257 template<std::ostream& os>
258 int MessageHandler_<os>::indentLevel = 0;
260 template<std::ostream& os>
261 int MessageHandler_<os>::lineno = 1;
263 template<std::ostream& os>
264 int MessageHandler_<os>::column = 0;
266 template<std::ostream& os>
267 typename MessageHandler_<os>::Buf* MessageHandler_<os>::lastUser = 0;
269 typedef MessageHandler_<std::cerr> MessageHandler;