NavicatCrack/common/exception.hpp

86 lines
2.1 KiB
C++

#pragma once
#include <exception>
#include <string>
#include <vector>
namespace nkg {
class exception : public std::exception {
private:
int m_source_line;
std::string m_source_file;
std::string m_custom_message;
std::vector<std::string> m_hints;
public:
[[noreturn]]
static void trap_then_terminate() {
#if _MSC_VER
__debugbreak();
#elif defined(__GNUC__) || defined(__GNUG__) || defined(__clang__)
__builtin_trap();
#else
#error "exception.hpp: unknown compiler is detected."
#endif
std::terminate();
}
exception(std::string_view file, int line, std::string_view message) noexcept :
std::exception(), // don't pass `char*` to `std::exception`, because it is not documented in c++ standard.
m_source_line(line),
m_source_file(file),
m_custom_message(message) {}
[[nodiscard]]
int source_line() const noexcept {
return m_source_line;
}
[[nodiscard]]
const std::string& source_file() const noexcept {
return m_source_file;
}
[[nodiscard]]
const std::string& custom_message() const noexcept {
return m_custom_message;
}
exception& push_hint(std::string_view hint) noexcept {
m_hints.emplace_back(hint);
return *this;
}
exception& pop_hint() noexcept {
m_hints.pop_back();
return *this;
}
const std::vector<std::string>& hints() const noexcept {
return m_hints;
}
virtual const char* what() const noexcept override {
return m_custom_message.c_str();
}
[[nodiscard]]
virtual bool error_code_exists() const noexcept {
return false;
}
[[nodiscard]]
virtual intptr_t error_code() const noexcept {
trap_then_terminate();
}
[[nodiscard]]
virtual const std::string& error_string() const noexcept {
trap_then_terminate();
}
virtual ~exception() = default;
};
}