From c0a622c5e43e4f8df8485c97f3e1469667307fff Mon Sep 17 00:00:00 2001 From: Erki Date: Wed, 29 Jun 2022 01:00:45 +0300 Subject: [PATCH] Utility: add mini-assert library --- Tests/CMakeLists.txt | 6 ++- Tests/assert.cpp | 68 ++++++++++++++++++++++++++++++++++ Tests/assert_ndebug.cpp | 62 +++++++++++++++++++++++++++++++ Utility/CMakeLists.txt | 1 + Utility/Inc/utility_assert.hpp | 33 +++++++++++++++++ Utility/Inc/utility_tag.hpp | 2 +- Utility/Src/utility_assert.cpp | 45 ++++++++++++++++++++++ 7 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 Tests/assert.cpp create mode 100644 Tests/assert_ndebug.cpp create mode 100644 Utility/Inc/utility_assert.hpp create mode 100644 Utility/Src/utility_assert.cpp diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 215684f..117a2ad 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -24,7 +24,11 @@ add_executable(tests rand.cpp fixedpoint.cpp pixelbuffer.cpp - pixelbuffer_effects.cpp function.cpp) + pixelbuffer_effects.cpp + function.cpp + assert_ndebug.cpp + assert.cpp +) target_link_libraries(tests PUBLIC diff --git a/Tests/assert.cpp b/Tests/assert.cpp new file mode 100644 index 0000000..3929583 --- /dev/null +++ b/Tests/assert.cpp @@ -0,0 +1,68 @@ +// +// Created by erki on 29.06.22. +// + +#include + +#ifdef NDEBUG +# undef NDEBUG +# define NDEBUG_WAS_SET +#endif + +#include "utility_assert.hpp" + +#ifdef NDEBUG_WAS_SET +# define NDEBUG +#endif + +namespace +{ + +bool assert_flag = false; + +void assertCallback(const char*, const int) +{ + assert_flag = true; +} + +} + +TEST_CASE("Assert debug without NDEBUG gets triggered if check is false.", "[utility],[assert]") +{ + assert_flag = false; + Utility::Assert::setHandler(assertCallback); + + SKULLC_ASSERT_DEBUG(false); + + CHECK(assert_flag == true); +} + +TEST_CASE("Assert debug without NDEBUG doesn't get triggered if check is true.", "[utility],[assert]") +{ + assert_flag = false; + Utility::Assert::setHandler(assertCallback); + + SKULLC_ASSERT_DEBUG(true); + + CHECK(assert_flag == false); +} + +TEST_CASE("Assert safe without NDEBUG gets triggered if check is false.", "[utility],[assert]") +{ + assert_flag = false; + Utility::Assert::setHandler(assertCallback); + + SKULLC_ASSERT_SAFE(false); + + CHECK(assert_flag == true); +} + +TEST_CASE("Assert safe without NDEBUG doesn't get triggered if check is true.", "[utility],[assert]") +{ + assert_flag = false; + Utility::Assert::setHandler(assertCallback); + + SKULLC_ASSERT_SAFE(true); + + CHECK(assert_flag == false); +} diff --git a/Tests/assert_ndebug.cpp b/Tests/assert_ndebug.cpp new file mode 100644 index 0000000..f130c25 --- /dev/null +++ b/Tests/assert_ndebug.cpp @@ -0,0 +1,62 @@ +// +// Created by erki on 29.06.22. +// + +#include + +#ifndef NDEBUG +# define NDEBUG +# define NDEBUG_WAS_NOT_DEFINED +#endif + +#include "utility_assert.hpp" + +#ifdef NDEBUG_WAS_NOT_DEFINED +# undef NDEBUG +#endif + +namespace +{ + +bool assert_flag = false; + +void assertCallback(const char*, const int) +{ + assert_flag = true; +} + +} + +TEST_CASE("Assert debug with NDEBUG is a null-opt.", "[utility],[assert]") +{ + assert_flag = false; + Utility::Assert::setHandler(assertCallback); + + int check_number = 0; + SKULLC_ASSERT_DEBUG(check_number++ == 0); + + CHECK(check_number == 0); + CHECK(assert_flag == false); +} + +TEST_CASE("Assert safe with NDEBUG gets triggered if check is false.", "[utility],[assert]") +{ + assert_flag = false; + Utility::Assert::setHandler(assertCallback); + + int check_number = 0; + SKULLC_ASSERT_SAFE(check_number++ == 1); + + CHECK(check_number == 1); + CHECK(assert_flag == true); +} + +TEST_CASE("Assert safe with NDEBUG doesn't get triggered if check is true.", "[utility],[assert]") +{ + assert_flag = false; + Utility::Assert::setHandler(assertCallback); + + SKULLC_ASSERT_SAFE(true); + + CHECK(assert_flag == false); +} diff --git a/Utility/CMakeLists.txt b/Utility/CMakeLists.txt index 2c825f6..1114ce1 100644 --- a/Utility/CMakeLists.txt +++ b/Utility/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.8 FATAL_ERROR) add_library(utility STATIC Src/utility_logging.cpp Src/utility_rand.cpp + Src/utility_assert.cpp ${additional_sources} ) diff --git a/Utility/Inc/utility_assert.hpp b/Utility/Inc/utility_assert.hpp new file mode 100644 index 0000000..89c1998 --- /dev/null +++ b/Utility/Inc/utility_assert.hpp @@ -0,0 +1,33 @@ +// +// Created by erki on 29.06.22. +// + +#ifndef SKULLC_UTILITY_ASSERT_HPP_ +#define SKULLC_UTILITY_ASSERT_HPP_ + +namespace Utility::Assert::Detail +{ + +void assertImpl(const bool expr, const char* file, const int line); + +} + +#ifndef NDEBUG +# define SKULLC_ASSERT_DEBUG(e) Utility::Assert::Detail::assertImpl(e, __FILE__, __LINE__) +#else +# define SKULLC_ASSERT_DEBUG(e) +#endif + +#define SKULLC_ASSERT_SAFE(e) Utility::Assert::Detail::assertImpl(e, __FILE__, __LINE__) + +namespace Utility::Assert +{ + +using assert_cb = void (*)(const char* file, const int line); + +void setHandler(assert_cb callback); +assert_cb getHandler(); + +} + +#endif // SKULLC_UTILITY_ASSERT_HPP_ diff --git a/Utility/Inc/utility_tag.hpp b/Utility/Inc/utility_tag.hpp index 99eb900..235a769 100644 --- a/Utility/Inc/utility_tag.hpp +++ b/Utility/Inc/utility_tag.hpp @@ -9,4 +9,4 @@ #define SKULLC_CONCAT(x, y) SKULLC_CONCAT_IMPL(x, y) #define SKULLC_TAG struct SKULLC_CONCAT(SkullCTag_, __COUNTER__) -#endif// SKULLC_UTILITY_TAG_HPP_ +#endif // SKULLC_UTILITY_TAG_HPP_ diff --git a/Utility/Src/utility_assert.cpp b/Utility/Src/utility_assert.cpp new file mode 100644 index 0000000..6527a3e --- /dev/null +++ b/Utility/Src/utility_assert.cpp @@ -0,0 +1,45 @@ +// +// Created by erki on 29.06.22. +// + +#include "utility_assert.hpp" + +#include + +namespace +{ + +Utility::Assert::assert_cb INSTALLED_HANDLER = nullptr; + +} + +namespace Utility::Assert +{ + +namespace Detail +{ + +void assertImpl(const bool expr, const char* file, const int line) +{ + if (!expr) + { + if (INSTALLED_HANDLER) + INSTALLED_HANDLER(file, line); + else + std::terminate(); + } +} + +} + +void setHandler(assert_cb callback) +{ + INSTALLED_HANDLER = callback; +} + +assert_cb getHandler() +{ + return INSTALLED_HANDLER; +} + +}