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"
28namespace Stroika::Foundation::Debug {
40#if !defined(qStroika_Foundation_Debug_AssertionsChecked)
42#define qStroika_Foundation_Debug_AssertionsChecked 1
44#define qStroika_Foundation_Debug_AssertionsChecked 0
48#define qStroika_Foundation_Debug_AssertionsChecked 1
53#if qStroika_Foundation_Debug_AssertionsChecked
56 static_assert (
false,
"INCONSISTENT DEFINES (NDEBUG and qStroika_Foundation_Debug_AssertionsChecked=1)");
61 static_assert (
false,
"INCONSISTENT DEFINES (_DEBUG and qStroika_Foundation_Debug_AssertionsChecked=0)");
69#define Stroika_Foundation_Debug_Widen2_(x) L##x
70#define Stroika_Foundation_Debug_Widen(x) Stroika_Foundation_Debug_Widen2_ (x)
72#if qStroika_Foundation_Debug_AssertionsChecked || defined(__Doxygen__)
82 using AssertionHandlerType = void (*) (
const wchar_t* assertCategory,
const wchar_t* assertionText,
const wchar_t* fileName,
83 int lineNum,
const wchar_t* functionName)
noexcept;
199 [[noreturn]]
void Assertion_Failure_Handler_ (
const wchar_t* assertCategory,
const wchar_t* assertionText,
const wchar_t* fileName,
200 int lineNum,
const char* functionName)
noexcept;
203 void Weak_Assertion_Failure_Handler_ (
const wchar_t* assertCategory,
const wchar_t* assertionText,
const wchar_t* fileName,
204 int lineNum,
const char* functionName)
noexcept;
210#if !defined(__Doxygen__)
211#if qCompilerAndStdLib_Support__PRETTY_FUNCTION__
212#define ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_ __PRETTY_FUNCTION__
213#elif qCompilerAndStdLib_Support__func__
214#define ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_ __func__
215#elif qCompilerAndStdLib_Support__FUNCTION__
216#define ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_ __FUNCTION__
218#define ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_ L""
232#if qStroika_Foundation_Debug_AssertionsChecked
233#define AssertExpression(c) \
234 (!!(c) || (Stroika::Foundation::Debug::Private_::Assertion_Failure_Handler_ (L"Assert", Stroika_Foundation_Debug_Widen (#c), \
235 Stroika_Foundation_Debug_Widen (__FILE__), __LINE__, \
236 ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_), \
239#define AssertExpression(c) ((void)0)
255#if qStroika_Foundation_Debug_AssertionsChecked
256#define Assert(c) AssertExpression (c)
258#define Assert(c) _ASSUME_ATTRIBUTE_ (c)
266#if qStroika_Foundation_Debug_AssertionsChecked
267#define RequireExpression(c) \
268 (!!(c) || (Stroika::Foundation::Debug::Private_::Assertion_Failure_Handler_ (L"Require", Stroika_Foundation_Debug_Widen (#c), \
269 Stroika_Foundation_Debug_Widen (__FILE__), __LINE__, \
270 ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_), \
273#define RequireExpression(c) ((void)0)
279#if qStroika_Foundation_Debug_AssertionsChecked
280#define Require(c) RequireExpression (c)
282#define Require(c) _ASSUME_ATTRIBUTE_ (c)
288#if qStroika_Foundation_Debug_AssertionsChecked
289#define EnsureExpression(c) \
290 (!!(c) || (Stroika::Foundation::Debug::Private_::Assertion_Failure_Handler_ (L"Ensure", Stroika_Foundation_Debug_Widen (#c), \
291 Stroika_Foundation_Debug_Widen (__FILE__), __LINE__, \
292 ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_), \
295#define EnsureExpression(c) ((void)0)
301#if qStroika_Foundation_Debug_AssertionsChecked
302#define Ensure(c) EnsureExpression (c)
304#define Ensure(c) _ASSUME_ATTRIBUTE_ (c)
312#define AssertMember(p, c) Assert (dynamic_cast<const c*> (p) != nullptr)
319#define EnsureMember(p, c) Ensure (dynamic_cast<const c*> (p) != nullptr)
326#define RequireMember(p, c) Require (dynamic_cast<const c*> (p) != nullptr)
333#define AssertNotNull(p) Assert (p != nullptr)
340#define EnsureNotNull(p) Ensure (p != nullptr)
347#define RequireNotNull(p) Require (p != nullptr)
354#if qStroika_Foundation_Debug_AssertionsChecked
355#define AssertNotReached() \
356 Stroika::Foundation::Debug::Private_::Assertion_Failure_Handler_ (L"Assert", L"Not Reached", Stroika_Foundation_Debug_Widen (__FILE__), \
357 __LINE__, ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_)
358#elif __cpp_lib_unreachable < 202202
359#define AssertNotReached()
361#define AssertNotReached() unreachable ()
369#if qStroika_Foundation_Debug_AssertionsChecked
370#define EnsureNotReached() \
371 Stroika::Foundation::Debug::Private_::Assertion_Failure_Handler_ (L"Ensure", L"Not Reached", Stroika_Foundation_Debug_Widen (__FILE__), \
372 __LINE__, ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_)
373#elif __cpp_lib_unreachable < 202202
374#define EnsureNotReached()
376#define EnsureNotReached() unreachable ()
384#if qStroika_Foundation_Debug_AssertionsChecked
385#define RequireNotReached() \
386 Stroika::Foundation::Debug::Private_::Assertion_Failure_Handler_ (L"Require", L"Not Reached", Stroika_Foundation_Debug_Widen (__FILE__), \
387 __LINE__, ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_)
388#elif __cpp_lib_unreachable < 202202
389#define RequireNotReached()
391#define RequireNotReached() unreachable ()
400#if qStroika_Foundation_Debug_AssertionsChecked
401#define AssertNotImplemented() \
402 Stroika::Foundation::Debug::Private_::Assertion_Failure_Handler_ (L"Assert", L"Not Implemented", Stroika_Foundation_Debug_Widen (__FILE__), \
403 __LINE__, ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_)
405#define AssertNotImplemented()
418#if qStroika_Foundation_Debug_AssertionsChecked
419#define Verify(c) Assert (c)
421#define Verify(c) ((void)(c))
437#if qStroika_Foundation_Debug_AssertionsChecked
438#define WeakAssert(c) \
439 (!!(c) || (Stroika::Foundation::Debug::Private_::Weak_Assertion_Failure_Handler_ (L"WeakAssert", Stroika_Foundation_Debug_Widen (#c), \
440 Stroika_Foundation_Debug_Widen (__FILE__), __LINE__, \
441 ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_), \
444#define WeakAssert(c) ((void)0)
452#define WeakAssertMember(p, c) WeakAssert (dynamic_cast<const c*> (p) != nullptr)
459#define WeakAssertNotNull(p) WeakAssert (p != nullptr)
466#if qStroika_Foundation_Debug_AssertionsChecked
467#define WeakAssertNotReached() \
468 Stroika::Foundation::Debug::Private_::Weak_Assertion_Failure_Handler_ ( \
469 L"WeakAssert", L"Not Reached", Stroika_Foundation_Debug_Widen (__FILE__), __LINE__, ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_)
471#define WeakAssertNotReached()
482#if qStroika_Foundation_Debug_AssertionsChecked
483#define WeakAssertNotImplemented() \
484 Stroika::Foundation::Debug::Private_::Weak_Assertion_Failure_Handler_ ( \
485 L"WeakAssert", L"Not Implemented", Stroika_Foundation_Debug_Widen (__FILE__), __LINE__, ASSERT_PRIVATE_ENCLOSING_FUNCTION_NAME_)
487#define WeakAssertNotImplemented()
501#if qStroika_Foundation_Debug_AssertionsChecked
502#define WeakVerify(c) WeakAssert (c)
504#define WeakVerify(c) ((void)(c))
508 [[deprecated (
"Since Stroika v3.0d6 - use the wchar_t overload")]]
void
509 SetWeakAssertionHandler (
void (*legacyHandler) (
const char* assertCategory,
const char* assertionText,
const char* fileName,
510 int lineNum,
const char* functionName)
noexcept);
511 [[deprecated (
"Since Stroika v3.0d6 - use the wchar_t overload")]]
void
512 SetAssertionHandler (
void (*legacyHandler) (
const char* assertCategory,
const char* assertionText,
const char* fileName,
int lineNum,
513 const char* functionName)
noexcept);
516#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...