exception.hpp 2.1 KB

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