benchmark  1.9.4
check.h
1 #ifndef CHECK_H_
2 #define CHECK_H_
3 
4 #include <cmath>
5 #include <cstdlib>
6 #include <ostream>
7 #include <string_view>
8 
9 #include "benchmark/export.h"
10 #include "internal_macros.h"
11 #include "log.h"
12 
13 #if defined(__GNUC__) || defined(__clang__)
14 #define BENCHMARK_NOEXCEPT noexcept
15 #define BENCHMARK_NOEXCEPT_OP(x) noexcept(x)
16 #elif defined(_MSC_VER) && !defined(__clang__)
17 #if _MSC_VER >= 1900
18 #define BENCHMARK_NOEXCEPT noexcept
19 #define BENCHMARK_NOEXCEPT_OP(x) noexcept(x)
20 #else
21 #define BENCHMARK_NOEXCEPT
22 #define BENCHMARK_NOEXCEPT_OP(x)
23 #endif
24 #define __func__ __FUNCTION__
25 #else
26 #define BENCHMARK_NOEXCEPT
27 #define BENCHMARK_NOEXCEPT_OP(x)
28 #endif
29 
30 namespace benchmark {
31 namespace internal {
32 
33 typedef void(AbortHandlerT)();
34 
35 BENCHMARK_EXPORT
36 AbortHandlerT*& GetAbortHandler();
37 
38 BENCHMARK_NORETURN inline void CallAbortHandler() {
39  GetAbortHandler()();
40  std::flush(std::cout);
41  std::flush(std::cerr);
42  std::abort(); // fallback to enforce noreturn
43 }
44 
45 // CheckHandler is the class constructed by failing BM_CHECK macros.
46 // CheckHandler will log information about the failures and abort when it is
47 // destructed.
48 class CheckHandler {
49  public:
50  CheckHandler(std::string_view check, std::string_view file,
51  std::string_view func, int line)
52  : log_(GetErrorLogInstance()) {
53  log_ << file << ":" << line << ": " << func << ": Check `" << check
54  << "' failed. ";
55  }
56 
57  LogType& GetLog() { return log_; }
58 
59 #if defined(COMPILER_MSVC)
60 #pragma warning(push)
61 #pragma warning(disable : 4722)
62 #endif
63  BENCHMARK_NORETURN ~CheckHandler() BENCHMARK_NOEXCEPT_OP(false) {
64  log_ << '\n';
65  CallAbortHandler();
66  }
67 #if defined(COMPILER_MSVC)
68 #pragma warning(pop)
69 #endif
70 
71  CheckHandler& operator=(const CheckHandler&) = delete;
72  CheckHandler(const CheckHandler&) = delete;
73  CheckHandler() = delete;
74 
75  private:
76  LogType& log_;
77 };
78 
79 } // end namespace internal
80 } // end namespace benchmark
81 
82 // The BM_CHECK macro returns a std::ostream object that can have extra
83 // information written to it.
84 #ifndef NDEBUG
85 #define BM_CHECK(b) \
86  (b ? ::benchmark::internal::GetNullLogInstance() \
87  : ::benchmark::internal::CheckHandler( \
88  std::string_view(#b), std::string_view(__FILE__), \
89  std::string_view(__func__), __LINE__) \
90  .GetLog())
91 #else
92 #define BM_CHECK(b) ::benchmark::internal::GetNullLogInstance()
93 #endif
94 
95 // clang-format off
96 // preserve whitespacing between operators for alignment
97 #define BM_CHECK_EQ(a, b) BM_CHECK((a) == (b))
98 #define BM_CHECK_NE(a, b) BM_CHECK((a) != (b))
99 #define BM_CHECK_GE(a, b) BM_CHECK((a) >= (b))
100 #define BM_CHECK_LE(a, b) BM_CHECK((a) <= (b))
101 #define BM_CHECK_GT(a, b) BM_CHECK((a) > (b))
102 #define BM_CHECK_LT(a, b) BM_CHECK((a) < (b))
103 
104 #define BM_CHECK_FLOAT_EQ(a, b, eps) BM_CHECK(std::fabs((a) - (b)) < (eps))
105 #define BM_CHECK_FLOAT_NE(a, b, eps) BM_CHECK(std::fabs((a) - (b)) >= (eps))
106 #define BM_CHECK_FLOAT_GE(a, b, eps) BM_CHECK((a) - (b) > -(eps))
107 #define BM_CHECK_FLOAT_LE(a, b, eps) BM_CHECK((b) - (a) > -(eps))
108 #define BM_CHECK_FLOAT_GT(a, b, eps) BM_CHECK((a) - (b) > (eps))
109 #define BM_CHECK_FLOAT_LT(a, b, eps) BM_CHECK((b) - (a) > (eps))
110 //clang-format on
111 
112 #endif // CHECK_H_
Definition: check.h:48
Definition: log.h:12