Allow supplying a custom ResultValue result type and optimise span

This allows PosixResultValue to be created easily.
This commit is contained in:
Billy Laws 2021-07-17 14:01:39 +01:00
parent 85c48d0e7e
commit f1bbf06cd8

View File

@ -83,26 +83,27 @@ namespace skyline {
/** /**
* @brief A wrapper around std::optional that also stores a HOS result code * @brief A wrapper around std::optional that also stores a HOS result code
* @tparam T The object type to hold * @tparam ValueType The object type to hold
* @tparam ResultType The result type to hold
*/ */
template<typename T> template<typename ValueType, typename ResultType = Result>
class ResultValue { class ResultValue {
static_assert(!std::is_same<T, Result>::value); static_assert(!std::is_same<ValueType, ResultType>::value);
private: private:
std::optional<T> value; std::optional<ValueType> value;
public: public:
Result result; ResultType result{};
constexpr ResultValue(T value) : value(value) {}; constexpr ResultValue(ValueType value) : value(value) {};
constexpr ResultValue(Result result) : result(result) {}; constexpr ResultValue(ResultType result) : result(result) {};
template<typename U> template<typename U>
constexpr ResultValue(ResultValue<U> result) : result(result) {}; constexpr ResultValue(ResultValue<U> result) : result(result) {};
constexpr operator Result() const { constexpr operator ResultType() const {
return result; return result;
} }
@ -110,11 +111,11 @@ namespace skyline {
return value.has_value(); return value.has_value();
} }
constexpr T& operator*() { constexpr ValueType& operator*() {
return *value; return *value;
} }
constexpr T* operator->() { constexpr ValueType* operator->() {
return &*value; return &*value;
} }
}; };
@ -362,6 +363,9 @@ namespace skyline {
template<typename Out> template<typename Out>
constexpr Out &as() { constexpr Out &as() {
if constexpr (Extent != std::dynamic_extent && sizeof(T) * Extent >= sizeof(Out))
return *reinterpret_cast<Out *>(span::data());
if (span::size_bytes() >= sizeof(Out)) if (span::size_bytes() >= sizeof(Out))
return *reinterpret_cast<Out *>(span::data()); return *reinterpret_cast<Out *>(span::data());
throw exception("Span size is less than Out type size (0x{:X}/0x{:X})", span::size_bytes(), sizeof(Out)); throw exception("Span size is less than Out type size (0x{:X}/0x{:X})", span::size_bytes(), sizeof(Out));