00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #pragma once
00018
00019 #include "AITypes.h"
00020 #include "AIAssert.hpp"
00021
00022 #if defined(AI_HAS_RVALUE_REFERENCES) && defined(AI_HAS_DEFAULTED_FUNCTIONS)
00023 #include "IAILiteralString.h"
00024 #endif
00025
00026
00039 class AIErrorThrower
00040 {
00041 public:
00042 AIErrorThrower(AIErr err = kNoErr) : fError(err)
00043 {
00044 check_throw(fError);
00045 }
00046
00047 AIErrorThrower& operator=(AIErr err)
00048 {
00049 fError = err;
00050 check_throw(fError);
00051 return (*this);
00052 }
00053
00054 AIErrorThrower& operator=(AIErrorThrower err)
00055 {
00056 *this = err.fError;
00057 return (*this);
00058 }
00059
00060 operator AIErr() const AINOEXCEPT { return fError; }
00061
00062 private:
00063 void check_throw(AIErr err)
00064 {
00065 if (err != kNoErr)
00066 {
00067 throw ai::Error(err);
00068 }
00069 }
00070
00071 private:
00072 AIErr fError;
00073 };
00074
00083 class AIErrorHandler
00084 {
00085 public:
00086 AIErrorHandler(AIErr err = kNoErr) : fError(err)
00087 {
00088 check_assert(fError);
00089 }
00090
00091 AIErrorHandler& operator=(AIErr err)
00092 {
00093 fError = err;
00094 check_assert(fError);
00095 return (*this);
00096 }
00097
00098 AIErrorHandler& operator=(AIErrorHandler err)
00099 {
00100 *this = err.fError;
00101 return (*this);
00102 }
00103
00104 operator AIErr() const AINOEXCEPT { return fError; }
00105
00106 private:
00107 void check_assert(AIErr err)
00108 {
00109 AIAssert(err == kNoErr || err == kCanceledErr);
00110 }
00111
00112 private:
00113 AIErr fError;
00114 };
00115
00116 namespace ai
00117 {
00118 #if defined(AI_HAS_RVALUE_REFERENCES) && defined(AI_HAS_DEFAULTED_FUNCTIONS)
00119
00120 constexpr AIErr kUnknownExceptionErr { 'UNEX' };
00121
00123 constexpr AIErr kStdExceptionErr { 'STEX' };
00124
00126 constexpr LiteralString kAIErrExceptionStr { "AIErr Exception" };
00127
00129 constexpr LiteralString kUnknownExceptionStr { "Unknown Exception" };
00130 #else // defined(AI_HAS_RVALUE_REFERENCES) && defined(AI_HAS_DEFAULTED_FUNCTIONS)
00131
00132 const AIErr kUnknownExceptionErr = 'UNEX';
00133
00135 const AIErr kStdExceptionErr = 'STEX';
00136 #endif // defined(AI_HAS_RVALUE_REFERENCES) && defined(AI_HAS_DEFAULTED_FUNCTIONS)
00137
00138 }
00139
00140 #define AI_CATCH_RETURN \
00141 catch (const ai::Error& e) { return (AIErr)e; } \
00142 catch (const std::exception&) { return ai::kStdExceptionErr; } \
00143 catch (AIErr e) { return e; } \
00144 catch (...) { return ai::kUnknownExceptionErr; }
00145
00146 #define AI_CATCH_FUNCTION(fn) \
00147 catch (const ai::Error& e) \
00148 { \
00149 fn(e); \
00150 } \
00151 catch (const std::exception& e) \
00152 { \
00153 ai::NOTUSED(e); \
00154 fn(ai::kStdExceptionErr); \
00155 } \
00156 catch (AIErr e) \
00157 { \
00158 fn(e); \
00159 } \
00160 catch (...) \
00161 { \
00162 fn(ai::kUnknownExceptionErr); \
00163 }
00164
00165 #define AI_CATCH_ASSERT_FUNCTION(fn) \
00166 catch (const ai::Error& e) \
00167 { \
00168 AIMsgAssert((AIErr)e == kNoErr || (AIErr)e == kCanceledErr, e.what()); \
00169 fn(e); \
00170 } \
00171 catch (const std::exception& e) \
00172 { \
00173 AIMsgAssert(false, e.what()); \
00174 ai::NOTUSED(e); \
00175 fn(ai::kStdExceptionErr); \
00176 } \
00177 catch (AIErr e) \
00178 { \
00179 AIMsgAssert(e == kNoErr || e == kCanceledErr, ai::kAIErrExceptionStr.c_str()); \
00180 fn(e); \
00181 } \
00182 catch (...) \
00183 { \
00184 AIMsgAssert(false, ai::kUnknownExceptionStr.c_str()); \
00185 fn(ai::kUnknownExceptionErr); \
00186 }
00187
00188 #define AI_CATCH_ASSERT_RETURN_FUNCTION(fn) \
00189 catch (const ai::Error& e) \
00190 { \
00191 AIMsgAssert((AIErr)e == kNoErr || (AIErr)e == kCanceledErr, e.what()); \
00192 return fn(e); \
00193 } \
00194 catch (const std::exception& e) \
00195 { \
00196 AIMsgAssert(false, e.what()); \
00197 ai::NOTUSED(e); \
00198 return fn(ai::kStdExceptionErr); \
00199 } \
00200 catch (AIErr e) \
00201 { \
00202 AIMsgAssert(e == kNoErr || e == kCanceledErr, ai::kAIErrExceptionStr.c_str()); \
00203 return fn(e); \
00204 } \
00205 catch (...) \
00206 { \
00207 AIMsgAssert(false, ai::kUnknownExceptionStr.c_str()); \
00208 return fn(ai::kUnknownExceptionErr); \
00209 }
00210
00211 #define AI_CATCH_ASSERT_RETURN \
00212 catch (const ai::Error& e) \
00213 { \
00214 AIMsgAssert((AIErr)e == kNoErr || (AIErr)e == kCanceledErr, e.what()); \
00215 return (AIErr)e; \
00216 } \
00217 catch (const std::exception& e) \
00218 { \
00219 AIMsgAssert(false, e.what()); \
00220 ai::NOTUSED(e); \
00221 return ai::kStdExceptionErr; \
00222 } \
00223 catch (AIErr e) \
00224 { \
00225 AIMsgAssert(e == kNoErr || e == kCanceledErr, ai::kAIErrExceptionStr.c_str()); \
00226 return e; \
00227 } \
00228 catch (...) \
00229 { \
00230 AIMsgAssert(false, ai::kUnknownExceptionStr.c_str()); \
00231 return ai::kUnknownExceptionErr; \
00232 }
00233
00234 #define AI_CATCH_ASSERT_THROW \
00235 catch (const ai::Error& e) \
00236 { \
00237 AIMsgAssert((AIErr)e == kNoErr || (AIErr)e == kCanceledErr, e.what()); \
00238 ai::NOTUSED(e); \
00239 throw; \
00240 } \
00241 catch (const std::exception& e) \
00242 { \
00243 AIMsgAssert(false, e.what()); \
00244 ai::NOTUSED(e); \
00245 throw; \
00246 } \
00247 catch (AIErr e) \
00248 { \
00249 AIMsgAssert(e == kNoErr || e == kCanceledErr, ai::kAIErrExceptionStr.c_str()); \
00250 ai::NOTUSED(e); \
00251 throw; \
00252 } \
00253 catch (...) \
00254 { \
00255 AIMsgAssert(false, ai::kUnknownExceptionStr.c_str()); \
00256 throw; \
00257 }
00258
00259
00260 #if defined(AI_HAS_RVALUE_REFERENCES) && defined(AI_HAS_DEFAULTED_FUNCTIONS)
00261
00262 #define AI_CATCH_ASSERT_RETURN_ERROR(error) \
00263 catch (const ai::Error& e) \
00264 { \
00265 constexpr AIErr e1{ error }; \
00266 ai::NOTUSED(e1); \
00267 bool isCovered = (AIErr)e == kNoErr || (AIErr)e == kCanceledErr; \
00268 AIMsgAssert(isCovered, e.what()); \
00269 if (!isCovered) \
00270 return error; \
00271 return e; \
00272 } \
00273 catch (const std::exception& e) \
00274 { \
00275 AIMsgAssert(false, e.what()); \
00276 ai::NOTUSED(e); \
00277 return error; \
00278 } \
00279 catch (AIErr e) \
00280 { \
00281 bool isCovered = e == kNoErr || e == kCanceledErr; \
00282 AIMsgAssert(isCovered, ai::kAIErrExceptionStr.c_str()); \
00283 if (!isCovered) \
00284 return error; \
00285 return e; \
00286 } \
00287 catch (...) \
00288 { \
00289 AIMsgAssert(false, ai::kUnknownExceptionStr.c_str()); \
00290 return error; \
00291 }
00292
00293
00294 #define AI_CATCH_RETURN_ERROR(error) \
00295 catch (const ai::Error& e) \
00296 { \
00297 constexpr AIErr e1{ error };\
00298 ai::NOTUSED(e1);\
00299 if ((AIErr)e != kNoErr && (AIErr)e != kCanceledErr) \
00300 return error; \
00301 return e; \
00302 } \
00303 catch (const std::exception&) \
00304 { \
00305 return error; \
00306 } \
00307 catch (AIErr e) \
00308 { \
00309 if (e != kNoErr && e != kCanceledErr) \
00310 return error; \
00311 return e; \
00312 } \
00313 catch (...) \
00314 { \
00315 return error; \
00316 }
00317
00318 #else // defined(AI_HAS_RVALUE_REFERENCES) && defined(AI_HAS_DEFAULTED_FUNCTIONS)
00319 #define AI_CATCH_ASSERT_RETURN_ERROR(error) \
00320 catch (const ai::Error& e) \
00321 { \
00322 bool isCovered = (AIErr)e == kNoErr || (AIErr)e == kCanceledErr; \
00323 AIMsgAssert(isCovered, e.what()); \
00324 if (!isCovered) \
00325 return error; \
00326 return e; \
00327 } \
00328 catch (const std::exception& e) \
00329 { \
00330 AIMsgAssert(false, e.what()); \
00331 ai::NOTUSED(e); \
00332 return error; \
00333 } \
00334 catch (AIErr e) \
00335 { \
00336 bool isCovered = e == kNoErr || e == kCanceledErr; \
00337 AIMsgAssert(isCovered, ai::kAIErrExceptionStr.c_str()); \
00338 if (!isCovered) \
00339 return error; \
00340 return e; \
00341 } \
00342 catch (...) \
00343 { \
00344 AIMsgAssert(false, ai::kUnknownExceptionStr.c_str()); \
00345 return error; \
00346 }
00347
00348 #define AI_CATCH_RETURN_ERROR(error) \
00349 catch (const ai::Error& e) \
00350 { \
00351 if ((AIErr)e != kNoErr && (AIErr)e != kCanceledErr) \
00352 return error; \
00353 return e; \
00354 } \
00355 catch (const std::exception&) \
00356 { \
00357 return error; \
00358 } \
00359 catch (AIErr e) \
00360 { \
00361 if (e != kNoErr && e != kCanceledErr) \
00362 return error; \
00363 return e; \
00364 } \
00365 catch (...) \
00366 { \
00367 return error; \
00368 }
00369 #endif //defined(AI_HAS_RVALUE_REFERENCES) && defined(AI_HAS_DEFAULTED_FUNCTIONS)
00370
00371 #define AI_CATCH_NO_RETURN \
00372 catch (const ai::Error& ) \
00373 { \
00374 } \
00375 catch (const std::exception& ) \
00376 { \
00377 } \
00378 catch (AIErr) \
00379 { \
00380 } \
00381 catch (...) \
00382 { \
00383 }
00384
00385 #define AI_CATCH_ASSERT_NO_RETURN \
00386 catch (const ai::Error& e) \
00387 { \
00388 AIMsgAssert((AIErr)e == kNoErr || (AIErr)e == kCanceledErr, e.what()); \
00389 ai::NOTUSED(e); \
00390 } \
00391 catch (const std::exception& e) \
00392 { \
00393 AIMsgAssert(false, e.what()); \
00394 ai::NOTUSED(e); \
00395 } \
00396 catch (AIErr e) \
00397 { \
00398 AIMsgAssert(e == kNoErr || e == kCanceledErr, ai::kAIErrExceptionStr.c_str());\
00399 ai::NOTUSED(e); \
00400 } \
00401 catch (...) \
00402 { \
00403 AIMsgAssert(false, ai::kUnknownExceptionStr.c_str()); \
00404 }