Select Git revision
PugsParser.cpp
-
Stéphane Del Pino authoredStéphane Del Pino authored
PugsAssert.hpp 2.89 KiB
#ifndef PUGS_ASSERT_HPP
#define PUGS_ASSERT_HPP
#include <PugsMacros.hpp>
#include <iostream>
#include <rang.hpp>
#include <string>
class AssertError
{
private:
const std::string m_file;
const int m_line;
const std::string m_function;
const std::string m_test;
const std::string m_message;
public:
friend std::ostream&
operator<<(std::ostream& os, const AssertError& assert_error)
{
os << '\n'
<< rang::style::bold << "---------- Assertion error -----------\n"
<< " at " << assert_error.m_file << ':' << assert_error.m_line << '\n'
<< " in " << assert_error.m_function << '\n'
<< " assertion (" << rang::fgB::red << assert_error.m_test << rang::fg::reset << ") failed!\n";
if (not assert_error.m_message.empty()) {
os << ' ' << rang::fgB::yellow << assert_error.m_message << rang::fg::reset << '\n';
}
os << "--------------------------------------" << rang::style::reset << '\n';
return os;
}
AssertError(const AssertError&) = default;
AssertError(std::string file, int line, std::string function, std::string test, std::string message = "")
: m_file(file), m_line(line), m_function(function), m_test(test), m_message(message)
{
;
}
~AssertError() = default;
};
PRAGMA_DIAGNOSTIC_IGNORED_WATTRIBUTES
inline bool __attribute__((analyzer_noreturn)) _pugs_assert(const bool& assert)
{
return assert;
}
PRAGMA_DIAGNOSTIC_POP
#ifdef NDEBUG
// Useless test is there to check syntax even in optimized mode. Costs nothing.
#define Assert(assertion, ...) \
if (not _pugs_assert(assertion)) { \
using vargs_t = decltype(std::make_tuple(__VA_ARGS__)); \
static_assert(std::tuple_size_v<vargs_t> <= 1, "too many arguments"); \
}
#else // NDEBUG
#define Assert(assertion, ...) \
if (not _pugs_assert(assertion)) { \
using vargs_t = decltype(std::make_tuple(__VA_ARGS__)); \
static_assert(std::tuple_size_v<vargs_t> <= 1, "too many arguments"); \
if constexpr (std::tuple_size_v<vargs_t> == 0) { \
throw AssertError(__FILE__, __LINE__, __PRETTY_FUNCTION__, #assertion); \
} else { \
throw AssertError(__FILE__, __LINE__, __PRETTY_FUNCTION__, #assertion, #__VA_ARGS__); \
} \
}
#endif // NDEBUG
// store the current state of Assert macro. This is useful for
// instance to noexcept management of Assert throws
#ifdef NDEBUG
#define NO_ASSERT true
#else // NDEBUG
#define NO_ASSERT false
#endif // NDEBUG
#endif // PUGS_ASSERT_HPP