summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2015-01-11 03:42:18 -0200
committerGravatar Yuri Kunde Schlesner2015-01-30 11:47:02 -0200
commitafc416c6079f2db2c6cfae704de4c312907b3bb7 (patch)
tree272123acc30ed634268a516981e738a71e11745d /src
parentMove VAddr/PAddr typedefs to kernel.h (diff)
downloadyuzu-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.h26
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
367private: 379private:
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>
400ResultVal<T> MakeResult(Args&&... args) { 412ResultVal<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__))