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 14namespace benchmark { 15namespace internal { 16 17typedef std::basic_ostream<char>&(EndLType)(std::basic_ostream<char>&); 18 19class 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: 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 43template <class Tp> 44LogType& operator<<(LogType& log, Tp const& value) { 45 if (log.out_) { 46 *log.out_ << value; 47 } 48 return log; 49} 50 51inline LogType& operator<<(LogType& log, EndLType* m) { 52 if (log.out_) { 53 *log.out_ << m; 54 } 55 return log; 56} 57 58inline int& LogLevel() { 59 static int log_level = 0; 60 return log_level; 61} 62 63inline LogType& GetNullLogInstance() { 64 static LogType null_log(static_cast<std::ostream*>(nullptr)); 65 return null_log; 66} 67 68inline LogType& GetErrorLogInstance() { 69 static LogType error_log(&std::clog); 70 return error_log; 71} 72 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