|
|
@ -19,6 +19,7 @@ |
|
|
|
#pragma once |
|
|
|
|
|
|
|
#include <stdexcept> |
|
|
|
#include <iostream> |
|
|
|
|
|
|
|
/** Macros */ |
|
|
|
|
|
|
@ -27,42 +28,59 @@ |
|
|
|
#define STRINGIFY_HELPER(line) \ |
|
|
|
STRINGIFY(line) |
|
|
|
|
|
|
|
#ifndef JESSILIB_ASSERT_MESSAGE |
|
|
|
#define JESSILIB_ASSERT_MESSAGE(expression) \ |
|
|
|
"Failed assertion: '" #expression "' at " __FILE__ ":" STRINGIFY_HELPER(__LINE__) |
|
|
|
#endif // JESSILIB_ASSERT_MESSAGE
|
|
|
|
|
|
|
|
// Returns a boolean expression indicating assertion success/failure
|
|
|
|
#ifndef jessilib_assert |
|
|
|
#define jessilib_assert(expression) \ |
|
|
|
(::jessilib::impl::_assert_helper( expression, "Failed assertion: '" #expression "' at " __FILE__ ":" STRINGIFY_HELPER(__LINE__) )) |
|
|
|
(::jessilib::impl::_assert_helper( expression, JESSILIB_ASSERT_MESSAGE(expression) )) |
|
|
|
#endif // jessilib_assert
|
|
|
|
|
|
|
|
// Similar to jessilib_assert, except exceptions are thrown only when NDEBUG is undefined
|
|
|
|
#ifndef jessilib_debug_assert |
|
|
|
#define jessilib_debug_assert(expression) \ |
|
|
|
(::jessilib::impl::_debug_assert_helper( expression, JESSILIB_ASSERT_MESSAGE(expression) )) |
|
|
|
#endif // jessilib_debug_assert
|
|
|
|
|
|
|
|
namespace jessilib { |
|
|
|
|
|
|
|
/** Exception type */ |
|
|
|
class assertion_failed : public std::logic_error { |
|
|
|
public: |
|
|
|
inline explicit assertion_failed(const char* expression) |
|
|
|
: std::logic_error{ expression } { |
|
|
|
} |
|
|
|
}; |
|
|
|
class assertion_failed : public std::logic_error { |
|
|
|
public: |
|
|
|
inline explicit assertion_failed(const char* expression) |
|
|
|
: std::logic_error{ expression } { |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
namespace impl { |
|
|
|
|
|
|
|
/** Macro helpers */ |
|
|
|
inline bool _assert_helper(bool value, [[maybe_unused]] const char* message) { |
|
|
|
#ifndef NDEBUG |
|
|
|
inline bool _assert_helper(bool value, const char* message) { |
|
|
|
if (!value) { |
|
|
|
// TODO: wrap std::cerr
|
|
|
|
std::cerr << message << std::endl; |
|
|
|
|
|
|
|
throw assertion_failed{message}; |
|
|
|
} |
|
|
|
#endif // NDEBUG
|
|
|
|
|
|
|
|
return value; |
|
|
|
} |
|
|
|
|
|
|
|
} // namespace impl
|
|
|
|
} // namespace jessilib
|
|
|
|
inline bool _debug_assert_helper(bool value, const char* message) { |
|
|
|
if (!value) { |
|
|
|
// TODO: wrap std::cerr
|
|
|
|
std::cerr << message << std::endl; |
|
|
|
|
|
|
|
// Provides for disabling of assertions; will likely produce warnings
|
|
|
|
#ifdef DISABLE_ASSERTIONS |
|
|
|
#ifndef NDEBUG |
|
|
|
throw assertion_failed{message}; |
|
|
|
#endif // NDEBUG
|
|
|
|
} |
|
|
|
|
|
|
|
// Disable jessilib_assert
|
|
|
|
#undef jessilib_assert |
|
|
|
#define jessilib_assert(expression) \ |
|
|
|
(true) |
|
|
|
return value; |
|
|
|
} |
|
|
|
|
|
|
|
#endif // DISABLE_ASSERTIONS
|
|
|
|
} // namespace impl
|
|
|
|
} // namespace jessilib
|
|
|
|