1d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#ifndef BENCHMARK_LOG_H_
2d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#define BENCHMARK_LOG_H_
3d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier
4d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier#include <iostream>
5d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#include <ostream>
6d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier
7d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier#include "benchmark/macros.h"
8d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier
9d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiseliernamespace benchmark {
10d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiseliernamespace internal {
11d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier
12d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiseliertypedef std::basic_ostream<char>&(EndLType)(std::basic_ostream<char>&);
13d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier
14d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselierclass LogType {
15d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  friend LogType& GetNullLogInstance();
16d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  friend LogType& GetErrorLogInstance();
17d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier
18d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  // FIXME: Add locking to output.
19d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  template <class Tp>
20d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  friend LogType& operator<<(LogType&, Tp const&);
21d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  friend LogType& operator<<(LogType&, EndLType*);
22d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier
23d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier private:
24d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  LogType(std::ostream* out) : out_(out) {}
25d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  std::ostream* out_;
26d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  BENCHMARK_DISALLOW_COPY_AND_ASSIGN(LogType);
27d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier};
28d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier
29d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiseliertemplate <class Tp>
30d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric FiselierLogType& operator<<(LogType& log, Tp const& value) {
31d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  if (log.out_) {
32d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier    *log.out_ << value;
33d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  }
34d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  return log;
35d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier}
36d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier
37d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselierinline LogType& operator<<(LogType& log, EndLType* m) {
38d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  if (log.out_) {
39d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier    *log.out_ << m;
40d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  }
41d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  return log;
42d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier}
43d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier
44d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselierinline int& LogLevel() {
45d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  static int log_level = 0;
46d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  return log_level;
47d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier}
48d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier
49d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselierinline LogType& GetNullLogInstance() {
50d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  static LogType log(nullptr);
51d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  return log;
52d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier}
53d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier
54d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselierinline LogType& GetErrorLogInstance() {
55d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  static LogType log(&std::clog);
56d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  return log;
57d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier}
58d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier
59d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselierinline LogType& GetLogInstanceForLevel(int level) {
60d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  if (level <= LogLevel()) {
61d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier    return GetErrorLogInstance();
62d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier  }
63d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier  return GetNullLogInstance();
64d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier}
65d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier
66d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier}  // end namespace internal
67d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier}  // end namespace benchmark
68d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier
69d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier#define VLOG(x)                                                               \
70d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier  (::benchmark::internal::GetLogInstanceForLevel(x) << "-- LOG(" << x << "):" \
71d87eb99b8071fbd5af4d6d04ac864ada752e24bcEric Fiselier                                                                         " ")
72d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier
73d9b9ef75a8ada5f9caaf2f4984bfb8094ade2590Eric Fiselier#endif