1#ifndef GIMBAL_EXCEPTION_HPP
2#define GIMBAL_EXCEPTION_HPP
6#include "../core/gimbal_call_stack.hpp"
7#include "../core/gimbal_api_generators.hpp"
8#include "../types/gimbal_result.hpp"
9#include "../core/gimbal_api_frame.h"
23 virtual const char* what(
void)
const noexcept {
27 virtual const std::exception& asStdException(
void)
const = 0;
28 virtual std::exception& asStdException(
void) = 0;
33 if(record.getResult().isError()) {
34 GBL_API_CLEAR_LAST_RECORD();
35 return throwException(record);
40 static const CallRecord& checkThrow(std::invocable
auto fn) {
41 const GblCallRecord* pRecord =
nullptr;
42 GblThread_callRecordSet(NULL, NULL);
44 pRecord = GblThread_callRecord(NULL);
49 static CallRecord tryCatchRecord(std::invocable
auto fn,
SourceLocation loc=SourceLocation(SRC_FILE,
nullptr, SRC_LN, SRC_COL))
noexcept;
56 TryBlock(
SourceLocation src=SourceLocation(SRC_FILE,
"TryBlock::TryBlock()", SRC_LN, SRC_COL)):
57 record_(Result::Success,
"Success",
nullptr, src) {}
59 TryBlock& operator=(std::invocable
auto fn) {
60 record_ = Exception::tryCatchRecord(std::forward<
decltype(fn)>(fn), std::move(getRecord().getSource()));
64 const CallRecord& getRecord(
void)
const {
return record_; }
65 Result getResult(
void)
const {
return getRecord().getResult(); }
66 const SourceLocation& getSource(
void)
const {
return getRecord().getSource(); }
67 const char* getMessage(
void)
const {
return getRecord().getMessage(); }
69 operator
bool()
const {
return getRecord().getResult().isSuccess(); }
74template<
typename StdType>
84 template<
typename V1,
typename V2>
98 virtual const char* what(
void)
const noexcept override {
102 virtual const std::exception& asStdException(
void)
const override {
106 virtual std::exception& asStdException(
void)
override {
117 }
catch(
const std::underflow_error& ex) {
118 return { Result::ErrorUnderflow, ex.what() };
119 }
catch(
const std::overflow_error& ex) {
120 return { Result::ErrorOverflow, ex.what() };
121 }
catch(
const std::out_of_range& ex) {
122 return { Result::ErrorOutOfRange, ex.what() };
123 }
catch(
const std::invalid_argument& ex) {
124 return { Result::ErrorInvalidArg, ex.what() };
125 }
catch(
const std::bad_alloc& ex) {
126 return { Result::ErrorMemAlloc, ex.what() };
127 }
catch(
const std::exception& stdEx) {
128 return { Result::ErrorUnhandledException, stdEx.what() };
130 return { Result::ErrorUnhandledException,
"Unknown Exception Type!" };
132 return Result::Success;
136 switch(record.getResult().getValue()) {
137 case Result::ErrorUnderflow:
throw StdException<std::underflow_error>(record);
138 case Result::ErrorOverflow:
throw StdException<std::overflow_error>(record);
139 case Result::ErrorOutOfRange:
throw StdException<std::out_of_range>(record);
140 case Result::ErrorInvalidArg:
throw StdException<std::invalid_argument>(record);
141 case Result::ErrorMemAlloc:
142 case Result::ErrorMemRealloc:
throw StdException<std::bad_alloc>(record);
143 default:
throw StdException<std::exception>(record);