1 #ifndef CHECK_H_ 2 #define CHECK_H_ 3 4 #include <cstdlib> 5 #include <ostream> 6 7 #include "internal_macros.h" 8 #include "log.h" 9 10 namespace benchmark { 11 namespace internal { 12 13 typedef void(AbortHandlerT)(); 14 15 inline AbortHandlerT*& GetAbortHandler() { 16 static AbortHandlerT* handler = &std::abort; 17 return handler; 18 } 19 20 BENCHMARK_NORETURN inline void CallAbortHandler() { 21 GetAbortHandler()(); 22 std::abort(); // fallback to enforce noreturn 23 } 24 25 // CheckHandler is the class constructed by failing CHECK macros. CheckHandler 26 // will log information about the failures and abort when it is destructed. 27 class CheckHandler { 28 public: 29 CheckHandler(const char* check, const char* file, const char* func, int line) 30 : log_(GetErrorLogInstance()) { 31 log_ << file << ":" << line << ": " << func << ": Check `" << check 32 << "' failed. "; 33 } 34 35 LogType& GetLog() { return log_; } 36 37 BENCHMARK_NORETURN ~CheckHandler() BENCHMARK_NOEXCEPT_OP(false) { 38 log_ << std::endl; 39 CallAbortHandler(); 40 } 41 42 CheckHandler& operator=(const CheckHandler&) = delete; 43 CheckHandler(const CheckHandler&) = delete; 44 CheckHandler() = delete; 45 46 private: 47 LogType& log_; 48 }; 49 50 } // end namespace internal 51 } // end namespace benchmark 52 53 // The CHECK macro returns a std::ostream object that can have extra information 54 // written to it. 55 #ifndef NDEBUG 56 #define CHECK(b) \ 57 (b ? ::benchmark::internal::GetNullLogInstance() \ 58 : ::benchmark::internal::CheckHandler(#b, __FILE__, __func__, __LINE__) \ 59 .GetLog()) 60 #else 61 #define CHECK(b) ::benchmark::internal::GetNullLogInstance() 62 #endif 63 64 #define CHECK_EQ(a, b) CHECK((a) == (b)) 65 #define CHECK_NE(a, b) CHECK((a) != (b)) 66 #define CHECK_GE(a, b) CHECK((a) >= (b)) 67 #define CHECK_LE(a, b) CHECK((a) <= (b)) 68 #define CHECK_GT(a, b) CHECK((a) > (b)) 69 #define CHECK_LT(a, b) CHECK((a) < (b)) 70 71 #endif // CHECK_H_ 72