107 lines · c
1#ifndef CHECK_H_2#define CHECK_H_3 4#include <cmath>5#include <cstdlib>6#include <ostream>7 8#include "benchmark/export.h"9#include "internal_macros.h"10#include "log.h"11 12#if defined(__GNUC__) || defined(__clang__)13#define BENCHMARK_NOEXCEPT noexcept14#define BENCHMARK_NOEXCEPT_OP(x) noexcept(x)15#elif defined(_MSC_VER) && !defined(__clang__)16#if _MSC_VER >= 190017#define BENCHMARK_NOEXCEPT noexcept18#define BENCHMARK_NOEXCEPT_OP(x) noexcept(x)19#else20#define BENCHMARK_NOEXCEPT21#define BENCHMARK_NOEXCEPT_OP(x)22#endif23#define __func__ __FUNCTION__24#else25#define BENCHMARK_NOEXCEPT26#define BENCHMARK_NOEXCEPT_OP(x)27#endif28 29namespace benchmark {30namespace internal {31 32typedef void(AbortHandlerT)();33 34BENCHMARK_EXPORT35AbortHandlerT*& GetAbortHandler();36 37BENCHMARK_NORETURN inline void CallAbortHandler() {38 GetAbortHandler()();39 std::abort(); // fallback to enforce noreturn40}41 42// CheckHandler is the class constructed by failing BM_CHECK macros.43// CheckHandler will log information about the failures and abort when it is44// destructed.45class CheckHandler {46 public:47 CheckHandler(const char* check, const char* file, const char* func, int line)48 : log_(GetErrorLogInstance()) {49 log_ << file << ":" << line << ": " << func << ": Check `" << check50 << "' failed. ";51 }52 53 LogType& GetLog() { return log_; }54 55#if defined(COMPILER_MSVC)56#pragma warning(push)57#pragma warning(disable : 4722)58#endif59 BENCHMARK_NORETURN ~CheckHandler() BENCHMARK_NOEXCEPT_OP(false) {60 log_ << std::endl;61 CallAbortHandler();62 }63#if defined(COMPILER_MSVC)64#pragma warning(pop)65#endif66 67 CheckHandler& operator=(const CheckHandler&) = delete;68 CheckHandler(const CheckHandler&) = delete;69 CheckHandler() = delete;70 71 private:72 LogType& log_;73};74 75} // end namespace internal76} // end namespace benchmark77 78// The BM_CHECK macro returns a std::ostream object that can have extra79// information written to it.80#ifndef NDEBUG81#define BM_CHECK(b) \82 (b ? ::benchmark::internal::GetNullLogInstance() \83 : ::benchmark::internal::CheckHandler(#b, __FILE__, __func__, __LINE__) \84 .GetLog())85#else86#define BM_CHECK(b) ::benchmark::internal::GetNullLogInstance()87#endif88 89// clang-format off90// preserve whitespacing between operators for alignment91#define BM_CHECK_EQ(a, b) BM_CHECK((a) == (b))92#define BM_CHECK_NE(a, b) BM_CHECK((a) != (b))93#define BM_CHECK_GE(a, b) BM_CHECK((a) >= (b))94#define BM_CHECK_LE(a, b) BM_CHECK((a) <= (b))95#define BM_CHECK_GT(a, b) BM_CHECK((a) > (b))96#define BM_CHECK_LT(a, b) BM_CHECK((a) < (b))97 98#define BM_CHECK_FLOAT_EQ(a, b, eps) BM_CHECK(std::fabs((a) - (b)) < (eps))99#define BM_CHECK_FLOAT_NE(a, b, eps) BM_CHECK(std::fabs((a) - (b)) >= (eps))100#define BM_CHECK_FLOAT_GE(a, b, eps) BM_CHECK((a) - (b) > -(eps))101#define BM_CHECK_FLOAT_LE(a, b, eps) BM_CHECK((b) - (a) > -(eps))102#define BM_CHECK_FLOAT_GT(a, b, eps) BM_CHECK((a) - (b) > (eps))103#define BM_CHECK_FLOAT_LT(a, b, eps) BM_CHECK((b) - (a) > (eps))104//clang-format on105 106#endif // CHECK_H_107