AuroraRuntime/Include/Aurora/Debug/SysAssertions.hpp

264 lines
7.8 KiB
C++

/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: SysAssertions.hpp
Date: 2021-7-14
Author: Reece
***/
//#pragma once <- AURORA_NO_ASSERTIONS may be redefined. do not cache
// AURORA_ASSERTIONS_FORCE_EXPRESSIONS < "Exp" suffix by default
// AURORA_ASSERTIONS_FORCE_SHIP < emulate ship build
// AURORA_ASSERTIONS_NO_EXPRESSIONS < forces expression strings to be stripped no matter the path
#if defined(AURORA_ASSERTIONS_NO_EXPRESSIONS_UNDER_SHIP)
#if defined(AU_CFG_ID_SHIP) || defined(AURORA_ASSERTIONS_FORCE_SHIP)
#define AURORA_ASSERTIONS_NO_EXPRESSIONS
#endif
#endif
#if defined(AURORA_ASSERTIONS_NO_EXPRESSIONS)
#define _AUKCON_STRINGIFY_X2(...)
#else
#define _AUKCON_STRINGIFY_X2 _AUKCON_STRINGIFY_X
#endif
#if !defined(AURORA_NO_ASSERTIONS) && !defined(AURORA_ASSERTIONS_NONE)
// defines SysAssert and SysAssertDbg
#if !(defined(AU_CFG_ID_SHIP) || defined(AURORA_ASSERTIONS_FORCE_SHIP))
/// @private
template<typename ... T>
static auline void SysAssertFileEx(const char *file, int fileno, const char *func, bool tru,
fmt::format_string<T...> msg, T&& ... args)
{
if (tru)
{
return;
}
Aurora::Logging::WriteLinef(
static_cast<AuUInt8>(Aurora::Logging::ELogLevel::eError),
Aurora::Console::EAnsiColor::eBoldRed,
"Fatal",
"Expression address: {} {}:{}", func, file, fileno);
SysPanic2<T...>(fileno, msg, AuForward<T>(args)...);
}
template<typename ... T>
static auline void SysAssertFileEx(const char *file, int fileno, const char *func, bool tru)
{
if (tru)
{
return;
}
Aurora::Logging::WriteLinef(
static_cast<AuUInt8>(Aurora::Logging::ELogLevel::eError),
Aurora::Console::EAnsiColor::eBoldRed,
"Fatal",
"Expression address: {} {}:{}", func, file, fileno);
SysPanic2(fileno, "That's all folks");
}
/**
A simple assertion with an optional message
*/
#define SysAssert(tru, ...) \
do \
{ \
SysAssertFileEx(__FILE__, __LINE__, SysSafeFunction, static_cast<bool>(tru), ## __VA_ARGS__); \
} while (0)
/**
A simple assertion with an optional message under debug targets
*/
#define SysAssertDbg SysAssert
#else
/// @private
template<typename ... T>
static auline void SysAssertEx(bool tru, int filenoOpt, fmt::format_string<T...> msg, T&& ... args)
{
if (tru)
{
return;
}
SysPanic2(filenoOpt, msg, args...);
}
/// @private
template<typename ... T>
static auline void SysAssertEx(bool tru, int filenoOpt)
{
if (tru)
{
return;
}
SysPanic2(filenoOpt, "That's all folks");
}
/**
A simple assertion with an optional message
*/
#define SysAssert(tru, ...) \
do \
{ \
SysAssertEx(static_cast<bool>(tru), SysSafeLine, ## __VA_ARGS__); \
} while (0)
/**
A simple assertion with an optional message under debug targets
*/
#define SysAssertDbg(tru, ...) do {} while (0)
#endif
// defines SysAssertExp and SysAssertDbgExp
#if !(defined(AU_CFG_ID_SHIP) || defined(AURORA_ASSERTIONS_FORCE_SHIP))
/// @private
template<typename ... T>
static auline void SysAssertFileExpEx(const char *file, int fileno, const char *func, const char *exp, bool tru, fmt::format_string<T...> msg, T&& ... args)
{
if (tru)
{
return;
}
Aurora::Logging::WriteLinef(
static_cast<AuUInt8>(Aurora::Logging::ELogLevel::eError),
Aurora::Console::EAnsiColor::eBoldRed,
"Fatal",
"Expression address: {} {}:{}", func, file, fileno);
Aurora::Logging::WriteLinef(
static_cast<AuUInt8>(Aurora::Logging::ELogLevel::eError),
Aurora::Console::EAnsiColor::eBoldRed,
"Fatal",
"Expression failed: {}", exp);
SysPanic2<T...>(fileno, msg, AuForward<T>(args)...);
}
/// @private
template<typename ... T>
static auline void SysAssertFileExpEx(const char *file, int fileno, const char *func, const char *exp, bool tru)
{
if (tru)
{
return;
}
Aurora::Logging::WriteLinef(
static_cast<AuUInt8>(Aurora::Logging::ELogLevel::eError),
Aurora::Console::EAnsiColor::eBoldRed,
"Fatal",
"Expression address: {} {}:{}", func, file, fileno);
Aurora::Logging::WriteLinef(
static_cast<AuUInt8>(Aurora::Logging::ELogLevel::eError),
Aurora::Console::EAnsiColor::eBoldRed,
"Fatal",
"Expression failed: {}", exp);
SysPanic2(fileno, "That's all folks");
}
/**
A simple assertion with a debug expresison and optional message
*/
#define SysAssertExp(tru, ...) \
do \
{ \
SysAssertFileExpEx(__FILE__, __LINE__, SysSafeFunction, _AUKCON_STRINGIFY_X2(tru), static_cast<bool>(tru), ## __VA_ARGS__); \
} while (0)
/**
A simple assertion with a debug expresison and optional message under debug targets only
*/
#define SysAssertDbgExp SysAssertExp
#else
/// @private
template<typename ... T>
static auline void SysAssertExpEx(const char *exp, int filenoOpt, bool tru, fmt::format_string<T...> msg, T&& ... args)
{
if (tru)
{
return;
}
#if !defined(AURORA_ASSERTIONS_NO_EXPRESSIONS)
Aurora::Logging::WriteLinef(
static_cast<AuUInt8>(Aurora::Logging::ELogLevel::eError),
Aurora::Console::EAnsiColor::eBoldRed,
"Fatal",
"Expression failed: {}", exp);
#endif
SysPanic2(filenoOpt, msg, args...);
}
/// @private
template<typename ... T>
static auline void SysAssertExpEx(const char *exp, int filenoOpt, bool tru)
{
if (tru)
{
return;
}
#if !defined(AURORA_ASSERTIONS_NO_EXPRESSIONS)
Aurora::Logging::WriteLinef(
static_cast<AuUInt8>(Aurora::Logging::ELogLevel::eError),
Aurora::Console::EAnsiColor::eBoldRed,
"Fatal",
"Expression failed: {}", exp);
#endif
SysPanic2(filenoOpt, "That's all folks");
}
/**
A simple assertion with a debug expresison and optional message
*/
#define SysAssertExp(tru, ...) \
do \
{ \
SysAssertExpEx(_AUKCON_STRINGIFY_X2(tru), SysSafeLine, static_cast<bool>(tru), ## __VA_ARGS__); \
} while (0)
/**
A simple assertion with a debug expresison and optional message under debug targets only
*/
#define SysAssertDbgExp(tru, ...) do {} while (0)
#endif
#if defined(AURORA_ASSERTIONS_FORCE_EXPRESSIONS)
#undef SysAssert
#undef SysAssertDbg
#define SysAssert SysAssertExp
#define SysAssertDbg SysAssertDbgExp
#endif
#endif