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()44inline int& LogLevel() { 45 static int log_level = 0; 46 return log_level; 47 } 48 GetNullLogInstance()49inline LogType& GetNullLogInstance() { 50 static LogType log(nullptr); 51 return log; 52 } 53 GetErrorLogInstance()54inline LogType& GetErrorLogInstance() { 55 static LogType log(&std::clog); 56 return log; 57 } 58 GetLogInstanceForLevel(int level)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 // clang-format off 70 #define BM_VLOG(x) \ 71 (::benchmark::internal::GetLogInstanceForLevel(x) << "-- LOG(" << x << "):" \ 72 " ") 73 // clang-format on 74 #endif 75