From afc416c6079f2db2c6cfae704de4c312907b3bb7 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sun, 11 Jan 2015 03:42:18 -0200 Subject: [PATCH] Additions to ResultVal to make it more convenient to use. --- src/core/hle/result.h | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/core/hle/result.h b/src/core/hle/result.h index 82dcf5bba7..ad06d00aa6 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h @@ -9,8 +9,9 @@ #include #include -#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::value>::type StorageType; @@ -400,3 +412,15 @@ template ResultVal MakeResult(Args&&... args) { return ResultVal::WithCode(RESULT_SUCCESS, std::forward(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__))