netgen/libsrc/core/exception.hpp

145 lines
5.1 KiB
C++
Raw Normal View History

2018-12-28 19:54:04 +05:00
#ifndef NETGEN_CORE_EXCEPTION_HPP
#define NETGEN_CORE_EXCEPTION_HPP
#include <sstream> // for stringstream
#include <stdexcept> // for exception
#include <string> // for string
#include "ngcore_api.hpp" // for NGCORE_API
#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;
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(); }
};
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);
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
RangeException (// const std::string & where,
const char * where,
int ind, int imin, int imax);
/*
: 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
}
*/
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-07-20 01:30:34 +05:00
[[noreturn]] NGCORE_API void ThrowRangeException(const char * s, int ind, int imin, int imax);
[[noreturn]] NGCORE_API void ThrowNotTheSameException(const char * s, long int a, long int b);
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; };
template <typename T>
struct IsSafe {
constexpr operator bool() const { return false; } };
namespace detail {
template <typename T>
inline static void CheckRange(const char * s, const T& n, int first, int next)
{
if constexpr (!IsSafe<decltype(n)>())
if (n<first || n>=next)
ThrowRangeException(s, int(n), first, next);
}
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)
{
if constexpr(std::is_same<decltype(a),size_t>() && std::is_same<decltype(b),size_t>())
ThrowNotTheSameException(s, long(a), long(b)); \
else
throw Exception(std::string(s) + "\t: not the same"+ToString(a) + ", b="+ngcore::ToString(b) + GetBackTrace());
}
}
} // namespace detail
2018-12-28 19:54:04 +05:00
} // namespace ngcore
#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__)
#define NETGEN_CHECK_RANGE(value, min, max_plus_one) ngcore::detail::CheckRange(__FILE__ ":" NETGEN_CORE_NGEXEPTION_STR(__LINE__) "\t", value, int(min), int(max_plus_one));
#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__)
#define NETGEN_CHECK_RANGE(value, min, max)
2023-08-21 09:13:13 +05:00
#define NETGEN_CHECK_SAME(a,b)
// #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__)
2022-05-01 14:56:22 +05:00
2018-12-28 19:54:04 +05:00
#endif // NETGEN_CORE_EXCEPTION_HPP