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)
258#if qStroika_Foundation_Debug_AssertionsChecked
259#define Assert(c) AssertExpression (c)
261#define Assert(c) Stroika_ATTRIBUTE_ASSUME (c)
269#if qStroika_Foundation_Debug_AssertionsChecked
270#define RequireExpression(c) \
271 (!!(c) || (Stroika::Foundation::Debug::Private_::Assertion_Failure_Handler_ (L"Require", Stroika_Foundation_Debug_Widen (#c), \
272 Stroika_Foundation_Debug_Widen (__FILE__), __LINE__, \
273 ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_), \
276#define RequireExpression(c) ((void)0)
282#if qStroika_Foundation_Debug_AssertionsChecked
283#define Require(c) RequireExpression (c)
285#define Require(c) Stroika_ATTRIBUTE_ASSUME (c)
291#if qStroika_Foundation_Debug_AssertionsChecked
292#define EnsureExpression(c) \
293 (!!(c) || (Stroika::Foundation::Debug::Private_::Assertion_Failure_Handler_ (L"Ensure", Stroika_Foundation_Debug_Widen (#c), \
294 Stroika_Foundation_Debug_Widen (__FILE__), __LINE__, \
295 ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_), \
298#define EnsureExpression(c) ((void)0)
304#if qStroika_Foundation_Debug_AssertionsChecked
305#define Ensure(c) EnsureExpression (c)
307#define Ensure(c) Stroika_ATTRIBUTE_ASSUME (c)
315#define AssertMember(p, c) Assert (dynamic_cast<const c*> (p) != nullptr)
322#define EnsureMember(p, c) Ensure (dynamic_cast<const c*> (p) != nullptr)
329#define RequireMember(p, c) Require (dynamic_cast<const c*> (p) != nullptr)
336#define AssertNotNull(p) Assert (p != nullptr)
343#define EnsureNotNull(p) Ensure (p != nullptr)
350#define RequireNotNull(p) Require (p != nullptr)
357#if qStroika_Foundation_Debug_AssertionsChecked
358#define AssertNotReached() \
359 Stroika::Foundation::Debug::Private_::Assertion_Failure_Handler_ (L"Assert", L"Not Reached", Stroika_Foundation_Debug_Widen (__FILE__), \
360 __LINE__, ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_)
361#elif not defined(__cpp_lib_unreachable)
362#define AssertNotReached()
364#define AssertNotReached() unreachable ()
372#if qStroika_Foundation_Debug_AssertionsChecked
373#define EnsureNotReached() \
374 Stroika::Foundation::Debug::Private_::Assertion_Failure_Handler_ (L"Ensure", L"Not Reached", Stroika_Foundation_Debug_Widen (__FILE__), \
375 __LINE__, ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_)
376#elif not defined(__cpp_lib_unreachable)
377#define EnsureNotReached()
379#define EnsureNotReached() unreachable ()
387#if qStroika_Foundation_Debug_AssertionsChecked
388#define RequireNotReached() \
389 Stroika::Foundation::Debug::Private_::Assertion_Failure_Handler_ (L"Require", L"Not Reached", Stroika_Foundation_Debug_Widen (__FILE__), \
390 __LINE__, ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_)
391#elif not defined(__cpp_lib_unreachable)
392#define RequireNotReached()
394#define RequireNotReached() unreachable ()
403#if qStroika_Foundation_Debug_AssertionsChecked
404#define AssertNotImplemented() \
405 Stroika::Foundation::Debug::Private_::Assertion_Failure_Handler_ (L"Assert", L"Not Implemented", Stroika_Foundation_Debug_Widen (__FILE__), \
406 __LINE__, ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_)
408#define AssertNotImplemented()
421#if qStroika_Foundation_Debug_AssertionsChecked
422#define Verify(c) Assert (c)
424#define Verify(c) ((void)(c))
440#if qStroika_Foundation_Debug_AssertionsChecked
441#define WeakAssert(c) \
442 (!!(c) || (Stroika::Foundation::Debug::Private_::Weak_Assertion_Failure_Handler_ (L"WeakAssert", Stroika_Foundation_Debug_Widen (#c), \
443 Stroika_Foundation_Debug_Widen (__FILE__), __LINE__, \
444 ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_), \
447#define WeakAssert(c) ((void)0)
455#define WeakAssertMember(p, c) WeakAssert (dynamic_cast<const c*> (p) != nullptr)
462#define WeakAssertNotNull(p) WeakAssert (p != nullptr)
469#if qStroika_Foundation_Debug_AssertionsChecked
470#define WeakAssertNotReached() \
471 Stroika::Foundation::Debug::Private_::Weak_Assertion_Failure_Handler_ ( \
472 L"WeakAssert", L"Not Reached", Stroika_Foundation_Debug_Widen (__FILE__), __LINE__, ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_)
474#define WeakAssertNotReached()
485#if qStroika_Foundation_Debug_AssertionsChecked
486#define WeakAssertNotImplemented() \
487 Stroika::Foundation::Debug::Private_::Weak_Assertion_Failure_Handler_ ( \
488 L"WeakAssert", L"Not Implemented", Stroika_Foundation_Debug_Widen (__FILE__), __LINE__, ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_)
490#define WeakAssertNotImplemented()
504#if qStroika_Foundation_Debug_AssertionsChecked
505#define WeakVerify(c) WeakAssert (c)
507#define WeakVerify(c) ((void)(c))
511 [[deprecated (
"Since Stroika v3.0d6 - use the wchar_t overload")]]
void
512 SetWeakAssertionHandler (
void (*legacyHandler) (
const char* assertCategory,
const char* assertionText,
const char* fileName,
513 int lineNum,
const char* functionName)
noexcept);
514 [[deprecated (
"Since Stroika v3.0d6 - use the wchar_t overload")]]
void
515 SetAssertionHandler (
void (*legacyHandler) (
const char* assertCategory,
const char* assertionText,
const char* fileName,
int lineNum,
516 const char* functionName)
noexcept);
519#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...