benchmark 1.10.0
Loading...
Searching...
No Matches
check.h
1#ifndef CHECK_H_
2#define CHECK_H_
3
4#include <cmath>
5#include <cstdlib>
6#include <ostream>
7#include <string_view>
8
9#include "benchmark/export.h"
10#include "internal_macros.h"
11#include "log.h"
12
13#if defined(__GNUC__) || defined(__clang__)
14#define BENCHMARK_NOEXCEPT noexcept
15#define BENCHMARK_NOEXCEPT_OP(x) noexcept(x)
16#elif defined(_MSC_VER) && !defined(__clang__)
17#if _MSC_VER >= 1900
18#define BENCHMARK_NOEXCEPT noexcept
19#define BENCHMARK_NOEXCEPT_OP(x) noexcept(x)
20#else
21#define BENCHMARK_NOEXCEPT
22#define BENCHMARK_NOEXCEPT_OP(x)
23#endif
24#define __func__ __FUNCTION__
25#else
26#define BENCHMARK_NOEXCEPT
27#define BENCHMARK_NOEXCEPT_OP(x)
28#endif
29
30namespace benchmark {
31namespace internal {
32
33typedef void(AbortHandlerT)();
34
35BENCHMARK_EXPORT
36AbortHandlerT*& GetAbortHandler();
37
38BENCHMARK_NORETURN inline void CallAbortHandler() {
39 GetAbortHandler()();
40 std::flush(std::cout);
41 std::flush(std::cerr);
42 std::abort(); // fallback to enforce noreturn
43}
44
45// CheckHandler is the class constructed by failing BM_CHECK macros.
46// CheckHandler will log information about the failures and abort when it is
47// destructed.
48class CheckHandler {
49 public:
50 CheckHandler(std::string_view check, std::string_view file,
51 std::string_view func, int line)
52 : log_(GetErrorLogInstance()) {
53 log_ << file << ":" << line << ": " << func << ": Check `" << check
54 << "' failed. ";
55 }
56
57 LogType& GetLog() { return log_; }
58
59#if defined(COMPILER_MSVC)
60#pragma warning(push)
61#pragma warning(disable : 4722)
62#endif
63 BENCHMARK_NORETURN ~CheckHandler() BENCHMARK_NOEXCEPT_OP(false) {
64 log_ << '\n';
65 CallAbortHandler();
66 }
67#if defined(COMPILER_MSVC)
68#pragma warning(pop)
69#endif
70
71 CheckHandler& operator=(const CheckHandler&) = delete;
72 CheckHandler(const CheckHandler&) = delete;
73 CheckHandler() = delete;
74
75 private:
76 LogType& log_;
77};
78
79} // end namespace internal
80} // end namespace benchmark
81
82// Like BM_CHECK, but enabled in every build configuration. Reserved for
83// invariants that are cheap enough to verify unconditionally and that must not
84// be violated silently in a release build.
85#define BM_CHECK_ALWAYS(b) \
86 (b ? ::benchmark::internal::GetNullLogInstance() \
87 : ::benchmark::internal::CheckHandler( \
88 std::string_view(#b), std::string_view(__FILE__), \
89 std::string_view(__func__), __LINE__) \
90 .GetLog())
91
92// The BM_CHECK macro returns a std::ostream object that can have extra
93// information written to it.
94#ifndef NDEBUG
95#define BM_CHECK(b) BM_CHECK_ALWAYS(b)
96#else
97#define BM_CHECK(b) ::benchmark::internal::GetNullLogInstance()
98#endif
99
100// clang-format off
101// preserve whitespacing between operators for alignment
102#define BM_CHECK_EQ(a, b) BM_CHECK((a) == (b))
103#define BM_CHECK_NE(a, b) BM_CHECK((a) != (b))
104#define BM_CHECK_GE(a, b) BM_CHECK((a) >= (b))
105#define BM_CHECK_LE(a, b) BM_CHECK((a) <= (b))
106#define BM_CHECK_GT(a, b) BM_CHECK((a) > (b))
107#define BM_CHECK_LT(a, b) BM_CHECK((a) < (b))
108
109#define BM_CHECK_FLOAT_EQ(a, b, eps) BM_CHECK(std::fabs((a) - (b)) < (eps))
110#define BM_CHECK_FLOAT_NE(a, b, eps) BM_CHECK(std::fabs((a) - (b)) >= (eps))
111#define BM_CHECK_FLOAT_GE(a, b, eps) BM_CHECK((a) - (b) > -(eps))
112#define BM_CHECK_FLOAT_LE(a, b, eps) BM_CHECK((b) - (a) > -(eps))
113#define BM_CHECK_FLOAT_GT(a, b, eps) BM_CHECK((a) - (b) > (eps))
114#define BM_CHECK_FLOAT_LT(a, b, eps) BM_CHECK((b) - (a) > (eps))
115//clang-format on
116
117#endif // CHECK_H_
Definition log.h:12