1#ifndef CHECK_H_ 2#define CHECK_H_ 3 4#include <cmath> 5#include <cstdlib> 6#include <ostream> 7 8#include "internal_macros.h" 9#include "log.h" 10 11namespace benchmark { 12namespace internal { 13 14typedef void(AbortHandlerT)(); 15 16inline AbortHandlerT*& GetAbortHandler() { 17 static AbortHandlerT* handler = &std::abort; 18 return handler; 19} 20 21BENCHMARK_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. 28class 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// clang-format off 66// preserve whitespacing between operators for alignment 67#define CHECK_EQ(a, b) CHECK((a) == (b)) 68#define CHECK_NE(a, b) CHECK((a) != (b)) 69#define CHECK_GE(a, b) CHECK((a) >= (b)) 70#define CHECK_LE(a, b) CHECK((a) <= (b)) 71#define CHECK_GT(a, b) CHECK((a) > (b)) 72#define CHECK_LT(a, b) CHECK((a) < (b)) 73 74#define CHECK_FLOAT_EQ(a, b, eps) CHECK(std::fabs((a) - (b)) < (eps)) 75#define CHECK_FLOAT_NE(a, b, eps) CHECK(std::fabs((a) - (b)) >= (eps)) 76#define CHECK_FLOAT_GE(a, b, eps) CHECK((a) - (b) > -(eps)) 77#define CHECK_FLOAT_LE(a, b, eps) CHECK((b) - (a) > -(eps)) 78#define CHECK_FLOAT_GT(a, b, eps) CHECK((a) - (b) > (eps)) 79#define CHECK_FLOAT_LT(a, b, eps) CHECK((b) - (a) > (eps)) 80//clang-format on 81 82#endif // CHECK_H_ 83