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

source code of third-party/benchmark/src/check.h