From cfb53c21e00f7e98389c29fe753871fb68ae13c1 Mon Sep 17 00:00:00 2001 From: _Redstone_c_ Date: Thu, 9 Dec 2021 20:25:56 +0800 Subject: [PATCH] feat(misc): add AssertionMacros.h and the corresponding testing --- .../Testing/AssertionMacrosTesting.cpp | 70 +++++++++++++++++++ .../Source/Public/Misc/AssertionMacros.h | 66 +++++++++++++++++ .../Public/Testing/AssertionMacrosTesting.h | 13 ++++ 3 files changed, 149 insertions(+) create mode 100644 Redcraft.Utility/Source/Private/Testing/AssertionMacrosTesting.cpp create mode 100644 Redcraft.Utility/Source/Public/Misc/AssertionMacros.h create mode 100644 Redcraft.Utility/Source/Public/Testing/AssertionMacrosTesting.h diff --git a/Redcraft.Utility/Source/Private/Testing/AssertionMacrosTesting.cpp b/Redcraft.Utility/Source/Private/Testing/AssertionMacrosTesting.cpp new file mode 100644 index 0000000..890dbd9 --- /dev/null +++ b/Redcraft.Utility/Source/Private/Testing/AssertionMacrosTesting.cpp @@ -0,0 +1,70 @@ +#include "Testing/AssertionMacrosTesting.h" +#include "Misc/AssertionMacros.h" + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) + +void TestNoEntry() +{ + check_no_entry(); + always_check_no_entry(); +} + +void TestNoReentry() +{ + check_no_reentry(); + always_check_no_reentry(); +} + +void TestNoRecursion(int32 Depth) +{ + if (Depth < 0) return; + + check_no_recursion(); + always_check_no_recursion(); + + TestNoRecursion(--Depth); +} + +void TestUnimplemented() +{ + unimplemented(); + always_unimplemented(); +} + +void TestAssertionMacros() +{ + check(true); + //check(false); + checkf(true, "True!"); + //checkf(false, "False!"); + + always_check(true); + //always_check(false); + always_checkf(true, "True!"); + //always_checkf(false, "False!"); + + //TestNoEntry(); + + TestNoReentry(); + //TestNoReentry(); + + TestNoRecursion(0); + TestNoRecursion(0); + //TestNoRecursion(1); + + //TestUnimplemented(); + + verify(true); + //verify(false); + + int32 A = 1; + int32 B = 0; + verify(B = A); + always_check(B == A); +} + +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END diff --git a/Redcraft.Utility/Source/Public/Misc/AssertionMacros.h b/Redcraft.Utility/Source/Public/Misc/AssertionMacros.h new file mode 100644 index 0000000..bb8d05b --- /dev/null +++ b/Redcraft.Utility/Source/Public/Misc/AssertionMacros.h @@ -0,0 +1,66 @@ +#pragma once + +#include "CoreTypes.h" +#include "Misc/PreprocessorHelpers.h" + +#undef NDEBUG +#include + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) + +NAMESPACE_PRIVATE_BEGIN + +class FRecursionScopeMarker +{ +public: + + FRecursionScopeMarker(uint8& InCounter) : Counter(InCounter) { ++Counter; } + ~FRecursionScopeMarker() { --Counter; } + +private: + + uint8& Counter; + +}; + +#define RS_CHECK_IMPL(InExpr) assert(InExpr) +#define RS_CHECK_F_IMPL(InExpr, InFormat, ...) assert(InExpr) + +NAMESPACE_PRIVATE_END + +#define always_check(InExpr) RS_CHECK_IMPL(InExpr) +#define always_checkf(InExpr, InFormat, ...) RS_CHECK_F_IMPL(InExpr, InFormat, ##__VA_ARGS__) +#define always_check_no_entry() always_checkf(false, "Enclosing block should never be called.") +#define always_check_no_reentry() { static bool PREPROCESSOR_JOIN(bBeenHere, __LINE__) = false; always_checkf(!PREPROCESSOR_JOIN(bBeenHere, __LINE__), "Enclosing block was called more than once."); PREPROCESSOR_JOIN(bBeenHere, __LINE__) = true; } +#define always_check_no_recursion() static uint8 PREPROCESSOR_JOIN(RecursionCounter, __LINE__) = 0; always_checkf(PREPROCESSOR_JOIN(RecursionCounter, __LINE__) == 0, "Enclosing block was entered recursively."); const NAMESPACE_PRIVATE::FRecursionScopeMarker PREPROCESSOR_JOIN(ScopeMarker, __LINE__)(PREPROCESSOR_JOIN(RecursionCounter, __LINE__)) +#define always_unimplemented() always_checkf(false, "Unimplemented function called.") + +#if BUILD_DEBUG + +# define check(InExpr) always_check(InExpr) +# define checkf(InExpr, InFormat, ...) always_checkf(InExpr, InFormat, ##__VA_ARGS__) +# define check_no_entry() always_check_no_entry() +# define check_no_reentry() always_check_no_reentry() +# define check_no_recursion() always_check_no_recursion() +# define verify(InExpr) always_check(InExpr) +# define verifyf(InExpr, InFormat, ...) always_checkf(InExpr, InFormat, ##__VA_ARGS__) +# define unimplemented() always_unimplemented() + +#else + +# define check(InExpr) +# define checkf(InExpr, InFormat, ...) +# define check_no_entry() +# define check_no_reentry() +# define check_no_recursion() +# define verify(InExpr) { if(InExpr) { } } +# define verifyf(InExpr, InFormat, ...) { if(InExpr) { } } +# define unimplemented() + +#endif + +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END diff --git a/Redcraft.Utility/Source/Public/Testing/AssertionMacrosTesting.h b/Redcraft.Utility/Source/Public/Testing/AssertionMacrosTesting.h new file mode 100644 index 0000000..cf0b0a5 --- /dev/null +++ b/Redcraft.Utility/Source/Public/Testing/AssertionMacrosTesting.h @@ -0,0 +1,13 @@ +#pragma once + +#include "CoreTypes.h" + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) + +void REDCRAFTUTILITY_API TestAssertionMacros(); + +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END