1#ifndef CHECK_H_
2#define CHECK_H_
3
4#include <cstdlib>
5#include <ostream>
6#include <cmath>
7
8#include "internal_macros.h"
9#include "log.h"
10
11namespace benchmark {
12namespace internal {
13
14typedef void(AbortHandlerT)();
15
16inline AbortHandlerT*& GetAbortHandler() {
17  static AbortHandlerT* handler = &std::abort;
18  return handler;
19}
20
21BENCHMARK_NORETURN inline void CallAbortHandler() {
22  GetAbortHandler()();
23  std::abort();  // fallback to enforce noreturn
24}
25
26// CheckHandler is the class constructed by failing CHECK macros. CheckHandler
27// will log information about the failures and abort when it is destructed.
28class CheckHandler {
29 public:
30  CheckHandler(const char* check, const char* file, const char* func, int line)
31      : log_(GetErrorLogInstance()) {
32    log_ << file << ":" << line << ": " << func << ": Check `" << check
33         << "' failed. ";
34  }
35
36  LogType& GetLog() { return log_; }
37
38  BENCHMARK_NORETURN ~CheckHandler() BENCHMARK_NOEXCEPT_OP(false) {
39    log_ << std::endl;
40    CallAbortHandler();
41  }
42
43  CheckHandler& operator=(const CheckHandler&) = delete;
44  CheckHandler(const CheckHandler&) = delete;
45  CheckHandler() = delete;
46
47 private:
48  LogType& log_;
49};
50
51}  // end namespace internal
52}  // end namespace benchmark
53
54// The CHECK macro returns a std::ostream object that can have extra information
55// written to it.
56#ifndef NDEBUG
57#define CHECK(b)                                                             \
58  (b ? ::benchmark::internal::GetNullLogInstance()                           \
59     : ::benchmark::internal::CheckHandler(#b, __FILE__, __func__, __LINE__) \
60           .GetLog())
61#else
62#define CHECK(b) ::benchmark::internal::GetNullLogInstance()
63#endif
64
65#define CHECK_EQ(a, b) CHECK((a) == (b))
66#define CHECK_NE(a, b) CHECK((a) != (b))
67#define CHECK_GE(a, b) CHECK((a) >= (b))
68#define CHECK_LE(a, b) CHECK((a) <= (b))
69#define CHECK_GT(a, b) CHECK((a) > (b))
70#define CHECK_LT(a, b) CHECK((a) < (b))
71
72#define CHECK_FLOAT_EQ(a, b, eps) CHECK(std::fabs((a) - (b)) <  (eps))
73#define CHECK_FLOAT_NE(a, b, eps) CHECK(std::fabs((a) - (b)) >= (eps))
74#define CHECK_FLOAT_GE(a, b, eps) CHECK((a) - (b) > -(eps))
75#define CHECK_FLOAT_LE(a, b, eps) CHECK((b) - (a) > -(eps))
76#define CHECK_FLOAT_GT(a, b, eps) CHECK((a) - (b) >  (eps))
77#define CHECK_FLOAT_LT(a, b, eps) CHECK((b) - (a) >  (eps))
78
79#endif  // CHECK_H_
80