diff --git a/include/bal.hh b/include/bal.hh index 5d31c3b..f42196a 100644 --- a/include/bal.hh +++ b/include/bal.hh @@ -26,12 +26,6 @@ #ifndef _BAL_HH_INCLUDED # define _BAL_HH_INCLUDED -# if defined(__has_include) -# define __HAS_INCLUDE(hdr) __has_include(hdr) -# else -# define __HAS_INCLUDE(hdr) false -# endif - # include "bal.h" # include # include @@ -41,7 +35,20 @@ # include # include # include -# if __HAS_INCLUDE() +# include + +# if defined(__has_include) +# define __HAS_INCLUDE(hdr) __has_include(hdr) +# else +# define __HAS_INCLUDE(hdr) false +# endif + +# if defined(__cpp_lib_source_location) && __HAS_INCLUDE() +# include +# define source_location std::source_location +# endif + +# if defined(__cpp_lib_bit_cast) && __HAS_INCLUDE() # include # define bit_cast std::bit_cast # else diff --git a/include/bal/errors.h b/include/bal/errors.h index ba9e557..a0e6f2d 100644 --- a/include/bal/errors.h +++ b/include/bal/errors.h @@ -161,11 +161,10 @@ bool __bal_validate(bool expr, int err, const char* func, const char* file, # if defined(BAL_DBGLOG) void __bal_dbglog(const char* func, const char* file, uint32_t line, const char* format, ...); -# if defined(__cplusplus) && __HAS_INCLUDE() -# include +# if defined(__cplusplus) && defined(source_location) # define _bal_dbglog(...) \ do { \ - std::source_location loc = std::source_location::current(); \ + source_location loc = source_location::current(); \ __bal_dbglog(loc.function_name(), loc.file_name(), loc.line(), __VA_ARGS__); \ } while (false) # else diff --git a/tests/tests++.hh b/tests/tests++.hh index 2913fc9..7cfd2f6 100644 --- a/tests/tests++.hh +++ b/tests/tests++.hh @@ -27,7 +27,6 @@ # define _BAL_TESTSXX_HH_INCLUDED # include -# include # include "tests_shared.h" /** @@ -71,16 +70,34 @@ namespace bal::tests try { \ initializer balinit; +/** Emits an error message when an unexpected exception is caught. */ +# define _BAL_TEST_LOG_UNEXPECTED_EXCEPTION(func, what) \ + ERROR_MSG("unexpected exception in %s: '%s'", (func), (what)); \ + pass = false + +/** Emits a message when an expected exception is caught. */ +# define _BAL_TEST_LOG_EXPECTED_EXCEPTION(func, what) \ + TEST_MSG(GREEN("expected exception in %s: '%s'"), (func), (what)) + /** Implements recovery in the event that an unexpected exception is caught. */ -# define _BAL_TEST_ON_EXCEPTION(ex) \ - std::source_location loc = std::source_location::current(); \ - ERROR_MSG("unexpected exception in %s: '%s'", loc.function_name(), ex.what()); \ - pass = false +# if defined(source_location) +# define _BAL_TEST_ON_EXCEPTION(ex) \ + source_location loc = source_location::current(); \ + _BAL_TEST_LOG_UNEXPECTED_EXCEPTION(loc.function_name(), ex.what()) +# else +# define _BAL_TEST_ON_EXCEPTION(ex) \ + _BAL_TEST_LOG_UNEXPECTED_EXCEPTION(__func__, ex.what()) +# endif /** Handles an expected exception. */ +# if defined(source_location) +# define _BAL_TEST_ON_EXPECTED_EXCEPTION(ex) \ + source_location loc = source_location::current(); \ + _BAL_TEST_LOG_EXPECTED_EXCEPTION(loc.function_name(), ex.what()) +# else # define _BAL_TEST_ON_EXPECTED_EXCEPTION(ex) \ - std::source_location loc = std::source_location::current(); \ - TEST_MSG(GREEN("expected exception in %s: '%s'"), loc.function_name(), ex.what()) + _BAL_TEST_LOG_EXPECTED_EXCEPTION(__func__, ex.what()) +# endif # define _BAL_TEST_CONCLUDE \ } catch (bal::exception& ex) { \