summaryrefslogtreecommitdiff
path: root/impl/Log.hpp
blob: 621c94c6fe178b53c5629d7cc7ffe55a097bfd42 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#ifndef LOG_HPP
#define LOG_HPP

// could not be hackier, but C++ is annoying
#define protected public
#include <streambuf>
#undef protected

#include <string>
#include <iostream>
#include <map>

namespace log {

  struct LoggerBuffer : public std::streambuf {
    LoggerBuffer(std::streambuf* buffer, const std::string& name)
      : _buffer(buffer),
        _prefix(name + ": "),
        _prefix_next(true) { }

    int_type overflow(int_type c=EOF) {
      if (_prefix_next) {
        _buffer->sputn(_prefix.c_str(), _prefix.length());
        _prefix_next = false;
      }
      if (c == '\n') {
        _prefix_next = true;
      }
      return _buffer->overflow(c);
    }
  private:
    std::streambuf* _buffer;
    std::string _prefix;
    bool _prefix_next;
  };

  struct Logger : public std::ostream {
    Logger(std::streambuf* buffer, const std::string& name)
      : std::ostream(NULL),
        _buffer(buffer, name) { }

    bool enabled() const {
      return rdbuf() != NULL;
    }

    bool enabled(bool v) {
      bool ret = enabled();
      rdbuf(v ? &_buffer : NULL);
      return ret;
    }

  private:
    LoggerBuffer _buffer;
  };

  Logger info(std::cout.rdbuf(), "info");
  Logger trace(std::cerr.rdbuf(), "trace");
  Logger strategy(std::cerr.rdbuf(), "strategy");
  Logger fixpoint(std::cerr.rdbuf(), "fixpoint");
  Logger debug(std::cerr.rdbuf(), "debug");

}

#endif