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