Home | History | Annotate | Download | only in src
      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