1 #ifndef BENCHMARK_LOG_H_
2 #define BENCHMARK_LOG_H_
3 
4 #include <iostream>
5 #include <ostream>
6 
7 #include "benchmark/benchmark.h"
8 
9 namespace benchmark {
10 namespace internal {
11 
12 typedef std::basic_ostream<char>&(EndLType)(std::basic_ostream<char>&);
13 
14 class 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:
LogType(std::ostream * out)24   LogType(std::ostream* out) : out_(out) {}
25   std::ostream* out_;
26   BENCHMARK_DISALLOW_COPY_AND_ASSIGN(LogType);
27 };
28 
29 template <class Tp>
30 LogType& operator<<(LogType& log, Tp const& value) {
31   if (log.out_) {
32     *log.out_ << value;
33   }
34   return log;
35 }
36 
37 inline LogType& operator<<(LogType& log, EndLType* m) {
38   if (log.out_) {
39     *log.out_ << m;
40   }
41   return log;
42 }
43 
LogLevel()44 inline int& LogLevel() {
45   static int log_level = 0;
46   return log_level;
47 }
48 
GetNullLogInstance()49 inline LogType& GetNullLogInstance() {
50   static LogType log(nullptr);
51   return log;
52 }
53 
GetErrorLogInstance()54 inline LogType& GetErrorLogInstance() {
55   static LogType log(&std::clog);
56   return log;
57 }
58 
GetLogInstanceForLevel(int level)59 inline 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 // clang-format off
70 #define VLOG(x)                                                               \
71   (::benchmark::internal::GetLogInstanceForLevel(x) << "-- LOG(" << x << "):" \
72                                                                          " ")
73 // clang-format on
74 #endif
75