blob: 4572babb49192de720f4d4038217f65e37927a6f [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() {
16 static AbortHandlerT* handler = &std::abort;
17 return handler;
18}
19
20BENCHMARK_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.
27class CheckHandler {
28public:
29 CheckHandler(const char* check, const char* file, const char* func, int line)
30 : log_(GetErrorLogInstance())
31 {
32 log_ << file << ":" << line << ": " << func << ": Check `"
33 << check << "' failed. ";
34 }
35
36 std::ostream& GetLog() {
37 return log_;
38 }
39
40 BENCHMARK_NORETURN ~CheckHandler() BENCHMARK_NOEXCEPT_OP(false) {
41 log_ << std::endl;
42 CallAbortHandler();
43 }
44
45 CheckHandler & operator=(const CheckHandler&) = delete;
46 CheckHandler(const CheckHandler&) = delete;
47 CheckHandler() = delete;
48private:
49 std::ostream& log_;
50};
51
52} // end namespace internal
53} // end namespace benchmark
54
55// The CHECK macro returns a std::ostream object that can have extra information
56// written to it.
57#ifndef NDEBUG
58# define CHECK(b) (b ? ::benchmark::internal::GetNullLogInstance() \
59 : ::benchmark::internal::CheckHandler( \
60 #b, __FILE__, __func__, __LINE__).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#endif // CHECK_H_