Common/Result: Swap order of template parameters to match C++26's std::expected, make all member functions constexpr, and add moving "unexpected" conversion constructor for consistency.

This commit is contained in:
Jordan Woyak 2025-11-21 19:24:48 -06:00
parent f38a2bbb0e
commit 127e068e51
7 changed files with 36 additions and 32 deletions

View File

@ -7,24 +7,30 @@
namespace Common namespace Common
{ {
template <typename ResultCode, typename T> template <typename Expected, typename Unexpected>
class Result final class Result final
{ {
public: public:
Result(ResultCode code) : m_variant{code} {} constexpr Result(const Expected& value) : m_variant{value} {}
Result(const T& t) : m_variant{t} {} constexpr Result(Expected&& value) : m_variant{std::move(value)} {}
Result(T&& t) : m_variant{std::move(t)} {}
explicit operator bool() const { return Succeeded(); } constexpr Result(const Unexpected& value) : m_variant{value} {}
bool Succeeded() const { return std::holds_alternative<T>(m_variant); } constexpr Result(Unexpected&& value) : m_variant{std::move(value)} {}
// Must only be called when Succeeded() returns false.
ResultCode Error() const { return std::get<ResultCode>(m_variant); } constexpr explicit operator bool() const { return Succeeded(); }
constexpr bool Succeeded() const { return std::holds_alternative<Expected>(m_variant); }
// Must only be called when Succeeded() returns true. // Must only be called when Succeeded() returns true.
const T& operator*() const { return std::get<T>(m_variant); } constexpr const Expected& operator*() const { return std::get<Expected>(m_variant); }
const T* operator->() const { return &std::get<T>(m_variant); } constexpr const Expected* operator->() const { return &std::get<Expected>(m_variant); }
T& operator*() { return std::get<T>(m_variant); } constexpr Expected& operator*() { return std::get<Expected>(m_variant); }
T* operator->() { return &std::get<T>(m_variant); } constexpr Expected* operator->() { return &std::get<Expected>(m_variant); }
// Must only be called when Succeeded() returns false.
constexpr Unexpected& Error() { return std::get<Unexpected>(m_variant); }
constexpr const Unexpected& Error() const { return std::get<Unexpected>(m_variant); }
private: private:
std::variant<ResultCode, T> m_variant; std::variant<Expected, Unexpected> m_variant;
}; };
} // namespace Common } // namespace Common

View File

@ -52,7 +52,7 @@ static std::vector<ActionReplay::AREntry> ResultToAREntries(u32 addr, const Chea
return codes; return codes;
} }
Common::Result<Cheats::GenerateActionReplayCodeErrorCode, ActionReplay::ARCode> Common::Result<ActionReplay::ARCode, Cheats::GenerateActionReplayCodeErrorCode>
Cheats::GenerateActionReplayCode(const Cheats::CheatSearchSessionBase& session, size_t index) Cheats::GenerateActionReplayCode(const Cheats::CheatSearchSessionBase& session, size_t index)
{ {
if (index >= session.GetResultCount()) if (index >= session.GetResultCount())

View File

@ -18,6 +18,6 @@ enum class GenerateActionReplayCodeErrorCode
InvalidAddress, InvalidAddress,
}; };
Common::Result<GenerateActionReplayCodeErrorCode, ActionReplay::ARCode> Common::Result<ActionReplay::ARCode, GenerateActionReplayCodeErrorCode>
GenerateActionReplayCode(const Cheats::CheatSearchSessionBase& session, size_t index); GenerateActionReplayCode(const Cheats::CheatSearchSessionBase& session, size_t index);
} // namespace Cheats } // namespace Cheats

View File

@ -109,11 +109,11 @@ TryReadValueFromEmulatedMemory(const Core::CPUThreadGuard& guard, u32 addr,
} }
template <typename T> template <typename T>
Common::Result<Cheats::SearchErrorCode, std::vector<Cheats::SearchResult<T>>> auto Cheats::NewSearch(const Core::CPUThreadGuard& guard,
Cheats::NewSearch(const Core::CPUThreadGuard& guard, const std::vector<Cheats::MemoryRange>& memory_ranges,
const std::vector<Cheats::MemoryRange>& memory_ranges, PowerPC::RequestedAddressSpace address_space, bool aligned,
PowerPC::RequestedAddressSpace address_space, bool aligned, const std::function<bool(const T& value)>& validator)
const std::function<bool(const T& value)>& validator) -> Common::Result<std::vector<SearchResult<T>>, SearchErrorCode>
{ {
if (AchievementManager::GetInstance().IsHardcoreModeActive()) if (AchievementManager::GetInstance().IsHardcoreModeActive())
return Cheats::SearchErrorCode::DisabledInHardcoreMode; return Cheats::SearchErrorCode::DisabledInHardcoreMode;
@ -162,11 +162,11 @@ Cheats::NewSearch(const Core::CPUThreadGuard& guard,
} }
template <typename T> template <typename T>
Common::Result<Cheats::SearchErrorCode, std::vector<Cheats::SearchResult<T>>> auto Cheats::NextSearch(
Cheats::NextSearch(const Core::CPUThreadGuard& guard, const Core::CPUThreadGuard& guard, const std::vector<Cheats::SearchResult<T>>& previous_results,
const std::vector<Cheats::SearchResult<T>>& previous_results, PowerPC::RequestedAddressSpace address_space,
PowerPC::RequestedAddressSpace address_space, const std::function<bool(const T& new_value, const T& old_value)>& validator)
const std::function<bool(const T& new_value, const T& old_value)>& validator) -> Common::Result<std::vector<SearchResult<T>>, SearchErrorCode>
{ {
if (AchievementManager::GetInstance().IsHardcoreModeActive()) if (AchievementManager::GetInstance().IsHardcoreModeActive())
return Cheats::SearchErrorCode::DisabledInHardcoreMode; return Cheats::SearchErrorCode::DisabledInHardcoreMode;
@ -335,7 +335,7 @@ Cheats::SearchErrorCode Cheats::CheatSearchSession<T>::RunSearch(const Core::CPU
{ {
if (AchievementManager::GetInstance().IsHardcoreModeActive()) if (AchievementManager::GetInstance().IsHardcoreModeActive())
return Cheats::SearchErrorCode::DisabledInHardcoreMode; return Cheats::SearchErrorCode::DisabledInHardcoreMode;
Common::Result<SearchErrorCode, std::vector<SearchResult<T>>> result = Common::Result<std::vector<SearchResult<T>>, SearchErrorCode> result =
Cheats::SearchErrorCode::InvalidParameters; Cheats::SearchErrorCode::InvalidParameters;
if (m_filter_type == FilterType::CompareAgainstSpecificValue) if (m_filter_type == FilterType::CompareAgainstSpecificValue)
{ {

View File

@ -116,7 +116,7 @@ std::vector<u8> GetValueAsByteVector(const SearchValue& value);
// Do a new search across the given memory region in the given address space, only keeping values // Do a new search across the given memory region in the given address space, only keeping values
// for which the given validator returns true. // for which the given validator returns true.
template <typename T> template <typename T>
Common::Result<SearchErrorCode, std::vector<SearchResult<T>>> Common::Result<std::vector<SearchResult<T>>, SearchErrorCode>
NewSearch(const Core::CPUThreadGuard& guard, const std::vector<MemoryRange>& memory_ranges, NewSearch(const Core::CPUThreadGuard& guard, const std::vector<MemoryRange>& memory_ranges,
PowerPC::RequestedAddressSpace address_space, bool aligned, PowerPC::RequestedAddressSpace address_space, bool aligned,
const std::function<bool(const T& value)>& validator); const std::function<bool(const T& value)>& validator);
@ -124,7 +124,7 @@ NewSearch(const Core::CPUThreadGuard& guard, const std::vector<MemoryRange>& mem
// Refresh the values for the given results in the given address space, only keeping values for // Refresh the values for the given results in the given address space, only keeping values for
// which the given validator returns true. // which the given validator returns true.
template <typename T> template <typename T>
Common::Result<SearchErrorCode, std::vector<SearchResult<T>>> Common::Result<std::vector<SearchResult<T>>, SearchErrorCode>
NextSearch(const Core::CPUThreadGuard& guard, const std::vector<SearchResult<T>>& previous_results, NextSearch(const Core::CPUThreadGuard& guard, const std::vector<SearchResult<T>>& previous_results,
PowerPC::RequestedAddressSpace address_space, PowerPC::RequestedAddressSpace address_space,
const std::function<bool(const T& new_value, const T& old_value)>& validator); const std::function<bool(const T& new_value, const T& old_value)>& validator);

View File

@ -49,7 +49,7 @@ enum class ResultCode
}; };
template <typename T> template <typename T>
using Result = Common::Result<ResultCode, T>; using Result = Common::Result<T, ResultCode>;
using Uid = u32; using Uid = u32;
using Gid = u16; using Gid = u16;

View File

@ -8,8 +8,6 @@
#include <memory> #include <memory>
#include <thread> #include <thread>
#include <utility> #include <utility>
#include <variant>
#include <vector>
#include "Common/Assert.h" #include "Common/Assert.h"
#include "Common/Event.h" #include "Common/Event.h"
@ -27,7 +25,7 @@ enum class ConversionResultCode
}; };
template <typename T> template <typename T>
using ConversionResult = Common::Result<ConversionResultCode, T>; using ConversionResult = Common::Result<T, ConversionResultCode>;
// This class starts a number of compression threads and one output thread. // This class starts a number of compression threads and one output thread.
// The set_up_compress_thread_state function is called at the start of each compression thread. // The set_up_compress_thread_state function is called at the start of each compression thread.