|
|
@ -9,8 +9,9 @@
|
|
|
|
#include <type_traits>
|
|
|
|
#include <type_traits>
|
|
|
|
#include <utility>
|
|
|
|
#include <utility>
|
|
|
|
|
|
|
|
|
|
|
|
#include "common/common_types.h"
|
|
|
|
|
|
|
|
#include "common/bit_field.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
|
|
|
|
// 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);
|
|
|
|
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:
|
|
|
|
private:
|
|
|
|
typedef typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type StorageType;
|
|
|
|
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) {
|
|
|
|
ResultVal<T> MakeResult(Args&&... args) {
|
|
|
|
return ResultVal<T>::WithCode(RESULT_SUCCESS, std::forward<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__))
|
|
|
|