xref: /aosp_15_r20/external/google-benchmark/src/check.h (revision dbb99499c3810fa1611fa2242a2fc446be01a57c)
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