• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef BENCHMARK_LOG_H_
2 #define BENCHMARK_LOG_H_
3 
4 #include <iostream>
5 #include <ostream>
6 
7 // NOTE: this is also defined in benchmark.h but we're trying to avoid a
8 // dependency.
9 // The _MSVC_LANG check should detect Visual Studio 2015 Update 3 and newer.
10 #if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
11 #define BENCHMARK_HAS_CXX11
12 #endif
13 
14 namespace benchmark {
15 namespace internal {
16 
17 typedef std::basic_ostream<char>&(EndLType)(std::basic_ostream<char>&);
18 
19 class LogType {
20   friend LogType& GetNullLogInstance();
21   friend LogType& GetErrorLogInstance();
22 
23   // FIXME: Add locking to output.
24   template <class Tp>
25   friend LogType& operator<<(LogType&, Tp const&);
26   friend LogType& operator<<(LogType&, EndLType*);
27 
28  private:
LogType(std::ostream * out)29   LogType(std::ostream* out) : out_(out) {}
30   std::ostream* out_;
31 
32   // NOTE: we could use BENCHMARK_DISALLOW_COPY_AND_ASSIGN but we shouldn't have
33   // a dependency on benchmark.h from here.
34 #ifndef BENCHMARK_HAS_CXX11
35   LogType(const LogType&);
36   LogType& operator=(const LogType&);
37 #else
38   LogType(const LogType&) = delete;
39   LogType& operator=(const LogType&) = delete;
40 #endif
41 };
42 
43 template <class Tp>
44 LogType& operator<<(LogType& log, Tp const& value) {
45   if (log.out_) {
46     *log.out_ << value;
47   }
48   return log;
49 }
50 
51 inline LogType& operator<<(LogType& log, EndLType* m) {
52   if (log.out_) {
53     *log.out_ << m;
54   }
55   return log;
56 }
57 
LogLevel()58 inline int& LogLevel() {
59   static int log_level = 0;
60   return log_level;
61 }
62 
GetNullLogInstance()63 inline LogType& GetNullLogInstance() {
64   static LogType null_log(static_cast<std::ostream*>(nullptr));
65   return null_log;
66 }
67 
GetErrorLogInstance()68 inline LogType& GetErrorLogInstance() {
69   static LogType error_log(&std::clog);
70   return error_log;
71 }
72 
GetLogInstanceForLevel(int level)73 inline LogType& GetLogInstanceForLevel(int level) {
74   if (level <= LogLevel()) {
75     return GetErrorLogInstance();
76   }
77   return GetNullLogInstance();
78 }
79 
80 }  // end namespace internal
81 }  // end namespace benchmark
82 
83 // clang-format off
84 #define BM_VLOG(x)                                                               \
85   (::benchmark::internal::GetLogInstanceForLevel(x) << "-- LOG(" << x << "):" \
86                                                                          " ")
87 // clang-format on
88 #endif
89