1#ifndef BENCHMARK_LOG_H_
2#define BENCHMARK_LOG_H_
3
4#include <iostream>
5#include <ostream>
6
7#include "benchmark/benchmark.h"
8
9namespace benchmark {
10namespace internal {
11
12typedef std::basic_ostream<char>&(EndLType)(std::basic_ostream<char>&);
13
14class LogType {
15  friend LogType& GetNullLogInstance();
16  friend LogType& GetErrorLogInstance();
17
18  // FIXME: Add locking to output.
19  template <class Tp>
20  friend LogType& operator<<(LogType&, Tp const&);
21  friend LogType& operator<<(LogType&, EndLType*);
22
23 private:
24  LogType(std::ostream* out) : out_(out) {}
25  std::ostream* out_;
26  BENCHMARK_DISALLOW_COPY_AND_ASSIGN(LogType);
27};
28
29template <class Tp>
30LogType& operator<<(LogType& log, Tp const& value) {
31  if (log.out_) {
32    *log.out_ << value;
33  }
34  return log;
35}
36
37inline LogType& operator<<(LogType& log, EndLType* m) {
38  if (log.out_) {
39    *log.out_ << m;
40  }
41  return log;
42}
43
44inline int& LogLevel() {
45  static int log_level = 0;
46  return log_level;
47}
48
49inline LogType& GetNullLogInstance() {
50  static LogType log(nullptr);
51  return log;
52}
53
54inline LogType& GetErrorLogInstance() {
55  static LogType log(&std::clog);
56  return log;
57}
58
59inline LogType& GetLogInstanceForLevel(int level) {
60  if (level <= LogLevel()) {
61    return GetErrorLogInstance();
62  }
63  return GetNullLogInstance();
64}
65
66}  // end namespace internal
67}  // end namespace benchmark
68
69#define VLOG(x)                                                               \
70  (::benchmark::internal::GetLogInstanceForLevel(x) << "-- LOG(" << x << "):" \
71                                                                         " ")
72
73#endif
74