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()58inline int& LogLevel() { 59 static int log_level = 0; 60 return log_level; 61 } 62 GetNullLogInstance()63inline LogType& GetNullLogInstance() { 64 static LogType null_log(static_cast<std::ostream*>(nullptr)); 65 return null_log; 66 } 67 GetErrorLogInstance()68inline LogType& GetErrorLogInstance() { 69 static LogType error_log(&std::clog); 70 return error_log; 71 } 72 GetLogInstanceForLevel(int level)73inline 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