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 11 namespace benchmark { 12 namespace internal { 13 14 typedef void(AbortHandlerT)(); 15 16 inline AbortHandlerT*& GetAbortHandler() { 17 static AbortHandlerT* handler = &std::abort; 18 return handler; 19 } 20 21 BENCHMARK_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. 28 class 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