blob: 6f1fe0cf860cd5f03cc6a7a645d4dbb3e8874e72 [file] [log] [blame]
Eric Fiselierb08d8b12016-07-19 23:07:03 +00001#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
10namespace benchmark {
11namespace internal {
12
13typedef void(AbortHandlerT)();
14
15inline AbortHandlerT*& GetAbortHandler() {
Eric Fiselierfbc9ff22016-11-05 00:30:27 +000016 static AbortHandlerT* handler = &std::abort;
17 return handler;
Eric Fiselierb08d8b12016-07-19 23:07:03 +000018}
19
20BENCHMARK_NORETURN inline void CallAbortHandler() {
Eric Fiselierfbc9ff22016-11-05 00:30:27 +000021 GetAbortHandler()();
22 std::abort(); // fallback to enforce noreturn
Eric Fiselierb08d8b12016-07-19 23:07:03 +000023}
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.
27class CheckHandler {
Eric Fiselierfbc9ff22016-11-05 00:30:27 +000028 public:
Eric Fiselierb08d8b12016-07-19 23:07:03 +000029 CheckHandler(const char* check, const char* file, const char* func, int line)
Eric Fiselierfbc9ff22016-11-05 00:30:27 +000030 : log_(GetErrorLogInstance()) {
31 log_ << file << ":" << line << ": " << func << ": Check `" << check
32 << "' failed. ";
Eric Fiselierb08d8b12016-07-19 23:07:03 +000033 }
34
Eric Fiselierfbc9ff22016-11-05 00:30:27 +000035 LogType& GetLog() { return log_; }
Eric Fiselierb08d8b12016-07-19 23:07:03 +000036
37 BENCHMARK_NORETURN ~CheckHandler() BENCHMARK_NOEXCEPT_OP(false) {
Eric Fiselierfbc9ff22016-11-05 00:30:27 +000038 log_ << std::endl;
39 CallAbortHandler();
Eric Fiselierb08d8b12016-07-19 23:07:03 +000040 }
41
Eric Fiselierfbc9ff22016-11-05 00:30:27 +000042 CheckHandler& operator=(const CheckHandler&) = delete;
Eric Fiselierb08d8b12016-07-19 23:07:03 +000043 CheckHandler(const CheckHandler&) = delete;
44 CheckHandler() = delete;
Eric Fiselierfbc9ff22016-11-05 00:30:27 +000045
46 private:
47 LogType& log_;
Eric Fiselierb08d8b12016-07-19 23:07:03 +000048};
49
Eric Fiselierfbc9ff22016-11-05 00:30:27 +000050} // end namespace internal
51} // end namespace benchmark
Eric Fiselierb08d8b12016-07-19 23:07:03 +000052
53// The CHECK macro returns a std::ostream object that can have extra information
54// written to it.
55#ifndef NDEBUG
Eric Fiselierfbc9ff22016-11-05 00:30:27 +000056#define CHECK(b) \
57 (b ? ::benchmark::internal::GetNullLogInstance() \
58 : ::benchmark::internal::CheckHandler(#b, __FILE__, __func__, __LINE__) \
59 .GetLog())
Eric Fiselierb08d8b12016-07-19 23:07:03 +000060#else
Eric Fiselierfbc9ff22016-11-05 00:30:27 +000061#define CHECK(b) ::benchmark::internal::GetNullLogInstance()
Eric Fiselierb08d8b12016-07-19 23:07:03 +000062#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_