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