18 #define _QX_DEBUG_BREAK __debugbreak()
20 #define _QX_DEBUG_BREAK __builtin_debugtrap()
23 #define _QX_DEBUG_BREAK raise(SIGTRAP)
25 #define _QX_DEBUG_BREAK QX_EMPTY_MACRO
31 template<verbosity eVerbosity>
32 void resolve_assert_proceeding(
34 const category& fileCategory,
35 string_view svFunction,
38 string_view svCondition)
40 QX_LOGGER_INSTANCE.log(eVerbosity, QX_TEXT(
"[{}] "), fileCategory, svFile, svFunction, nLine, svCondition);
41 QX_LOGGER_INSTANCE.flush();
44 template<verbosity eVerbosity>
45 void resolve_assert_proceeding(
47 const category& fileCategory,
48 string_view svFunction,
51 string_view svCondition,
53 const category& category)
56 sMessage.append_format(QX_TEXT(
"[{}] "), svCondition);
57 QX_LOGGER_INSTANCE.log(eVerbosity, sMessage, category, svFile, svFunction, nLine);
58 QX_LOGGER_INSTANCE.flush();
61 template<verbosity eVerbosity,
class... args_t>
62 requires log_acceptable_args_c<args_t...>
63 void resolve_assert_proceeding(
65 const category& fileCategory,
66 string_view svFunction,
69 string_view svCondition,
71 format_string_strong_checks<args_t...> sFormat,
75 sMessage.append_format(QX_TEXT(
"[{}] "), svCondition);
76 sMessage.append_format(sFormat, std::forward<args_t>(args)...);
77 QX_LOGGER_INSTANCE.log(eVerbosity, sMessage, fileCategory, svFile, svFunction, nLine);
78 QX_LOGGER_INSTANCE.flush();
81 template<verbosity eVerbosity>
82 void resolve_assert_proceeding(
84 const category& fileCategory,
85 string_view svFunction,
88 string_view svCondition,
90 string_view svMessage)
93 sMessage.append_format(QX_TEXT(
"[{}] {}"), svCondition, svMessage);
94 QX_LOGGER_INSTANCE.log(eVerbosity, sMessage, fileCategory, svFile, svFunction, nLine);
95 QX_LOGGER_INSTANCE.flush();
98 template<verbosity eVerbosity,
class... args_t>
99 requires log_acceptable_args_c<args_t...>
100 void resolve_assert_proceeding(
102 const category& fileCategory,
103 string_view svFunction,
106 string_view svCondition,
108 const category& category,
109 format_string_strong_checks<args_t...> sFormat,
113 sMessage.append_format(QX_TEXT(
"[{}] "), svCondition);
114 sMessage.append_format(sFormat, std::forward<args_t>(args)...);
115 QX_LOGGER_INSTANCE.log(eVerbosity, sMessage, category, svFile, svFunction, nLine);
116 QX_LOGGER_INSTANCE.flush();
119 template<verbosity eVerbosity>
120 void resolve_assert_proceeding(
122 const category& fileCategory,
123 string_view svFunction,
126 string_view svCondition,
128 const category& category,
129 string_view svMessage)
132 sMessage.append_format(QX_TEXT(
"[{}] {}"), svCondition, svMessage);
133 QX_LOGGER_INSTANCE.log(eVerbosity, sMessage, category, svFile, svFunction, nLine);
134 QX_LOGGER_INSTANCE.flush();
141 #ifndef QX_DEBUG_BREAK
142 #define QX_DEBUG_BREAK _QX_DEBUG_BREAK
145 #ifndef QX_EXPECT_BEFORE_DEBUG_BREAK
146 #define QX_EXPECT_BEFORE_DEBUG_BREAK(condition, ...) \
147 qx::details::resolve_assert_proceeding<qx::verbosity::error>( \
148 QX_FILE_CATEGORY(), \
149 qx::to_string(__FUNCTION__), \
152 QX_TEXT(#condition), \
156 #ifndef QX_EXPECT_DEBUG_BREAK
157 #if QX_WITH_DEBUG_INFO
158 #define QX_EXPECT_DEBUG_BREAK QX_DEBUG_BREAK
160 #define QX_EXPECT_DEBUG_BREAK true
164 #ifndef QX_EXPECT_AFTER_DEBUG_BREAK
165 #define QX_EXPECT_AFTER_DEBUG_BREAK(condition, ...) true
168 #ifndef QX_ASSERT_BEFORE_DEBUG_BREAK
169 #define QX_ASSERT_BEFORE_DEBUG_BREAK(condition, ...) \
170 qx::details::resolve_assert_proceeding<qx::verbosity::critical>( \
171 QX_FILE_CATEGORY(), \
172 qx::to_string(__FUNCTION__), \
175 QX_TEXT(#condition), \
179 #ifndef QX_ASSERT_DEBUG_BREAK
180 #if QX_WITH_DEBUG_INFO
181 #define QX_ASSERT_DEBUG_BREAK QX_DEBUG_BREAK
183 #define QX_ASSERT_DEBUG_BREAK true
187 #ifndef QX_ASSERT_AFTER_DEBUG_BREAK
188 #define QX_ASSERT_AFTER_DEBUG_BREAK(condition, ...) std::terminate()
193 #define _QX_ASSERT(before_debug_break, debug_break, after_debug_break, condition, ...) \
194 (qx::predicates::is_valid(condition) \
195 || (before_debug_break(condition, ##__VA_ARGS__), \
197 after_debug_break(condition, ##__VA_ARGS__), \
200 #define _QX_ASSERT_CONTINUE(before_debug_break, debug_break, after_debug_break, condition, ...) \
201 if (!_QX_ASSERT(before_debug_break, debug_break, after_debug_break, condition, ##__VA_ARGS__)) [[unlikely]] \
206 #define _QX_ASSERT_BREAK(before_debug_break, debug_break, after_debug_break, condition, ...) \
207 if (!_QX_ASSERT(before_debug_break, debug_break, after_debug_break, condition, ##__VA_ARGS__)) [[unlikely]] \
212 #define _QX_ASSERT_RETURN( \
213 before_debug_break, \
220 if (!_QX_ASSERT(before_debug_break, debug_break, after_debug_break, condition, ##__VA_ARGS__)) [[unlikely]] \
221 return_keyword return_value; \
237 #define QX_ASSERT(condition, ...) \
239 QX_ASSERT_BEFORE_DEBUG_BREAK, \
240 QX_ASSERT_DEBUG_BREAK, \
241 QX_ASSERT_AFTER_DEBUG_BREAK, \
255 #define QX_EXPECT(condition, ...) \
257 QX_EXPECT_BEFORE_DEBUG_BREAK, \
258 QX_EXPECT_DEBUG_BREAK, \
259 QX_EXPECT_AFTER_DEBUG_BREAK, \
273 #define QX_EXPECT_CONTINUE(condition, ...) \
274 _QX_ASSERT_CONTINUE( \
275 QX_EXPECT_BEFORE_DEBUG_BREAK, \
276 QX_EXPECT_DEBUG_BREAK, \
277 QX_EXPECT_AFTER_DEBUG_BREAK, \
291 #define QX_EXPECT_BREAK(condition, ...) \
293 QX_EXPECT_BEFORE_DEBUG_BREAK, \
294 QX_EXPECT_DEBUG_BREAK, \
295 QX_EXPECT_AFTER_DEBUG_BREAK, \
310 #define QX_EXPECT_RETURN(condition, return_value, ...) \
312 QX_EXPECT_BEFORE_DEBUG_BREAK, \
313 QX_EXPECT_DEBUG_BREAK, \
314 QX_EXPECT_AFTER_DEBUG_BREAK, \
330 #define QX_EXPECT_RETURN_VOID(condition, ...) \
332 QX_EXPECT_BEFORE_DEBUG_BREAK, \
333 QX_EXPECT_DEBUG_BREAK, \
334 QX_EXPECT_AFTER_DEBUG_BREAK, \
351 #define QX_EXPECT_CO_RETURN(condition, return_value, ...) \
353 QX_EXPECT_BEFORE_DEBUG_BREAK, \
354 QX_EXPECT_DEBUG_BREAK, \
355 QX_EXPECT_AFTER_DEBUG_BREAK, \
371 #define QX_EXPECT_CO_RETURN_VOID(condition, ...) \
373 QX_EXPECT_BEFORE_DEBUG_BREAK, \
374 QX_EXPECT_DEBUG_BREAK, \
375 QX_EXPECT_AFTER_DEBUG_BREAK, \
384 #define QX_NO_ENTRY !QX_TEXT("No entry")
389 #define QX_NOT_IMPLEMENTED !QX_TEXT("Not implemented")
391 namespace qx::details
394 inline bool hit_once(
bool& bHit)
396 const bool bReturn = bHit;
411 #define QX_PREDICATE_HIT_ONCE() \
414 static bool h = false; \
415 return qx::details::hit_once(h); \
requires(same_variadic_args_v< args_t... >) const expr auto coalesce(args_t &&... args)
Coalesce function, C# a ?? b analogue.