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