Rename Assert macro to Ensure, clean up exception to be in line with THROW.
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Deukhoofd 2020-12-13 11:41:41 +01:00
parent 4466aeeee6
commit 4e854516c1
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
9 changed files with 67 additions and 68 deletions

View File

@ -1,38 +1,36 @@
/** @file */ /** @file */
#include "Exception.hpp" #include "Exception.hpp"
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) /// \defgroup Ensure Ensure
/// \brief A set of ensure macros.
/// \defgroup Asserts Asserts #ifndef NO_ENSURE
/// \brief A set of assertion macros. /// @brief Ensures an expression is true. Throws an exception if the assertion fails.
/// @ingroup Ensure
#ifndef NO_ASSERT #define Ensure(expr) \
/// @brief Asserts an expression is true. Throws an exception if the assertion fails.
/// @ingroup Asserts
#define Assert(expr) \
if (!(expr)) { \ if (!(expr)) { \
std::stringstream ss; \ std::stringstream ss; \
ss << "ASSERTION FAILED: [" << __FILENAME__ << " (" << __LINE__ << ")] \""; \ ss << "[" << file_name(__FILE__) << ":" << __LINE__ << "] ENSURE FAILED: \""; \
ss << #expr << "\""; \ ss << #expr << "\""; \
throw ArbUt::Exception(ss.str()); \ throw ArbUt::Exception(ss.str()); \
} }
/// @brief Asserts an expression is true for a range. The value in the range can be retrieved using ``item``. /// @brief Ensures an expression is true for a range. The value in the range can be retrieved using ``item``.
/// @ingroup Asserts /// @ingroup Ensure
#define AssertForEach(iterator, assertion) \ #define EnsureForEach(iterator, assertion) \
{ \ { \
for (auto item : (iterator)) \ for (auto item : (iterator)) \
Assert(assertion) \ Ensure(assertion) \
} }
#else #else
// Assert is empty if NO_ASSERT is defined. // Ensure is empty if NO_ENSURE is defined.
#define Assert(expr) ; #define Ensure(expr) ;
#define AssertForEach(iterator, assertion) ; #define EnsureForEach(iterator, assertion) ;
#endif #endif
/// @brief Asserts a pointer is not null. /// @brief Ensures a pointer is not null.
/// @ingroup Asserts /// @ingroup Ensure
#define AssertNotNull(value) Assert((value) != nullptr) #define EnsureNotNull(value) Ensure((value) != nullptr)
/// @brief Asserts a range is not null. /// @brief Ensures a range is not null.
/// @ingroup Asserts /// @ingroup Ensure
#define AssertAllNotNull(iterator) AssertForEach(iterator, item != nullptr) #define EnsureAllNotNull(iterator) EnsureForEach(iterator, item != nullptr)

View File

@ -140,9 +140,13 @@ namespace ArbUt {
}; };
} }
static constexpr const char* file_name(const char* path) { #if !__cpp_consteval
#define consteval constexpr
#endif
static consteval const char* file_name(const char* path) {
const char* file = path; const char* file = path;
while (*path) { while (*path != 0) {
if (*path++ == '/') { if (*path++ == '/') {
file = path; file = path;
} }

View File

@ -16,7 +16,7 @@ namespace ArbUt {
public: public:
inline BorrowedPtr<T>() {} inline BorrowedPtr<T>() {}
/// @brief Initialise a BorrowedPtr with a specific raw pointer. /// @brief Initialise a BorrowedPtr with a specific raw pointer.
inline BorrowedPtr<T>(T* ptr) : _raw(ptr) { AssertNotNull(ptr); }; inline BorrowedPtr<T>(T* ptr) : _raw(ptr) { EnsureNotNull(ptr); };
/// @brief Initialise a BorrowedPtr from a copy. /// @brief Initialise a BorrowedPtr from a copy.
inline BorrowedPtr<T>(const BorrowedPtr<T>& other) : _raw(other._raw){}; inline BorrowedPtr<T>(const BorrowedPtr<T>& other) : _raw(other._raw){};
/// @brief Initialise a BorrowedPtr with a std unique_ptr. /// @brief Initialise a BorrowedPtr with a std unique_ptr.
@ -39,7 +39,7 @@ namespace ArbUt {
if (_raw == rhs) { if (_raw == rhs) {
return *this; return *this;
} }
AssertNotNull(rhs); EnsureNotNull(rhs);
_raw = rhs; _raw = rhs;
return *this; return *this;
} }

View File

@ -43,7 +43,7 @@ namespace ArbUt {
/// @brief Operator for access into underlying pointer. /// @brief Operator for access into underlying pointer.
/// @warning Note that this asserts that the underlying pointer is not null first, to prevent segfaults. /// @warning Note that this asserts that the underlying pointer is not null first, to prevent segfaults.
inline T* operator->() const noexcept { inline T* operator->() const noexcept {
AssertNotNull(_raw); EnsureNotNull(_raw);
return _raw; return _raw;
} }

View File

@ -16,7 +16,7 @@ namespace ArbUt {
public: public:
inline UniquePtr<T>() {} inline UniquePtr<T>() {}
/// @brief Initialise a UniquePtr with a specific raw pointer. /// @brief Initialise a UniquePtr with a specific raw pointer.
inline UniquePtr<T>(T* ptr) : _raw(ptr) { AssertNotNull(ptr); }; inline UniquePtr<T>(T* ptr) : _raw(ptr) { EnsureNotNull(ptr); };
/// @brief Initialise a UniquePtr from a copy. /// @brief Initialise a UniquePtr from a copy.
inline UniquePtr<T>(const UniquePtr<T>& other) : _raw(other._raw){}; inline UniquePtr<T>(const UniquePtr<T>& other) : _raw(other._raw){};
/// @brief Initialise a UniquePtr with a std unique_ptr. /// @brief Initialise a UniquePtr with a std unique_ptr.
@ -42,7 +42,7 @@ namespace ArbUt {
return *this; return *this;
} }
delete _raw; delete _raw;
AssertNotNull(rhs); EnsureNotNull(rhs);
_raw = rhs; _raw = rhs;
return *this; return *this;
} }

View File

@ -17,7 +17,7 @@ namespace ArbUt {
inline UniquePtrList() noexcept : _vector() {} inline UniquePtrList() noexcept : _vector() {}
/// @brief Initialises a UniquePtrList from a std::vector of raw pointers. /// @brief Initialises a UniquePtrList from a std::vector of raw pointers.
/// @param vec A std::vector of raw pointers. /// @param vec A std::vector of raw pointers.
inline UniquePtrList(const std::vector<ValueT*>& vec) noexcept : _vector(vec) { AssertAllNotNull(vec); } inline UniquePtrList(const std::vector<ValueT*>& vec) noexcept : _vector(vec) { EnsureAllNotNull(vec); }
/// @brief Initialises a UniquePtrList with a certain capacity reserved for use. This does not set immediate /// @brief Initialises a UniquePtrList with a certain capacity reserved for use. This does not set immediate
/// size. /// size.
/// @param capacity The desired capacity. /// @param capacity The desired capacity.
@ -25,13 +25,13 @@ namespace ArbUt {
/// @brief Initialises a UniquePtrList from a initialiser_list. /// @brief Initialises a UniquePtrList from a initialiser_list.
/// @param l A initialiser_list /// @param l A initialiser_list
inline UniquePtrList(const std::initializer_list<ValueT*>& l) noexcept : _vector(l) { inline UniquePtrList(const std::initializer_list<ValueT*>& l) noexcept : _vector(l) {
AssertAllNotNull(_vector); EnsureAllNotNull(_vector);
} }
/// @brief Initialises a UniquePtrList from a raw pointer range. /// @brief Initialises a UniquePtrList from a raw pointer range.
/// @param begin The raw pointer to the start of the list. /// @param begin The raw pointer to the start of the list.
/// @param end The raw pointer to the end of the list. /// @param end The raw pointer to the end of the list.
inline UniquePtrList(ValueT* const* begin, ValueT* const* end) noexcept : _vector(begin, end) { inline UniquePtrList(ValueT* const* begin, ValueT* const* end) noexcept : _vector(begin, end) {
AssertAllNotNull(_vector); EnsureAllNotNull(_vector);
} }
UniquePtrList(const UniquePtrList<ValueT>&) = delete; UniquePtrList(const UniquePtrList<ValueT>&) = delete;
@ -80,7 +80,7 @@ namespace ArbUt {
/// @param index The index to set the pointer to. /// @param index The index to set the pointer to.
/// @param ptr The pointer to store. /// @param ptr The pointer to store.
void Set(size_t index, ValueT* ptr) { void Set(size_t index, ValueT* ptr) {
AssertNotNull(ptr); EnsureNotNull(ptr);
delete _vector[index]; delete _vector[index];
_vector[index] = ptr; _vector[index] = ptr;
} }
@ -119,7 +119,7 @@ namespace ArbUt {
/// @brief Append a pointer to the list. /// @brief Append a pointer to the list.
/// @param value The pointer to push to the list. /// @param value The pointer to push to the list.
inline void Append(ValueT* value) { inline void Append(ValueT* value) {
AssertNotNull(value); EnsureNotNull(value);
_vector.push_back(value); _vector.push_back(value);
} }
/// @brief Borrow a pointer at a certain index. /// @brief Borrow a pointer at a certain index.

View File

@ -43,7 +43,7 @@ namespace ArbUt {
/// @brief Gets a random 32 bit integer between 0, and given max parameter. /// @brief Gets a random 32 bit integer between 0, and given max parameter.
/// @param max The exclusive max value the random value should be. /// @param max The exclusive max value the random value should be.
[[nodiscard]] inline int32_t Get(int32_t max) { [[nodiscard]] inline int32_t Get(int32_t max) {
Assert(max > 0); Ensure(max > 0);
std::uniform_int_distribution<int32_t> distribution(0, max - 1); std::uniform_int_distribution<int32_t> distribution(0, max - 1);
return distribution(_rng); return distribution(_rng);
} }
@ -52,7 +52,7 @@ namespace ArbUt {
/// @param min The inclusive min value the random value should be. /// @param min The inclusive min value the random value should be.
/// @param max The exclusive max value the random value should be. /// @param max The exclusive max value the random value should be.
[[nodiscard]] inline int32_t Get(int32_t min, int32_t max) { [[nodiscard]] inline int32_t Get(int32_t min, int32_t max) {
Assert(max > min); Ensure(max > min);
std::uniform_int_distribution<int32_t> distribution(min, max - 1); std::uniform_int_distribution<int32_t> distribution(min, max - 1);
return distribution(_rng); return distribution(_rng);
} }
@ -71,7 +71,7 @@ namespace ArbUt {
/// @param min The inclusive min value the random value should be. /// @param min The inclusive min value the random value should be.
/// @param max The exclusive max value the random value should be. /// @param max The exclusive max value the random value should be.
[[nodiscard]] inline uint32_t GetUnsigned(uint32_t min, uint32_t max) { [[nodiscard]] inline uint32_t GetUnsigned(uint32_t min, uint32_t max) {
Assert(max > min); Ensure(max > min);
std::uniform_int_distribution<uint32_t> distribution(min, max - 1); std::uniform_int_distribution<uint32_t> distribution(min, max - 1);
return distribution(_rng); return distribution(_rng);
} }

View File

@ -1,31 +0,0 @@
#include "../extern/doctest.hpp"
#include "../src/Assert.hpp"
void TestWrapper(bool wrapperExpression) { Assert(wrapperExpression) }
void TestWrapperNotNull(void* value) { AssertNotNull(value) }
TEST_CASE("Assert succeeds if true") { REQUIRE_NOTHROW(TestWrapper(true)); }
TEST_CASE("Assert throws if false") { REQUIRE_THROWS(TestWrapper(false)); }
TEST_CASE("Assert throws if false with message") {
try {
TestWrapper(false);
} catch (const ArbUt::Exception& e) {
REQUIRE(strcmp(e.what(), "ASSERTION FAILED: [AssertTests.cpp (3)] \"wrapperExpression\"") == 0);
return;
}
throw ArbUt::Exception("Didn't throw.");
}
TEST_CASE("Multiple asserts") {
Assert(true)
Assert(true)
Assert(true)
}
TEST_CASE("AssertNotNull throws if nullptr") { REQUIRE_THROWS(TestWrapperNotNull(nullptr)); }
TEST_CASE("Assert for each") {
auto i = {10, 500, 2300, 454};
AssertForEach(i, item > 0)
}

28
tests/EnsureTests.cpp Normal file
View File

@ -0,0 +1,28 @@
#include "../extern/doctest.hpp"
#include "../src/Assert.hpp"
void TestWrapper(bool wrapperExpression) { Ensure(wrapperExpression) }
void TestWrapperNotNull(void* value) {EnsureNotNull(value) }
TEST_CASE("Ensure succeeds if true") { REQUIRE_NOTHROW(TestWrapper(true)); }
TEST_CASE("Ensure throws if false") { REQUIRE_THROWS(TestWrapper(false)); }
TEST_CASE("Ensure throws if false with message") {
try {
TestWrapper(false);
} catch (const ArbUt::Exception& e) {
REQUIRE(std::string(e.what()) == "[EnsureTests.cpp:3] ENSURE FAILED: \"wrapperExpression\"");
return;
}
throw ArbUt::Exception("Didn't throw.");
}
TEST_CASE("Multiple asserts") {Ensure(true) Ensure(true) Ensure(true)
}
TEST_CASE("EnsureNotNull throws if nullptr") { REQUIRE_THROWS(TestWrapperNotNull(nullptr)); }
TEST_CASE("Ensure for each") {
auto i = {10, 500, 2300, 454};
EnsureForEach(i, item > 0)
}