57 const char*
function);
63 const char*
function) noexcept;
128 #if defined(__GNUC__) || defined(__clang__)
133 #elif defined(_MSC_VER)
185 if (handler ==
nullptr) {
188 _assertion_handler.store(handler, std::memory_order_release);
201 return _assertion_handler.load(std::memory_order_acquire);
226 #if defined(_WIN32) || defined(_WIN64)
228 #if defined(_MSC_VER)
230 #elif defined(__GNUC__) || defined(__clang__)
237 #elif defined(__i386__) || defined(__x86_64__)
239 #if defined(__GNUC__) || defined(__clang__)
240 __asm__
volatile(
"int3");
245 #elif defined(__aarch64__) || defined(__arm__)
247 #if defined(__GNUC__) || defined(__clang__)
254 #if defined(__GNUC__) || defined(__clang__)
288 #if defined(__GNUC__) || defined(__clang__)
289 __builtin_unreachable();
290 #elif defined(_MSC_VER)
315 [[noreturn]]
static void abort(
const char* message =
nullptr) noexcept {
316 if (message !=
nullptr) {
317 std::cerr <<
"Program terminated: " << message << std::endl;
319 std::cerr <<
"Program terminated by DebugUtils::abort()" << std::endl;
346 #if defined(_WIN32) && defined(_MSC_VER)
349 #elif defined(__GNUC__) || defined(__clang__)
351 #if defined(__GLIBC__) || defined(__APPLE__) || defined(__FreeBSD__)
381 std::cerr <<
"Stack trace not available on this platform" << std::endl;
386 #if defined(_WIN32) && defined(_MSC_VER)
387 printStackTraceWindows();
388 #elif defined(__GNUC__) || defined(__clang__)
389 #if defined(__GLIBC__) || defined(__APPLE__) || defined(__FreeBSD__)
390 printStackTraceUnix();
392 std::cerr <<
"Stack trace not implemented for this Unix variant" << std::endl;
395 std::cerr <<
"Stack trace not implemented for this platform" << std::endl;
405 static std::atomic<AssertionHandler> _assertion_handler;
413 #if defined(_WIN32) && defined(_MSC_VER)
414 static void printStackTraceWindows() noexcept {
417 std::cerr <<
"Windows stack trace would be printed here" << std::endl;
418 std::cerr <<
"(StackWalk64 implementation not included in this example)" << std::endl;
428 #if defined(__GNUC__) || defined(__clang__)
429 #if defined(__GLIBC__) || defined(__APPLE__) || defined(__FreeBSD__)
430 static void printStackTraceUnix() noexcept {
433 std::cerr <<
"Unix stack trace would be printed here" << std::endl;
434 std::cerr <<
"(backtrace() implementation not included in this example)" << std::endl;
464 const char*
function) noexcept {
465 std::cerr <<
"\n" << std::string(60,
'=') <<
"\n";
466 std::cerr <<
"ASSERTION FAILED\n";
467 std::cerr << std::string(60,
'=') <<
"\n";
468 std::cerr <<
"Expression: " << expression <<
"\n";
469 std::cerr <<
"File: " << file <<
"\n";
470 std::cerr <<
"Line: " << line <<
"\n";
471 std::cerr <<
"Function: " <<
function <<
"\n";
472 std::cerr << std::string(60,
'=') <<
"\n";
476 std::cerr <<
"\nStack trace:\n";
481 std::cerr <<
"Program will now terminate.\n" << std::endl;
512 #define TRLC_DEBUG_BUILD 0
514 #define TRLC_DEBUG_BUILD 1
536 #define TRLC_ASSERT(expr) \
538 : trlc::platform::DebugUtils::getAssertionHandler()( \
539 #expr, __FILE__, __LINE__, __func__))
541 #define TRLC_ASSERT(expr) ((void)0)
560 #define TRLC_DEBUG_ONLY(code) code
562 #define TRLC_DEBUG_ONLY(code) ((void)0)
585 #ifdef TRLC_UNREACHABLE
586 #undef TRLC_UNREACHABLE
588 #define TRLC_UNREACHABLE() trlc::platform::DebugUtils::unreachable()
605 #define TRLC_ABORT(msg) trlc::platform::DebugUtils::abort(msg)
623 #if defined(_MSC_VER)
625 #define TRLC_DEBUG_BREAK() __debugbreak()
626 #elif defined(__GNUC__) || defined(__clang__)
628 #if defined(__i386__) || defined(__x86_64__)
630 #define TRLC_DEBUG_BREAK() __asm__ volatile("int3")
633 #define TRLC_DEBUG_BREAK() __builtin_trap()
637 #define TRLC_DEBUG_BREAK() trlc::platform::DebugUtils::debugBreak()
646 "Debug and release build detection must be mutually exclusive");
651 "TRLC_DEBUG_BUILD macro should match isDebugBuild() function");
654 "TRLC_DEBUG_BUILD macro should match build detection functions");
659 void (*)(
const char*,
const char*,
int,
const char*)>,
660 "AssertionHandler type signature must match specification");