ZeroErr
Loading...
Searching...
No Matches
assert.h
Go to the documentation of this file.
1#pragma once
2
4
5#include "zeroerr/format.h"
8#include "zeroerr/print.h"
9
10#include <cstdint>
11#include <exception>
12
13
15
16
17// This macro will be redefined in the log.h header, so the global context variable could be
18// envolved only when we use log.h at the same time. If you didn't use log.h, this is still a
19// header-only library.
20#ifndef ZEROERR_G_CONTEXT_SCOPE
21#define ZEROERR_G_CONTEXT_SCOPE(x)
22#endif
23
24
34#ifndef ZEROERR_PRINT_ASSERT_DEFAULT_PRINTER
35#define ZEROERR_PRINT_ASSERT_DEFAULT_PRINTER(cond, level, ...) \
36 do { \
37 if (cond) { \
38 switch (zeroerr::assert_level::ZEROERR_CAT(level, _l)) { \
39 case zeroerr::assert_level::ZEROERR_WARN_l: \
40 zeroerr::getStderrPrinter().os << zeroerr::FgYellow << "WARN" << zeroerr::Reset; \
41 break; \
42 case zeroerr::assert_level::ZEROERR_ERROR_l: \
43 zeroerr::getStderrPrinter().os << zeroerr::FgRed << "ERROR" << zeroerr::Reset; \
44 break; \
45 case zeroerr::assert_level::ZEROERR_FATAL_l: \
46 zeroerr::getStderrPrinter().os << zeroerr::FgMagenta << "FATAL" << zeroerr::Reset; \
47 break; \
48 } \
49 zeroerr::getStderrPrinter().os << zeroerr::format(__VA_ARGS__) << '\n'; \
50 } \
51 } while (0)
52#endif
53
54// pattern is optional: call sites pass "" __VA_ARGS__ so empty message args still
55// provide a pattern token. ##__VA_ARGS__ drops the trailing comma when there are no
56// extra format arguments (required for clang/clangd; MSVC accepts the extension too).
57ZEROERR_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wgnu-zero-variadic-macro-arguments")
58#define ZEROERR_PRINT_ASSERT(cond, level, pattern, ...) \
59 ZEROERR_PRINT_ASSERT_DEFAULT_PRINTER(cond, level, " Assertion Failed:\n{msg}" pattern, \
60 assertion_data.log(), ##__VA_ARGS__)
62
63#define ZEROERR_ASSERT_EXP(cond, level, expect_throw, is_false, ...) \
64 ZEROERR_FUNC_SCOPE_BEGIN { \
65 zeroerr::assert_info info{zeroerr::assert_level::ZEROERR_CAT(level, _l), \
66 zeroerr::assert_throw::expect_throw, is_false}; \
67 \
68 zeroerr::AssertionData assertion_data(__FILE__, __LINE__, #cond, info); \
69 try { \
70 assertion_data.setResult(zeroerr::ExpressionDecomposer() << cond); \
71 } catch (const std::exception& e) { \
72 assertion_data.setException(e); \
73 } \
74 zeroerr::detail::context_helper< \
75 decltype(_ZEROERR_TEST_CONTEXT), \
76 std::is_same<decltype(_ZEROERR_TEST_CONTEXT), \
77 const bool>::value>::setContext(assertion_data, _ZEROERR_TEST_CONTEXT); \
78 ZEROERR_PRINT_ASSERT(assertion_data.passed == false, level, "" __VA_ARGS__); \
79 if (false) debug_break(); \
80 assertion_data(); \
81 ZEROERR_FUNC_SCOPE_RET(assertion_data.passed); \
82 } \
83 ZEROERR_FUNC_SCOPE_END
84
85
86#define ZEROERR_ASSERT_CMP(lhs, op, rhs, level, expect_throw, is_false, ...) \
87 ZEROERR_FUNC_SCOPE_BEGIN { \
88 zeroerr::assert_info info{zeroerr::assert_level::ZEROERR_CAT(level, _l), \
89 zeroerr::assert_throw::expect_throw, is_false}; \
90 \
91 zeroerr::Printer print; \
92 print.isQuoted = false; \
93 zeroerr::AssertionData assertion_data(__FILE__, __LINE__, #lhs " " #op " " #rhs, info); \
94 try { \
95 ZEROERR_SUPPRESS_COMPARE \
96 assertion_data.setResult(zeroerr::detail::makeComparisonLhs((lhs), print) op (rhs)); \
97 ZEROERR_SUPPRESS_COMPARE_POP \
98 } catch (const std::exception& e) { \
99 assertion_data.setException(e); \
100 } \
101 zeroerr::detail::context_helper< \
102 decltype(_ZEROERR_TEST_CONTEXT), \
103 std::is_same<decltype(_ZEROERR_TEST_CONTEXT), \
104 const bool>::value>::setContext(assertion_data, _ZEROERR_TEST_CONTEXT); \
105 ZEROERR_PRINT_ASSERT(assertion_data.passed == false, level, "" __VA_ARGS__); \
106 if (false) debug_break(); \
107 assertion_data(); \
108 ZEROERR_FUNC_SCOPE_RET(assertion_data.passed); \
109 } \
110 ZEROERR_FUNC_SCOPE_END
111
112
113#ifdef ZEROERR_NO_ASSERT
114
115#define CHECK(...)
116#define CHECK_NOT(...)
117#define CHECK_THROWS(...)
118#define REQUIRE(...)
119#define REQUIRE_NOT(...)
120#define REQUIRE_THROWS(...)
121#define ASSERT(...)
122#define ASSERT_NOT(...)
123#define ASSERT_THROWS(...)
124
125#define CHECK_EQ(...)
126#define CHECK_NE(...)
127#define CHECK_LT(...)
128#define CHECK_LE(...)
129#define CHECK_GT(...)
130#define CHECK_GE(...)
131
132#define REQUIRE_EQ(...)
133#define REQUIRE_NE(...)
134#define REQUIRE_LT(...)
135#define REQUIRE_LE(...)
136#define REQUIRE_GT(...)
137#define REQUIRE_GE(...)
138
139#define ASSERT_EQ(...)
140#define ASSERT_NE(...)
141#define ASSERT_LT(...)
142#define ASSERT_LE(...)
143#define ASSERT_GT(...)
144#define ASSERT_GE(...)
145
146#else
147// clang-format off
148ZEROERR_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wgnu-zero-variadic-macro-arguments")
149
150// Keep warning-only checks compatible by default. Consumers can opt into runner
151// failure accounting, including context-free helpers, before including zeroerr.
152#ifdef ZEROERR_CHECK_AS_ERROR
153#define ZEROERR_CHECK_LEVEL ZEROERR_ERROR
154#else
155#define ZEROERR_CHECK_LEVEL ZEROERR_WARN
156#endif
157#define ZEROERR_CHECK(cond, ...) ZEROERR_EXPAND(ZEROERR_ASSERT_EXP(cond, ZEROERR_CHECK_LEVEL, no_throw, false, __VA_ARGS__))
158#define ZEROERR_CHECK_NOT(cond, ...) ZEROERR_EXPAND(ZEROERR_ASSERT_EXP(cond, ZEROERR_CHECK_LEVEL, no_throw, true, __VA_ARGS__))
159#define ZEROERR_CHECK_THROWS(cond, ...) ZEROERR_EXPAND(ZEROERR_ASSERT_EXP(cond, ZEROERR_CHECK_LEVEL, throws, false, __VA_ARGS__))
160#define ZEROERR_REQUIRE(cond, ...) ZEROERR_EXPAND(ZEROERR_ASSERT_EXP(cond, ZEROERR_ERROR, no_throw, false, __VA_ARGS__))
161#define ZEROERR_REQUIRE_NOT(cond, ...) ZEROERR_EXPAND(ZEROERR_ASSERT_EXP(cond, ZEROERR_ERROR, no_throw, true, __VA_ARGS__))
162#define ZEROERR_REQUIRE_THROWS(cond, ...) ZEROERR_EXPAND(ZEROERR_ASSERT_EXP(cond, ZEROERR_ERROR, throws, false, __VA_ARGS__))
163#define ZEROERR_ASSERT(cond, ...) ZEROERR_EXPAND(ZEROERR_ASSERT_EXP(cond, ZEROERR_FATAL, no_throw, false, __VA_ARGS__))
164#define ZEROERR_ASSERT_NOT(cond, ...) ZEROERR_EXPAND(ZEROERR_ASSERT_EXP(cond, ZEROERR_FATAL, no_throw, true, __VA_ARGS__))
165#define ZEROERR_ASSERT_THROWS(cond, ...) ZEROERR_EXPAND(ZEROERR_ASSERT_EXP(cond, ZEROERR_FATAL, throws, false, __VA_ARGS__))
166
167#define CHECK(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_CHECK(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
168#define CHECK_NOT(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_CHECK_NOT(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
169#define CHECK_THROWS(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_CHECK_THROWS(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
170#define REQUIRE(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_REQUIRE(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
171#define REQUIRE_NOT(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_REQUIRE_NOT(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
172#define REQUIRE_THROWS(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_REQUIRE_THROWS(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
173#define ASSERT(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_ASSERT(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
174#define ASSERT_NOT(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_ASSERT_NOT(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
175#define ASSERT_THROWS(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_ASSERT_THROWS(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
176
177#define ZEROERR_CHECK_EQ(lhs, rhs, ...) ZEROERR_ASSERT_CMP(lhs, ==, rhs, ZEROERR_CHECK_LEVEL, no_throw, false, __VA_ARGS__)
178#define ZEROERR_CHECK_NE(lhs, rhs, ...) ZEROERR_ASSERT_CMP(lhs, !=, rhs, ZEROERR_CHECK_LEVEL, no_throw, false, __VA_ARGS__)
179#define ZEROERR_CHECK_LT(lhs, rhs, ...) ZEROERR_ASSERT_CMP(lhs, <, rhs, ZEROERR_CHECK_LEVEL, no_throw, false, __VA_ARGS__)
180#define ZEROERR_CHECK_LE(lhs, rhs, ...) ZEROERR_ASSERT_CMP(lhs, <=, rhs, ZEROERR_CHECK_LEVEL, no_throw, false, __VA_ARGS__)
181#define ZEROERR_CHECK_GT(lhs, rhs, ...) ZEROERR_ASSERT_CMP(lhs, >, rhs, ZEROERR_CHECK_LEVEL, no_throw, false, __VA_ARGS__)
182#define ZEROERR_CHECK_GE(lhs, rhs, ...) ZEROERR_ASSERT_CMP(lhs, >=, rhs, ZEROERR_CHECK_LEVEL, no_throw, false, __VA_ARGS__)
183
184#define ZEROERR_REQUIRE_EQ(lhs, rhs, ...) ZEROERR_ASSERT_CMP(lhs, ==, rhs, ZEROERR_ERROR, no_throw, false, __VA_ARGS__)
185#define ZEROERR_REQUIRE_NE(lhs, rhs, ...) ZEROERR_ASSERT_CMP(lhs, !=, rhs, ZEROERR_ERROR, no_throw, false, __VA_ARGS__)
186#define ZEROERR_REQUIRE_LT(lhs, rhs, ...) ZEROERR_ASSERT_CMP(lhs, <, rhs, ZEROERR_ERROR, no_throw, false, __VA_ARGS__)
187#define ZEROERR_REQUIRE_LE(lhs, rhs, ...) ZEROERR_ASSERT_CMP(lhs, <=, rhs, ZEROERR_ERROR, no_throw, false, __VA_ARGS__)
188#define ZEROERR_REQUIRE_GT(lhs, rhs, ...) ZEROERR_ASSERT_CMP(lhs, >, rhs, ZEROERR_ERROR, no_throw, false, __VA_ARGS__)
189#define ZEROERR_REQUIRE_GE(lhs, rhs, ...) ZEROERR_ASSERT_CMP(lhs, >=, rhs, ZEROERR_ERROR, no_throw, false, __VA_ARGS__)
190
191#define ZEROERR_ASSERT_EQ(lhs, rhs, ...) ZEROERR_ASSERT_CMP(lhs, ==, rhs, ZEROERR_FATAL, no_throw, false, __VA_ARGS__)
192#define ZEROERR_ASSERT_NE(lhs, rhs, ...) ZEROERR_ASSERT_CMP(lhs, !=, rhs, ZEROERR_FATAL, no_throw, false, __VA_ARGS__)
193#define ZEROERR_ASSERT_LT(lhs, rhs, ...) ZEROERR_ASSERT_CMP(lhs, <, rhs, ZEROERR_FATAL, no_throw, false, __VA_ARGS__)
194#define ZEROERR_ASSERT_LE(lhs, rhs, ...) ZEROERR_ASSERT_CMP(lhs, <=, rhs, ZEROERR_FATAL, no_throw, false, __VA_ARGS__)
195#define ZEROERR_ASSERT_GT(lhs, rhs, ...) ZEROERR_ASSERT_CMP(lhs, >, rhs, ZEROERR_FATAL, no_throw, false, __VA_ARGS__)
196#define ZEROERR_ASSERT_GE(lhs, rhs, ...) ZEROERR_ASSERT_CMP(lhs, >=, rhs, ZEROERR_FATAL, no_throw, false, __VA_ARGS__)
197
198#define CHECK_EQ(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_CHECK_EQ(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
199#define CHECK_NE(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_CHECK_NE(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
200#define CHECK_LT(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_CHECK_LT(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
201#define CHECK_LE(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_CHECK_LE(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
202#define CHECK_GT(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_CHECK_GT(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
203#define CHECK_GE(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_CHECK_GE(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
204#define REQUIRE_EQ(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_REQUIRE_EQ(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
205#define REQUIRE_NE(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_REQUIRE_NE(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
206#define REQUIRE_LT(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_REQUIRE_LT(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
207#define REQUIRE_LE(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_REQUIRE_LE(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
208#define REQUIRE_GT(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_REQUIRE_GT(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
209#define REQUIRE_GE(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_REQUIRE_GE(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
210#define ASSERT_EQ(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_ASSERT_EQ(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
211#define ASSERT_NE(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_ASSERT_NE(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
212#define ASSERT_LT(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_ASSERT_LT(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
213#define ASSERT_LE(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_ASSERT_LE(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
214#define ASSERT_GT(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_ASSERT_GT(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
215#define ASSERT_GE(...) ZEROERR_SUPPRESS_VARIADIC_MACRO ZEROERR_EXPAND(ZEROERR_ASSERT_GE(__VA_ARGS__)) ZEROERR_SUPPRESS_VARIADIC_MACRO_POP
216
218// clang-format on
219#endif
220
221
222// This symbol must be in the global namespace or anonymous namespace
223// used for checking the assert is inside testing or not
224namespace {
225constexpr bool _ZEROERR_TEST_CONTEXT = false;
226} // namespace
227
228
229namespace zeroerr {
230
232enum class assert_throw : uint8_t { no_throw, throws, throws_as };
233enum class assert_cmp : uint8_t { eq, ne, gt, ge, lt, le };
234
244
245
250struct AssertionData : std::exception {
251 const char* file; // file name
252 unsigned line; // line number
253 assert_info info; // assert info
254 bool passed; // if the assertion passed
255 zeroerr::String message; // the message of the assertion
256 zeroerr::String cond; // the condition of the assertion
257
258 AssertionData(const char* file, unsigned line, const char* cond, assert_info info)
259 : file(file), line(line), info(info) {
260 static zeroerr::String pattern = "zeroerr::ExpressionDecomposer() << ";
261 zeroerr::String cond_str(cond);
262 size_t pos = cond_str.find(pattern);
263 if (pos != zeroerr::String::npos) cond_str.replace(pos, pos + pattern.size(), "");
264 this->cond = cond_str;
265 }
266
267 void setResult(ExprResult&& result) {
268 ExprResult r(std::move(result));
269 if (info.is_false)
270 passed = !r.res;
271 else
272 passed = r.res;
273 message = r.decomp;
274 }
275
276 void setException(const std::exception& e) {
277 passed = info.throw_type == assert_throw::throws;
278 message = e.what();
279 }
280
284
285 // throw the exception
286 void operator()() {
287 if (passed) return;
288 if (shouldThrow()) throw *this;
289 }
290
292};
293
294namespace detail {
295// This struct is used for handle constexpr if in C++11
296// https://stackoverflow.com/questions/43587405/constexpr-if-alternative
297template <typename T, bool>
299
300template <typename T>
301struct context_helper<T, true> {
302 static void setContext(AssertionData& data, T) {
303 if (data.passed) return;
304 }
305};
306
307template <typename T>
308struct context_helper<T, false> {
309 static void setContext(AssertionData& data, T ctx) {
310 if (data.passed) {
311 ctx->passed_as++;
312 return;
313 }
314 switch (data.info.level) {
316 case assert_level::ZEROERR_ERROR_l: ctx->failed_as++; break;
317 case assert_level::ZEROERR_WARN_l: ctx->warning_as++; break;
318 }
319 }
320};
321} // namespace detail
322
323
324} // namespace zeroerr
325
Definition string.h:41
size_type size() const noexcept
Definition string.h:78
String & replace(size_type pos, size_type count, const String &text)
Definition string.cpp:132
static constexpr size_type npos
Definition string.h:47
size_type find(const String &text, size_type pos=0) const noexcept
Definition string.cpp:98
#define ZEROERR_SUPPRESS_COMMON_WARNINGS_POP
Definition config.h:283
#define ZEROERR_SUPPRESS_COMMON_WARNINGS_PUSH
Definition config.h:235
#define ZEROERR_CLANG_SUPPRESS_WARNING_WITH_PUSH(w)
Definition config.h:188
Definition assert.h:224
constexpr bool _ZEROERR_TEST_CONTEXT
Definition assert.h:225
zeroerr::String assertionText(const zeroerr::String &condition, const zeroerr::String &message, const char *file, unsigned line)
Definition assert_text.cpp:8
Definition assert_text.cpp:5
assert_throw
Definition assert.h:232
@ throws
Definition assert.h:232
@ throws_as
Definition assert.h:232
@ no_throw
Definition assert.h:232
assert_level
Definition assert.h:231
@ ZEROERR_FATAL_l
Definition assert.h:231
@ ZEROERR_ERROR_l
Definition assert.h:231
@ ZEROERR_WARN_l
Definition assert.h:231
assert_cmp
Definition assert.h:233
@ ge
Definition assert.h:233
@ gt
Definition assert.h:233
@ ne
Definition assert.h:233
@ le
Definition assert.h:233
@ lt
Definition assert.h:233
@ eq
Definition assert.h:233
AssertionData is a struct that contains all the information of an assertion. It will be thrown as an ...
Definition assert.h:250
assert_info info
Definition assert.h:253
const char * file
Definition assert.h:251
zeroerr::String message
Definition assert.h:255
zeroerr::String log()
Definition assert.h:281
void operator()()
Definition assert.h:286
void setResult(ExprResult &&result)
Definition assert.h:267
bool shouldThrow()
Definition assert.h:291
AssertionData(const char *file, unsigned line, const char *cond, assert_info info)
Definition assert.h:258
void setException(const std::exception &e)
Definition assert.h:276
bool passed
Definition assert.h:254
zeroerr::String cond
Definition assert.h:256
unsigned line
Definition assert.h:252
Definition decomposition.h:70
bool res
Definition decomposition.h:71
zeroerr::String decomp
Definition decomposition.h:72
This is a one-byte assert info struct, which is used to collect the meta info of an assertion.
Definition assert.h:239
assert_level level
Definition assert.h:240
assert_throw throw_type
Definition assert.h:241
bool is_false
Definition assert.h:242
static void setContext(AssertionData &data, T ctx)
Definition assert.h:309
static void setContext(AssertionData &data, T)
Definition assert.h:302
Definition assert.h:298