4#ifndef _Stroika_Foundation_Debug_Assertions_h_
5#define _Stroika_Foundation_Debug_Assertions_h_ 1
7#include "Stroika/Foundation/StroikaPreComp.h"
9#include "Stroika/Foundation/Common/Common.h"
29namespace Stroika::Foundation::Debug {
41#if !defined(qStroika_Foundation_Debug_AssertionsChecked)
43#define qStroika_Foundation_Debug_AssertionsChecked 1
45#define qStroika_Foundation_Debug_AssertionsChecked 0
49#define qStroika_Foundation_Debug_AssertionsChecked 1
54#if qStroika_Foundation_Debug_AssertionsChecked
57 static_assert (
false,
"INCONSISTENT DEFINES (NDEBUG and qStroika_Foundation_Debug_AssertionsChecked=1)");
62 static_assert (
false,
"INCONSISTENT DEFINES (_DEBUG and qStroika_Foundation_Debug_AssertionsChecked=0)");
70#define Stroika_Foundation_Debug_Widen2_(x) L##x
71#define Stroika_Foundation_Debug_Widen(x) Stroika_Foundation_Debug_Widen2_ (x)
73#if qStroika_Foundation_Debug_AssertionsChecked || defined(__Doxygen__)
83 using AssertionHandlerType = void (*) (
const wchar_t* assertCategory,
const wchar_t* assertionText,
const wchar_t* fileName,
84 int lineNum,
const wchar_t* functionName)
noexcept;
200 [[noreturn]]
void Assertion_Failure_Handler_ (
const wchar_t* assertCategory,
const wchar_t* assertionText,
const wchar_t* fileName,
201 int lineNum,
const char* functionName)
noexcept;
204 void Weak_Assertion_Failure_Handler_ (
const wchar_t* assertCategory,
const wchar_t* assertionText,
const wchar_t* fileName,
205 int lineNum,
const char* functionName)
noexcept;
211#if !defined(__Doxygen__)
212#if qCompilerAndStdLib_Support__PRETTY_FUNCTION__
213#define ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_ __PRETTY_FUNCTION__
214#elif qCompilerAndStdLib_Support__func__
215#define ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_ __func__
216#elif qCompilerAndStdLib_Support__FUNCTION__
217#define ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_ __FUNCTION__
219#define ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_ L""
233#if qStroika_Foundation_Debug_AssertionsChecked
234#define AssertExpression(c) \
235 (!!(c) || (Stroika::Foundation::Debug::Private_::Assertion_Failure_Handler_ (L"Assert", Stroika_Foundation_Debug_Widen (#c), \
236 Stroika_Foundation_Debug_Widen (__FILE__), __LINE__, \
237 ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_), \
240#define AssertExpression(c) ((void)0)
256#if qStroika_Foundation_Debug_AssertionsChecked
257#define Assert(c) AssertExpression (c)
259#define Assert(c) qStroika_ATTRIBUTE_ASSUME (c)
267#if qStroika_Foundation_Debug_AssertionsChecked
268#define RequireExpression(c) \
269 (!!(c) || (Stroika::Foundation::Debug::Private_::Assertion_Failure_Handler_ (L"Require", Stroika_Foundation_Debug_Widen (#c), \
270 Stroika_Foundation_Debug_Widen (__FILE__), __LINE__, \
271 ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_), \
274#define RequireExpression(c) ((void)0)
280#if qStroika_Foundation_Debug_AssertionsChecked
281#define Require(c) RequireExpression (c)
283#define Require(c) qStroika_ATTRIBUTE_ASSUME (c)
289#if qStroika_Foundation_Debug_AssertionsChecked
290#define EnsureExpression(c) \
291 (!!(c) || (Stroika::Foundation::Debug::Private_::Assertion_Failure_Handler_ (L"Ensure", Stroika_Foundation_Debug_Widen (#c), \
292 Stroika_Foundation_Debug_Widen (__FILE__), __LINE__, \
293 ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_), \
296#define EnsureExpression(c) ((void)0)
302#if qStroika_Foundation_Debug_AssertionsChecked
303#define Ensure(c) EnsureExpression (c)
305#define Ensure(c) qStroika_ATTRIBUTE_ASSUME (c)
313#define AssertMember(p, c) Assert (dynamic_cast<const c*> (p) != nullptr)
320#define EnsureMember(p, c) Ensure (dynamic_cast<const c*> (p) != nullptr)
327#define RequireMember(p, c) Require (dynamic_cast<const c*> (p) != nullptr)
334#define AssertNotNull(p) Assert (p != nullptr)
341#define EnsureNotNull(p) Ensure (p != nullptr)
348#define RequireNotNull(p) Require (p != nullptr)
355#if qStroika_Foundation_Debug_AssertionsChecked
356#define AssertNotReached() \
357 Stroika::Foundation::Debug::Private_::Assertion_Failure_Handler_ (L"Assert", L"Not Reached", Stroika_Foundation_Debug_Widen (__FILE__), \
358 __LINE__, ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_)
359#elif __cpp_lib_unreachable < 202202
360#define AssertNotReached()
362#define AssertNotReached() unreachable ()
370#if qStroika_Foundation_Debug_AssertionsChecked
371#define EnsureNotReached() \
372 Stroika::Foundation::Debug::Private_::Assertion_Failure_Handler_ (L"Ensure", L"Not Reached", Stroika_Foundation_Debug_Widen (__FILE__), \
373 __LINE__, ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_)
374#elif __cpp_lib_unreachable < 202202
375#define EnsureNotReached()
377#define EnsureNotReached() unreachable ()
385#if qStroika_Foundation_Debug_AssertionsChecked
386#define RequireNotReached() \
387 Stroika::Foundation::Debug::Private_::Assertion_Failure_Handler_ (L"Require", L"Not Reached", Stroika_Foundation_Debug_Widen (__FILE__), \
388 __LINE__, ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_)
389#elif __cpp_lib_unreachable < 202202
390#define RequireNotReached()
392#define RequireNotReached() unreachable ()
401#if qStroika_Foundation_Debug_AssertionsChecked
402#define AssertNotImplemented() \
403 Stroika::Foundation::Debug::Private_::Assertion_Failure_Handler_ (L"Assert", L"Not Implemented", Stroika_Foundation_Debug_Widen (__FILE__), \
404 __LINE__, ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_)
406#define AssertNotImplemented()
419#if qStroika_Foundation_Debug_AssertionsChecked
420#define Verify(c) Assert (c)
422#define Verify(c) ((void)(c))
438#if qStroika_Foundation_Debug_AssertionsChecked
439#define WeakAssert(c) \
440 (!!(c) || (Stroika::Foundation::Debug::Private_::Weak_Assertion_Failure_Handler_ (L"WeakAssert", Stroika_Foundation_Debug_Widen (#c), \
441 Stroika_Foundation_Debug_Widen (__FILE__), __LINE__, \
442 ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_), \
445#define WeakAssert(c) ((void)0)
453#define WeakAssertMember(p, c) WeakAssert (dynamic_cast<const c*> (p) != nullptr)
460#define WeakAssertNotNull(p) WeakAssert (p != nullptr)
467#if qStroika_Foundation_Debug_AssertionsChecked
468#define WeakAssertNotReached() \
469 Stroika::Foundation::Debug::Private_::Weak_Assertion_Failure_Handler_ ( \
470 L"WeakAssert", L"Not Reached", Stroika_Foundation_Debug_Widen (__FILE__), __LINE__, ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_)
472#define WeakAssertNotReached()
483#if qStroika_Foundation_Debug_AssertionsChecked
484#define WeakAssertNotImplemented() \
485 Stroika::Foundation::Debug::Private_::Weak_Assertion_Failure_Handler_ ( \
486 L"WeakAssert", L"Not Implemented", Stroika_Foundation_Debug_Widen (__FILE__), __LINE__, ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_)
488#define WeakAssertNotImplemented()
502#if qStroika_Foundation_Debug_AssertionsChecked
503#define WeakVerify(c) WeakAssert (c)
505#define WeakVerify(c) ((void)(c))
509 [[deprecated (
"Since Stroika v3.0d6 - use the wchar_t overload")]]
void
510 SetWeakAssertionHandler (
void (*legacyHandler) (
const char* assertCategory,
const char* assertionText,
const char* fileName,
511 int lineNum,
const char* functionName)
noexcept);
512 [[deprecated (
"Since Stroika v3.0d6 - use the wchar_t overload")]]
void
513 SetAssertionHandler (
void (*legacyHandler) (
const char* assertCategory,
const char* assertionText,
const char* fileName,
int lineNum,
514 const char* functionName)
noexcept);
517#define qDebug qStroika_Foundation_Debug_AssertionsChecked
void SetWeakAssertionHandler(AssertionHandlerType assertionHandler)
void SetAssertionHandler(AssertionHandlerType assertionHandler)
AssertionHandlerType GetAssertionHandler()
#define qStroika_Foundation_Debug_AssertionsChecked
The qStroika_Foundation_Debug_AssertionsChecked flag determines if assertions are checked and validat...
void(*)(const wchar_t *assertCategory, const wchar_t *assertionText, const wchar_t *fileName, int lineNum, const wchar_t *functionName) noexcept AssertionHandlerType
#define CompileTimeFlagChecker_HEADER(NS_PREFIX, NAME, VALUE)
CompileTimeFlagChecker_HEADER () will generate a LINK ERROR if you ever compile a header with one val...