exception.hpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #pragma once
  2. #include <exception>
  3. #include <string>
  4. #include <vector>
  5. #include <utility>
  6. namespace nkg {
  7. class exception : public std::exception {
  8. private:
  9. int m_source_line;
  10. std::string m_source_file;
  11. std::string m_custom_message;
  12. std::vector<std::string> m_hints;
  13. public:
  14. [[noreturn]]
  15. static void trap_then_terminate() {
  16. #if _MSC_VER
  17. __debugbreak();
  18. #elif defined(__GNUC__) || defined(__GNUG__) || defined(__clang__)
  19. __builtin_trap();
  20. #else
  21. #error "exception.hpp: unknown compiler is detected."
  22. #endif
  23. std::terminate();
  24. }
  25. exception(std::string_view file, int line, std::string_view message) noexcept :
  26. std::exception(), m_source_line(line), m_source_file(file), m_custom_message(message) {}
  27. exception(const exception&) noexcept = default;
  28. exception(exception&&) noexcept = default;
  29. exception& operator=(const exception&) noexcept = default;
  30. exception& operator=(exception&&) noexcept = default;
  31. [[nodiscard]]
  32. int source_line() const noexcept {
  33. return m_source_line;
  34. }
  35. [[nodiscard]]
  36. const std::string& source_file() const noexcept {
  37. return m_source_file;
  38. }
  39. [[nodiscard]]
  40. const std::string& custom_message() const noexcept {
  41. return m_custom_message;
  42. }
  43. exception&& push_hint(std::string_view hint) noexcept {
  44. m_hints.emplace_back(hint);
  45. return std::move(*this);
  46. }
  47. exception&& pop_hint() noexcept {
  48. m_hints.pop_back();
  49. return std::move(*this);
  50. }
  51. const std::vector<std::string>& hints() const noexcept {
  52. return m_hints;
  53. }
  54. virtual const char* what() const noexcept override {
  55. return m_custom_message.c_str();
  56. }
  57. [[nodiscard]]
  58. virtual bool error_code_exists() const noexcept {
  59. return false;
  60. }
  61. [[nodiscard]]
  62. virtual intptr_t error_code() const noexcept {
  63. trap_then_terminate();
  64. }
  65. [[nodiscard]]
  66. virtual const std::string& error_string() const noexcept {
  67. trap_then_terminate();
  68. }
  69. virtual ~exception() override = default;
  70. };
  71. }