diff options
Diffstat (limited to 'src/core')
-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 @@ #include <type_traits> #include <utility> -#include "common/common_types.h" #include "common/bit_field.h" +#include "common/common_funcs.h" +#include "common/common_types.h" // All the constants in this file come from http://3dbrew.org/wiki/Error_codes @@ -364,6 +365,17 @@ public: return !empty() ? *GetPointer() : std::move(value); } + /// Asserts that the result succeeded and returns a reference to it. + T& Unwrap() { + // TODO(yuriks): Should be a release assert + _assert_msg_(Common, Succeeded(), "Tried to Unwrap empty ResultVal"); + return **this; + } + + T&& MoveFrom() { + return std::move(Unwrap()); + } + private: typedef typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type StorageType; @@ -400,3 +412,15 @@ template <typename T, typename... Args> ResultVal<T> MakeResult(Args&&... args) { return ResultVal<T>::WithCode(RESULT_SUCCESS, std::forward<Args>(args)...); } + +/** + * Check for the success of `source` (which must evaluate to a ResultVal). If it succeeds, unwraps + * the contained value and assigns it to `target`, which can be either an l-value expression or a + * variable declaration. If it fails the return code is returned from the current function. Thus it + * can be used to cascade errors out, achieving something akin to exception handling. + */ +#define CASCADE_RESULT(target, source) \ + auto CONCAT2(check_result_L, __LINE__) = source; \ + if (CONCAT2(check_result_L, __LINE__).Failed()) \ + return CONCAT2(check_result_L, __LINE__).Code(); \ + target = std::move(*CONCAT2(check_result_L, __LINE__)) |