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.