CASM  1.1.0
A Clusters Approach to Statistical Mechanics
Log.hh
Go to the documentation of this file.
1 #ifndef CASM_Log
2 #define CASM_Log
3 
4 #include <boost/chrono.hpp>
5 #include <iostream>
6 #include <vector>
7 
9 
10 namespace CASM {
11 
12 class Log;
13 struct LogText;
14 struct LogParagraph;
15 struct LogVerbatim;
16 
18 
19 struct LogText : public notstd::Cloneable {
21 
22  explicit LogText(std::string _text) : text(_text) {}
23 
24  std::string text;
25 
26  virtual void print(Log &log) const = 0;
27 };
28 
29 struct LogParagraph : public LogText {
31 
32  explicit LogParagraph(std::string _text) : LogText(_text) {}
33 
34  virtual void print(Log &log) const override;
35 };
36 
37 struct LogVerbatim : public LogText {
39 
40  explicit LogVerbatim(std::string _text, bool _indent_first_line = true)
41  : LogText(_text), indent_first_line(_indent_first_line) {}
42 
44 
45  virtual void print(Log &log) const override;
46 };
47 
48 class Log {
49  public:
50  static const int none = 0;
51  static const int quiet = 5;
52  static const int standard = 10;
53  static const int verbose = 20;
54  static const int debug = 100;
55 
65  Log(std::ostream &_ostream = std::cout, int _verbosity = standard,
66  bool _show_clock = false, int _indent_space = 2);
67 
68  // --- List of section types ---
69  // Each adds a header, ends the previous section, and begins a new section
70  // Each section is associated with a verbosity level which must be met or
71  // exceded in order for the section to be printed to the stream
72 
73  template <int _required_verbosity = standard>
74  void calculate(const std::string &what) {
75  _add<_required_verbosity>("Calculate", what);
76  }
77 
78  template <int _required_verbosity = standard>
79  void construct(const std::string &what) {
80  _add<_required_verbosity>("Construct", what);
81  }
82 
83  template <int _required_verbosity = standard>
84  void generate(const std::string &what) {
85  _add<_required_verbosity>("Generate", what);
86  }
87 
88  template <int _required_verbosity = standard>
89  void set(const std::string &what) {
90  _add<_required_verbosity>("Set", what);
91  }
92 
93  template <int _required_verbosity = standard>
94  void check(const std::string &what) {
95  _add<_required_verbosity>("Check", what);
96  }
97 
98  template <int _required_verbosity = standard>
99  void results(const std::string &what) {
100  _add<_required_verbosity>("Results", what);
101  }
102 
103  template <int _required_verbosity = standard>
104  void read(const std::string &what) {
105  _add<_required_verbosity>("Read", what);
106  }
107 
108  template <int _required_verbosity = standard>
109  void write(const std::string &what) {
110  _add<_required_verbosity>("Write", what);
111  }
112 
113  template <int _required_verbosity = standard>
114  void begin(const std::string &what) {
115  _add<_required_verbosity>("Begin", what);
116  }
117 
118  template <int _required_verbosity = standard>
119  void end(const std::string &what) {
120  _add<_required_verbosity>("End", what);
121  }
122 
123  template <int _required_verbosity = standard>
124  void warning(const std::string &what) {
125  _add<_required_verbosity>("Warning", what);
126  }
127 
128  template <int _required_verbosity = standard>
129  void error(const std::string &what) {
130  _add<_required_verbosity>("Error", what);
131  }
132 
133  template <int _required_verbosity = standard>
134  void compiling(const std::string &what) {
135  _add<_required_verbosity>("Compiling", what);
136  }
137 
138  template <int _required_verbosity = standard>
139  void custom(const std::string &what) {
140  static_assert(_required_verbosity >= none && _required_verbosity <= debug,
141  "CASM::Log _required_verbosity must be <= 100");
142  end_section();
143  begin_section<_required_verbosity>();
144  if (_print()) {
145  ostream() << indent_str() << "-- " << what << " -- ";
146  _add_time();
147  ostream() << std::endl;
148  }
149  }
150 
151  template <int _required_verbosity = standard>
152  void custom(const std::string &type, const std::string &what) {
153  _add<_required_verbosity>(type, what);
154  }
155 
157  template <int _required_verbosity = standard>
158  void begin_section() {
159  m_required_verbosity.push_back(_required_verbosity);
161  }
162 
187  begin_section<none>();
188  return *this;
189  }
190 
192  void end_section() {
193  if (m_required_verbosity.size()) {
194  m_required_verbosity.pop_back();
195  }
197  }
198 
199  // --- Timing ---
200  // Enables timing by section
201 
202  void restart_clock();
203 
204  void show_clock();
205 
206  void hide_clock();
207 
208  double time_s() const;
209 
210  void begin_lap();
211 
212  double lap_time() const;
213 
214  // --- Verbosity ---
215 
216  int verbosity() const;
217 
218  void set_verbosity(int _verbosity);
219 
220  template <int _required_verbosity>
222  static_assert(_required_verbosity >= none && _required_verbosity <= debug,
223  "CASM::Log _required_verbosity must be <= 100");
224  m_print = (m_verbosity >= _required_verbosity);
225  return *this;
226  }
227 
228  void reset(std::ostream &_ostream = std::cout);
229 
230  // --- Paragraph printing ---
231 
233 
234  int width() const { return m_paragraph_width; }
235 
238  }
239 
241 
242  Log &paragraph(std::string text);
243 
244  Log &verbatim(std::string text, bool indent_first_line = true);
245 
246  // --- List printing
247 
249  template <typename OutputIterator>
250  Log &verbatim_list(OutputIterator begin, OutputIterator end,
251  std::string sep = "- ");
252 
253  // --- Stream operations ---
254 
255  template <typename T>
256  friend Log &operator<<(Log &log, const T &msg_details);
257 
258  friend Log &operator<<(Log &log, std::ostream &(*fptr)(std::ostream &));
259 
260  operator std::ostream &();
261 
262  std::ostream &ostream() { return *m_ostream; }
263 
264  bool print() const;
265 
266  explicit operator bool() { return m_print; }
267 
268  // --- Indentation ---
269  // Indentation is not coupled to sectioning
270 
271  int indent_space() const { return m_indent_space; }
272 
273  std::string indent_str() const {
274  return std::string(m_indent_space * m_indent_level + m_indent_spaces, ' ');
275  }
276 
278 
280  if (m_indent_level > 0) {
281  m_indent_level--;
282  }
283  }
284 
286 
288 
289  Log &indent() {
290  (*this) << indent_str();
291  return *this;
292  }
293 
295  template <typename T>
296  Log &indent(const T &t) {
297  std::stringstream ss;
298  ss << t;
299  return verbatim(ss.str());
300  }
301 
302  static std::string invalid_verbosity_msg(std::string s);
303 
305  static std::pair<bool, int> verbosity_level(std::string s);
306 
307  private:
308  template <int _required_verbosity = standard>
309  void _add(const std::string &type, const std::string &what) {
310  static_assert(_required_verbosity >= none && _required_verbosity <= debug,
311  "CASM::Log _required_verbosity must be <= 100");
312  end_section();
313  begin_section<_required_verbosity>();
314  if (_print()) {
315  ostream() << indent_str() << "-- " << type << ": " << what << " -- ";
316  _add_time();
317  ostream() << std::endl;
318  }
319  }
320 
321  void _print_justified_line(std::vector<std::string> &line, int curr_width);
322  void _print_left_justified_line(std::vector<std::string> &line,
323  int curr_width);
324  void _print_right_justified_line(std::vector<std::string> &line,
325  int curr_width);
326  void _print_center_justified_line(std::vector<std::string> &line,
327  int curr_width);
328  void _print_full_justified_line(std::vector<std::string> &line,
329  int curr_width);
330 
331  void _add_time();
332 
333  bool _print() const;
334 
335  std::vector<int> m_required_verbosity;
336 
339 
341  bool m_print;
342 
344 
349 
350  // for paragraph writing
353 
354  boost::chrono::steady_clock::time_point m_start_time;
355 
356  boost::chrono::steady_clock::time_point m_lap_start_time;
357 
358  std::ostream *m_ostream;
359 };
360 
376 template <typename OutputIterator>
377 Log &Log::verbatim_list(OutputIterator begin, OutputIterator end,
378  std::string sep) {
379  int n_indent_spaces = sep.size();
380 
381  bool indent_first_line = false;
382  for (auto it = begin; it != end; ++it) {
383  indent() << sep;
384  std::stringstream ss;
385  ss << *it;
386  increase_indent_spaces(n_indent_spaces);
387  verbatim(ss.str(), indent_first_line);
388  decrease_indent_spaces(n_indent_spaces);
389  }
390  return *this;
391 }
392 
393 template <typename T>
394 Log &operator<<(Log &log, const T &msg_details) {
395  if (log._print()) {
396  static_cast<std::ostream &>(log) << msg_details;
397  }
398  return log;
399 }
400 
401 Log &operator<<(Log &log, std::ostream &(*fptr)(std::ostream &));
402 
404 class FixedLog : public Log {
405  public:
406  explicit FixedLog(std::ostream &_ostream);
407  FixedLog(FixedLog const &) = delete;
408  FixedLog &operator=(FixedLog const &RHS) = delete;
409 
410  private:
411  using Log::reset;
412 };
413 
414 inline Log &default_log() {
415  static Log log{std::cout};
416  return log;
417 }
418 
419 inline Log &default_err_log() {
420  static Log log{std::cerr};
421  return log;
422 }
423 
424 inline Log &log() { return CASM::default_log(); }
425 
426 inline Log &err_log() { return CASM::default_err_log(); }
427 
428 inline Log &cout_log() {
429  static FixedLog log{std::cout};
430  return log;
431 }
432 
433 inline Log &cerr_log() {
434  static FixedLog log{std::cerr};
435  return log;
436 }
437 
438 inline Log &null_log() {
439  static std::ostream nullout{nullptr};
440  static FixedLog log{nullout};
441  return log;
442 }
443 
444 class OStringStreamLog : public Log {
445  public:
454  OStringStreamLog(int _verbosity = standard, bool _show_clock = false)
455  : Log(std::cout, _verbosity, _show_clock) {
456  reset(m_ss);
457  }
458 
459  std::ostringstream &ss() { return m_ss; };
460 
461  const std::ostringstream &ss() const { return m_ss; };
462 
463  private:
464  std::ostringstream m_ss;
465 };
466 
471  public:
472  ScopedLogging(Log &new_log, Log &new_err_log)
474  CASM::log() = new_log;
475  CASM::err_log() = new_err_log;
476  }
477 
479  CASM::log() = m_old_log;
481  }
482 
485 };
486 
491  public:
493 
494  private:
496 };
497 
504  public:
507  bool _show_clock = false)
508  : m_ss_log(_verbosity, _show_clock),
509  m_ss_err_log(_verbosity, _show_clock) {
510  m_logging = notstd::make_unique<ScopedLogging>(m_ss_log, m_ss_err_log);
511  }
512 
514 
515  std::ostringstream &ss() { return m_ss_log.ss(); };
516 
517  const std::ostringstream &ss() const { return m_ss_log.ss(); };
518 
519  std::ostringstream &err_ss() { return m_ss_err_log.ss(); };
520 
521  const std::ostringstream &err_ss() const { return m_ss_err_log.ss(); };
522 
523  private:
524  std::unique_ptr<ScopedLogging> m_logging;
527 };
528 
529 // class Logging {
530 //
531 // public:
532 //
533 // Logging(Log &log = default_log(), Log &debug_log = default_log(), Log
534 // &err_log = default_err_log()) :
535 // m_log(&log),
536 // m_debug_log(&debug_log),
537 // m_err_log(&err_log) {
538 // }
539 //
540 // Log &log() const {
541 // return *m_log;
542 // }
543 //
544 // Log &debug_log() const {
545 // return *m_debug_log;
546 // }
547 //
548 // Log &err_log() const {
549 // return *m_err_log;
550 // }
551 //
552 // static Logging null() {
553 // return Logging(null_log(), null_log(), null_log());
554 // }
555 //
556 // private:
557 //
558 // Log *m_log;
559 // Log *m_debug_log;
560 // Log *m_err_log;
561 //
562 // };
563 
564 } // namespace CASM
565 
566 #endif
std::set< std::string > & s
A Log whose underlying ostream* cannot be reset.
Definition: Log.hh:404
FixedLog(std::ostream &_ostream)
Definition: Log.cc:277
FixedLog(FixedLog const &)=delete
FixedLog & operator=(FixedLog const &RHS)=delete
Definition: Log.hh:48
boost::chrono::steady_clock::time_point m_lap_start_time
Definition: Log.hh:356
void read(const std::string &what)
Definition: Log.hh:104
void custom(const std::string &type, const std::string &what)
Definition: Log.hh:152
int width() const
Definition: Log.hh:234
static const int none
Definition: Log.hh:50
bool m_print
Whether to print.
Definition: Log.hh:341
static const int quiet
Definition: Log.hh:51
static std::string invalid_verbosity_msg(std::string s)
Definition: Log.cc:219
void _print_justified_line(std::vector< std::string > &line, int curr_width)
Definition: Log.cc:81
std::string indent_str() const
Definition: Log.hh:273
Log & require()
Definition: Log.hh:221
void _add(const std::string &type, const std::string &what)
Definition: Log.hh:309
int m_paragraph_width
Definition: Log.hh:351
bool m_show_clock
Definition: Log.hh:343
void _add_time()
Definition: Log.cc:262
void end_section()
End a section.
Definition: Log.hh:192
Log(std::ostream &_ostream=std::cout, int _verbosity=standard, bool _show_clock=false, int _indent_space=2)
Construct a Log.
Definition: Log.cc:22
bool print() const
Definition: Log.cc:260
void set_verbosity(int _verbosity)
Definition: Log.cc:57
void _print_center_justified_line(std::vector< std::string > &line, int curr_width)
Definition: Log.cc:126
void check(const std::string &what)
Definition: Log.hh:94
void custom(const std::string &what)
Definition: Log.hh:139
static const int debug
Definition: Log.hh:54
bool _print() const
Definition: Log.cc:268
void results(const std::string &what)
Definition: Log.hh:99
boost::chrono::steady_clock::time_point m_start_time
Definition: Log.hh:354
JustificationType justification()
Definition: Log.hh:240
void compiling(const std::string &what)
Definition: Log.hh:134
void begin_section()
Begin a section, without header.
Definition: Log.hh:158
std::ostream * m_ostream
Definition: Log.hh:358
Log & subsection()
Create a subsection.
Definition: Log.hh:186
void begin_lap()
Definition: Log.cc:47
int verbosity() const
Definition: Log.cc:55
friend Log & operator<<(Log &log, const T &msg_details)
Definition: Log.hh:394
Log & indent()
Definition: Log.hh:289
int m_verbosity
If m_verbosity >= required verbosity, then print.
Definition: Log.hh:338
void set(const std::string &what)
Definition: Log.hh:89
void decrease_indent_spaces(int n)
Definition: Log.hh:287
void begin(const std::string &what)
Definition: Log.hh:114
void generate(const std::string &what)
Definition: Log.hh:84
Log & verbatim(std::string text, bool indent_first_line=true)
Print verbatim, but with indentation (optional on first line)
Definition: Log.cc:201
void hide_clock()
Definition: Log.cc:39
void increase_indent()
Definition: Log.hh:277
void calculate(const std::string &what)
Definition: Log.hh:74
JustificationType m_justification
Definition: Log.hh:352
static const int verbose
Definition: Log.hh:53
void warning(const std::string &what)
Definition: Log.hh:124
void reset(std::ostream &_ostream=std::cout)
Definition: Log.cc:59
int m_indent_space
indent_str = m_indent_space*m_indent_level + m_indent_spaces
Definition: Log.hh:346
void error(const std::string &what)
Definition: Log.hh:129
void increase_indent_spaces(int n)
Definition: Log.hh:285
Log & paragraph(std::string text)
Print indented paragraph with wrapping at Log::width()
Definition: Log.cc:168
std::ostream & ostream()
Definition: Log.hh:262
void _print_full_justified_line(std::vector< std::string > &line, int curr_width)
Definition: Log.cc:142
void show_clock()
Definition: Log.cc:37
std::vector< int > m_required_verbosity
Definition: Log.hh:335
Log & verbatim_list(OutputIterator begin, OutputIterator end, std::string sep="- ")
Print a list.
Definition: Log.hh:377
void set_width(int width)
Definition: Log.hh:232
void set_justification(JustificationType justification)
Definition: Log.hh:236
int indent_space() const
Definition: Log.hh:271
Log & indent(const T &t)
Same as verbatim, but uses stringstream to convert to string first.
Definition: Log.hh:296
void construct(const std::string &what)
Definition: Log.hh:79
static const int standard
Definition: Log.hh:52
void decrease_indent()
Definition: Log.hh:279
int m_indent_level
Definition: Log.hh:347
int m_indent_spaces
Definition: Log.hh:348
double lap_time() const
Definition: Log.cc:49
double time_s() const
Definition: Log.cc:41
static std::pair< bool, int > verbosity_level(std::string s)
Read verbosity level from a string.
Definition: Log.cc:231
void _print_right_justified_line(std::vector< std::string > &line, int curr_width)
Definition: Log.cc:110
void _print_left_justified_line(std::vector< std::string > &line, int curr_width)
Definition: Log.cc:98
void restart_clock()
Definition: Log.cc:35
void write(const std::string &what)
Definition: Log.hh:109
void end(const std::string &what)
Definition: Log.hh:119
std::ostringstream & ss()
Definition: Log.hh:459
OStringStreamLog(int _verbosity=standard, bool _show_clock=false)
Construct a StringStreamLog.
Definition: Log.hh:454
const std::ostringstream & ss() const
Definition: Log.hh:461
std::ostringstream m_ss
Definition: Log.hh:461
ScopedLogging(Log &new_log, Log &new_err_log)
Definition: Log.hh:472
ScopedLogging m_logging
Definition: Log.hh:495
ScopedStringStreamLogging(int _verbosity=Log::standard, bool _show_clock=false)
Construct scoped StringStreamLog.
Definition: Log.hh:506
std::ostringstream & ss()
Definition: Log.hh:515
std::unique_ptr< ScopedLogging > m_logging
Definition: Log.hh:521
std::ostringstream & err_ss()
Definition: Log.hh:519
const std::ostringstream & err_ss() const
Definition: Log.hh:521
OStringStreamLog m_ss_log
Definition: Log.hh:525
OStringStreamLog m_ss_err_log
Definition: Log.hh:526
const std::ostringstream & ss() const
Definition: Log.hh:517
Base class for cloning.
#define CLONEABLE(T)
#define ABSTRACT_CLONEABLE(T)
Main CASM namespace.
Definition: APICommand.hh:8
std::ostream & operator<<(std::ostream &_stream, const FormattedPrintable &_formatted)
Log & cerr_log()
Definition: Log.hh:433
Log & log()
Definition: Log.hh:424
Log & null_log()
Definition: Log.hh:438
Log & cout_log()
Definition: Log.hh:428
JustificationType
Definition: Log.hh:17
Log & default_err_log()
Definition: Log.hh:419
Log & default_log()
Definition: Log.hh:414
Log & err_log()
Definition: Log.hh:426
Definition: stream_io.hh:24
virtual void print(Log &log) const override
Definition: Log.cc:10
std::string text
Definition: Log.hh:24
virtual void print(Log &log) const =0
bool indent_first_line
Definition: Log.hh:43
virtual void print(Log &log) const override
Definition: Log.cc:12