diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/result.h | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/src/core/hle/result.h b/src/core/hle/result.h index 82dcf5bba..ad06d00aa 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h | |||
| @@ -9,8 +9,9 @@ | |||
| 9 | #include <type_traits> | 9 | #include <type_traits> |
| 10 | #include <utility> | 10 | #include <utility> |
| 11 | 11 | ||
| 12 | #include "common/common_types.h" | ||
| 13 | #include "common/bit_field.h" | 12 | #include "common/bit_field.h" |
| 13 | #include "common/common_funcs.h" | ||
| 14 | #include "common/common_types.h" | ||
| 14 | 15 | ||
| 15 | // All the constants in this file come from http://3dbrew.org/wiki/Error_codes | 16 | // All the constants in this file come from http://3dbrew.org/wiki/Error_codes |
| 16 | 17 | ||
| @@ -364,6 +365,17 @@ public: | |||
| 364 | return !empty() ? *GetPointer() : std::move(value); | 365 | return !empty() ? *GetPointer() : std::move(value); |
| 365 | } | 366 | } |
| 366 | 367 | ||
| 368 | /// Asserts that the result succeeded and returns a reference to it. | ||
| 369 | T& Unwrap() { | ||
| 370 | // TODO(yuriks): Should be a release assert | ||
| 371 | _assert_msg_(Common, Succeeded(), "Tried to Unwrap empty ResultVal"); | ||
| 372 | return **this; | ||
| 373 | } | ||
| 374 | |||
| 375 | T&& MoveFrom() { | ||
| 376 | return std::move(Unwrap()); | ||
| 377 | } | ||
| 378 | |||
| 367 | private: | 379 | private: |
| 368 | typedef typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type StorageType; | 380 | typedef typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type StorageType; |
| 369 | 381 | ||
| @@ -400,3 +412,15 @@ template <typename T, typename... Args> | |||
| 400 | ResultVal<T> MakeResult(Args&&... args) { | 412 | ResultVal<T> MakeResult(Args&&... args) { |
| 401 | return ResultVal<T>::WithCode(RESULT_SUCCESS, std::forward<Args>(args)...); | 413 | return ResultVal<T>::WithCode(RESULT_SUCCESS, std::forward<Args>(args)...); |
| 402 | } | 414 | } |
| 415 | |||
| 416 | /** | ||
| 417 | * Check for the success of `source` (which must evaluate to a ResultVal). If it succeeds, unwraps | ||
| 418 | * the contained value and assigns it to `target`, which can be either an l-value expression or a | ||
| 419 | * variable declaration. If it fails the return code is returned from the current function. Thus it | ||
| 420 | * can be used to cascade errors out, achieving something akin to exception handling. | ||
| 421 | */ | ||
| 422 | #define CASCADE_RESULT(target, source) \ | ||
| 423 | auto CONCAT2(check_result_L, __LINE__) = source; \ | ||
| 424 | if (CONCAT2(check_result_L, __LINE__).Failed()) \ | ||
| 425 | return CONCAT2(check_result_L, __LINE__).Code(); \ | ||
| 426 | target = std::move(*CONCAT2(check_result_L, __LINE__)) | ||