diff options
| author | 2015-01-11 03:42:18 -0200 | |
|---|---|---|
| committer | 2015-01-30 11:47:02 -0200 | |
| commit | afc416c6079f2db2c6cfae704de4c312907b3bb7 (patch) | |
| tree | 272123acc30ed634268a516981e738a71e11745d /src | |
| parent | Move VAddr/PAddr typedefs to kernel.h (diff) | |
| download | yuzu-afc416c6079f2db2c6cfae704de4c312907b3bb7.tar.gz yuzu-afc416c6079f2db2c6cfae704de4c312907b3bb7.tar.xz yuzu-afc416c6079f2db2c6cfae704de4c312907b3bb7.zip | |
Additions to ResultVal to make it more convenient to use.
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__)) | ||