aboutsummaryrefslogtreecommitdiff
path: root/src/check.h
blob: 4572babb49192de720f4d4038217f65e37927a6f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#ifndef CHECK_H_
#define CHECK_H_

#include <cstdlib>
#include <ostream>

#include "internal_macros.h"
#include "log.h"

namespace benchmark {
namespace internal {

typedef void(AbortHandlerT)();

inline AbortHandlerT*& GetAbortHandler() {
    static AbortHandlerT* handler = &std::abort;
    return handler;
}

BENCHMARK_NORETURN inline void CallAbortHandler() {
    GetAbortHandler()();
    std::abort(); // fallback to enforce noreturn
}

// CheckHandler is the class constructed by failing CHECK macros. CheckHandler
// will log information about the failures and abort when it is destructed.
class CheckHandler {
public:
  CheckHandler(const char* check, const char* file, const char* func, int line)
    : log_(GetErrorLogInstance())
  {
    log_ << file << ":" << line << ": " << func << ": Check `"
          << check << "' failed. ";
  }

  std::ostream& GetLog() {
    return log_;
  }

  BENCHMARK_NORETURN ~CheckHandler() BENCHMARK_NOEXCEPT_OP(false) {
      log_ << std::endl;
      CallAbortHandler();
  }

  CheckHandler & operator=(const CheckHandler&) = delete;
  CheckHandler(const CheckHandler&) = delete;
  CheckHandler() = delete;
private:
  std::ostream& log_;
};

} // end namespace internal
} // end namespace benchmark

// The CHECK macro returns a std::ostream object that can have extra information
// written to it.
#ifndef NDEBUG
# define CHECK(b)  (b ? ::benchmark::internal::GetNullLogInstance()        \
                      : ::benchmark::internal::CheckHandler(               \
                          #b, __FILE__, __func__, __LINE__).GetLog())
#else
# define CHECK(b) ::benchmark::internal::GetNullLogInstance()
#endif

#define CHECK_EQ(a, b) CHECK((a) == (b))
#define CHECK_NE(a, b) CHECK((a) != (b))
#define CHECK_GE(a, b) CHECK((a) >= (b))
#define CHECK_LE(a, b) CHECK((a) <= (b))
#define CHECK_GT(a, b) CHECK((a) > (b))
#define CHECK_LT(a, b) CHECK((a) < (b))

#endif  // CHECK_H_