2018-12-28 19:54:04 +05:00
|
|
|
#ifndef NETGEN_CORE_EXCEPTION_HPP
|
|
|
|
#define NETGEN_CORE_EXCEPTION_HPP
|
|
|
|
|
2024-12-02 23:35:49 +05:00
|
|
|
#include <cstddef>
|
2018-12-28 19:54:04 +05:00
|
|
|
#include <sstream> // for stringstream
|
|
|
|
#include <stdexcept> // for exception
|
|
|
|
#include <string> // for string
|
|
|
|
|
|
|
|
#include "ngcore_api.hpp" // for NGCORE_API
|
2024-11-21 00:52:54 +05:00
|
|
|
#include "utils.hpp" // for ToString
|
2018-12-28 19:54:04 +05:00
|
|
|
|
2019-09-23 17:01:35 +05:00
|
|
|
|
2018-12-28 19:54:04 +05:00
|
|
|
namespace ngcore
|
|
|
|
{
|
2019-09-23 17:01:35 +05:00
|
|
|
NGCORE_API std::string GetBackTrace();
|
|
|
|
|
2018-12-28 19:54:04 +05:00
|
|
|
// Exception for code that shouldn't be executed
|
|
|
|
class NGCORE_API UnreachableCodeException : public std::exception
|
|
|
|
{
|
|
|
|
const char* what() const noexcept override
|
|
|
|
{
|
|
|
|
return "Shouldn't get here, something went wrong!";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Default exception class
|
|
|
|
class NGCORE_API Exception : public std::exception
|
|
|
|
{
|
|
|
|
/// a verbal description of the exception
|
|
|
|
std::string m_what;
|
|
|
|
public:
|
|
|
|
Exception() = default;
|
|
|
|
Exception(const Exception&) = default;
|
|
|
|
Exception(Exception&&) = default;
|
2019-11-29 20:26:20 +05:00
|
|
|
Exception(const std::string& s); // : m_what(s) {}
|
|
|
|
Exception(const char* s); // : m_what(s) {}
|
2024-07-17 15:01:59 +05:00
|
|
|
Exception(std::string_view s1, std::string_view s2);
|
|
|
|
Exception(std::string_view s1, std::string_view s2, std::string_view s3);
|
2018-12-28 19:54:04 +05:00
|
|
|
~Exception() override = default;
|
|
|
|
|
2024-07-17 20:58:38 +05:00
|
|
|
[[noreturn]] static void Throw (std::string_view s1);
|
|
|
|
[[noreturn]] static void Throw (std::string_view s1, std::string_view s2);
|
|
|
|
[[noreturn]] static void Throw (std::string_view s1, std::string_view s2, std::string_view s3);
|
|
|
|
|
2018-12-28 19:54:04 +05:00
|
|
|
Exception& operator =(const Exception&) = default;
|
|
|
|
Exception& operator =(Exception&&) noexcept = default;
|
|
|
|
|
|
|
|
/// append string to description
|
|
|
|
Exception & Append (const std::string & s) { m_what += s; return *this; }
|
|
|
|
/// append string to description
|
|
|
|
Exception & Append (const char * s) { m_what += s; return *this; }
|
|
|
|
|
|
|
|
/// verbal description of exception
|
|
|
|
const std::string & What() const { return m_what; }
|
|
|
|
|
|
|
|
/// implement virtual function of std::exception
|
|
|
|
const char* what() const noexcept override { return m_what.c_str(); }
|
|
|
|
};
|
2019-11-25 11:46:21 +05:00
|
|
|
|
2024-07-20 01:30:34 +05:00
|
|
|
[[noreturn]] NGCORE_API void ThrowException(const std::string & s);
|
|
|
|
[[noreturn]] NGCORE_API void ThrowException(const char * s);
|
2019-11-25 11:46:21 +05:00
|
|
|
|
2018-12-28 19:54:04 +05:00
|
|
|
// Out of Range exception
|
|
|
|
class NGCORE_API RangeException : public Exception
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/// where it occurs, index, minimal and maximal indices
|
2024-07-16 13:18:16 +05:00
|
|
|
RangeException (// const std::string & where,
|
|
|
|
const char * where,
|
2024-12-02 23:35:49 +05:00
|
|
|
ptrdiff_t ind, ptrdiff_t imin, ptrdiff_t imax);
|
2024-07-16 13:18:16 +05:00
|
|
|
/*
|
|
|
|
: Exception("")
|
2018-12-28 19:54:04 +05:00
|
|
|
{
|
|
|
|
std::stringstream str;
|
2019-08-05 15:48:08 +05:00
|
|
|
str << where << ": index " << ind << " out of range [" << imin << "," << imax << ")\n";
|
2018-12-28 19:54:04 +05:00
|
|
|
Append (str.str());
|
2019-09-23 17:01:35 +05:00
|
|
|
Append (GetBackTrace());
|
2018-12-28 19:54:04 +05:00
|
|
|
}
|
2024-07-16 13:18:16 +05:00
|
|
|
*/
|
2019-01-02 20:30:55 +05:00
|
|
|
template<typename T>
|
|
|
|
RangeException(const std::string& where, const T& value)
|
|
|
|
{
|
|
|
|
std::stringstream str;
|
|
|
|
str << where << " called with wrong value " << value << "\n";
|
|
|
|
Append(str.str());
|
|
|
|
}
|
2018-12-28 19:54:04 +05:00
|
|
|
};
|
|
|
|
|
2024-12-02 23:35:49 +05:00
|
|
|
[[noreturn]] NGCORE_API void ThrowRangeException(const char * s, ptrdiff_t ind, ptrdiff_t imin, ptrdiff_t imax);
|
|
|
|
[[noreturn]] NGCORE_API void ThrowNotTheSameException(const char * s, ptrdiff_t a, ptrdiff_t b);
|
2024-07-16 13:18:16 +05:00
|
|
|
|
|
|
|
|
2018-12-28 19:54:04 +05:00
|
|
|
// Exception used if no simd implementation is available to fall back to standard evaluation
|
|
|
|
class NGCORE_API ExceptionNOSIMD : public Exception
|
|
|
|
{ public: using Exception::Exception; };
|
2024-11-21 00:52:54 +05:00
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
struct IsSafe {
|
|
|
|
constexpr operator bool() const { return false; } };
|
|
|
|
|
|
|
|
namespace detail {
|
2024-12-02 23:35:49 +05:00
|
|
|
template <typename T, typename Tmin, typename Tmax>
|
|
|
|
inline static void CheckRange(const char * s, const T& n, Tmin first, Tmax next)
|
2024-11-21 00:52:54 +05:00
|
|
|
{
|
|
|
|
if constexpr (!IsSafe<decltype(n)>())
|
|
|
|
if (n<first || n>=next)
|
2024-12-02 23:35:49 +05:00
|
|
|
ThrowRangeException(s, ptrdiff_t(n), ptrdiff_t(first), ptrdiff_t(next));
|
2024-11-21 00:52:54 +05:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename Ta, typename Tb>
|
|
|
|
inline static void CheckSame(const char * s, const Ta& a, const Tb& b)
|
|
|
|
{
|
|
|
|
if constexpr (!IsSafe<decltype(a)>() || !IsSafe<decltype(b)>())
|
|
|
|
if(a != b)
|
|
|
|
{
|
2024-12-02 23:35:49 +05:00
|
|
|
if constexpr(std::is_integral_v<decltype(a)> && std::is_same_v<decltype(a),decltype(b)>)
|
2024-11-21 00:52:54 +05:00
|
|
|
ThrowNotTheSameException(s, long(a), long(b)); \
|
|
|
|
else
|
2024-12-02 23:35:49 +05:00
|
|
|
throw Exception(std::string(s) + "\t: not the same, a="+ToString(a) + ", b="+ngcore::ToString(b) + GetBackTrace());
|
2024-11-21 00:52:54 +05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} // namespace detail
|
2018-12-28 19:54:04 +05:00
|
|
|
} // namespace ngcore
|
|
|
|
|
2019-01-02 20:30:55 +05:00
|
|
|
#define NETGEN_CORE_NGEXEPTION_STR_HELPER(x) #x
|
|
|
|
#define NETGEN_CORE_NGEXEPTION_STR(x) NETGEN_CORE_NGEXEPTION_STR_HELPER(x)
|
|
|
|
|
|
|
|
// Convenience macro to append file name and line of exception origin to the string
|
|
|
|
#define NG_EXCEPTION(s) ngcore::Exception(__FILE__ ":" NETGEN_CORE_NGEXEPTION_STR(__LINE__) "\t"+std::string(s))
|
|
|
|
|
2023-02-16 16:55:12 +05:00
|
|
|
#if defined(NETGEN_ENABLE_CHECK_RANGE) && !defined(__CUDA_ARCH__)
|
2024-12-02 23:35:49 +05:00
|
|
|
#define NETGEN_CHECK_RANGE(value, min, max_plus_one) ngcore::detail::CheckRange(__FILE__ ":" NETGEN_CORE_NGEXEPTION_STR(__LINE__) "\t", value, min, max_plus_one);
|
2024-11-21 00:52:54 +05:00
|
|
|
#define NETGEN_CHECK_SAME(a,b) ngcore::detail::CheckSame(__FILE__ ":" NETGEN_CORE_NGEXEPTION_STR(__LINE__) "\t", a, b);
|
|
|
|
|
2023-08-04 12:22:34 +05:00
|
|
|
#define NETGEN_NOEXCEPT
|
2023-02-16 16:55:12 +05:00
|
|
|
#else // defined(NETGEN_ENABLE_CHECK_RANGE) && !defined(__CUDA_ARCH__)
|
2019-01-02 20:30:55 +05:00
|
|
|
#define NETGEN_CHECK_RANGE(value, min, max)
|
2023-08-21 09:13:13 +05:00
|
|
|
#define NETGEN_CHECK_SAME(a,b)
|
2024-07-16 13:18:16 +05:00
|
|
|
// #define NETGEN_CHECK_SHAPE(a,b)
|
2023-08-04 12:22:34 +05:00
|
|
|
#define NETGEN_NOEXCEPT noexcept
|
2023-02-16 16:55:12 +05:00
|
|
|
#endif // defined(NETGEN_ENABLE_CHECK_RANGE) && !defined(__CUDA_ARCH__)
|
2019-01-02 20:30:55 +05:00
|
|
|
|
2022-05-01 14:56:22 +05:00
|
|
|
|
|
|
|
|
2018-12-28 19:54:04 +05:00
|
|
|
#endif // NETGEN_CORE_EXCEPTION_HPP
|