-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcheck.h
More file actions
104 lines (85 loc) · 3.7 KB
/
check.h
File metadata and controls
104 lines (85 loc) · 3.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#pragma once
#include <stdio.h>
#include <stdint.h>
#include <type_traits>
#include <ext/core/tracer.h>
#include <ext/error/exception.h>
#include <ext/error/dump_writer.h>
#include <ext/utils/call_once.h>
namespace ext::check {
struct CheckFailedException : ::ext::exception
{
explicit CheckFailedException(std::source_location&& source, const char* expression) noexcept
: exception(std::move(source), "", "CheckFailedException")
, m_expression(expression)
{}
[[nodiscard]] std::string external_text() const override { return "expression: '" + m_expression + "'"; }
template <class T>
CheckFailedException& operator<<(const T& data) { ::ext::exception::operator<<(data); return *this; }
std::string m_expression;
};
} // namespace ext::check
// Checks expression via check function, if check fails - throw exception
// Example: EXT_CHECK_RESULT(val, _result == 0, ::ext::check::CheckFailedException(std::source_location::current(), "Failed")) << "Text";
#define EXT_CHECK_RESULT(expr, check_func, exception) \
for (auto &&__result = (expr); !(check_func);) \
throw exception
// Checks boolean expression, in case of fail - throw CheckFailedException
// Example: EXT_CHECK(val == true) << "Check failed";
#define EXT_CHECK(bool_expression) \
EXT_CHECK_RESULT(bool_expression, !!(__result), ::ext::check::CheckFailedException(std::source_location::current(), #bool_expression))
/*
Checks expression via check function, if check fails:
* generate breakpoint if debugger present, otherwise - create dump.
* throw exception
Example:
EXT_EXPECT_RESULT(val, _result == 0, ::ext::check::CheckFailedException(std::source_location::current(), "Value check failed")) << "Check failed";
*/
#define EXT_EXPECT_RESULT(expr, check_func, exception) \
for (auto &&__result = (expr); !(check_func);) \
for (bool __firstEnter = true;; __firstEnter = false) \
if (__firstEnter && !::ext::dump::g_dumpGenerationDisabled) \
{ \
CALL_ONCE(DEBUG_BREAK_OR_CREATE_DUMP()) \
} \
else \
throw exception
/*
Checks boolean expression or HRESULT, if check fails:
* generate breakpoint if debugger present, otherwise - create dump.
* throw exception
Example:
EXT_EXPECT(val == true) << "Check failed";
*/
#define EXT_EXPECT(bool_expression) \
EXT_EXPECT_RESULT(bool_expression, !!(__result), ::ext::check::CheckFailedException(std::source_location::current(), #bool_expression))
/*
Checks boolean expression or HRESULT in DEBUG, if check fails:
* generate breakpoint if debugger present, otherwise - create dump.
* show error in log
Example:
EXT_ASSERT(val == true) << "Check failed";
*/
#ifdef _DEBUG
#define EXT_ASSERT(bool_expression) EXT_DUMP_IF(!(bool_expression))
#else
#define EXT_ASSERT(...) if (true) {} else EXT_TRACE_ERR()
#endif // _DEBUG
/* Unreachable code
*
* if (true) return;
* EXT_UNREACHABLE()
*/
#ifdef __GNUC__
#define EXT_UNREACHABLE(...) EXT_ASSERT(false) << EXT_TRACE_FUNCTION << "" __VA_ARGS__; __builtin_unreachable()
#else
#define EXT_UNREACHABLE(...) EXT_ASSERT(false) << EXT_TRACE_FUNCTION << "" __VA_ARGS__; __assume(0)
#endif
/*
Checks boolean expression or HRESULT, if check fails:
* generate breakpoint if debugger present, otherwise - create dump.
* throw exception
Example:
EXT_REQUIRE(MainInterface) << "No main interface";
*/
#define EXT_REQUIRE(bool_expression) EXT_ASSERT(bool_expression)