diff --git a/Source/Core/Common/Config/Layer.cpp b/Source/Core/Common/Config/Layer.cpp index 6653dbfe65..8eba0d7c1a 100644 --- a/Source/Core/Common/Config/Layer.cpp +++ b/Source/Core/Common/Config/Layer.cpp @@ -11,44 +11,6 @@ namespace Config { -namespace detail -{ -std::string ValueToString(u16 value) -{ - return StringFromFormat("0x%04x", value); -} - -std::string ValueToString(u32 value) -{ - return StringFromFormat("0x%08x", value); -} - -std::string ValueToString(float value) -{ - return StringFromFormat("%#.9g", value); -} - -std::string ValueToString(double value) -{ - return StringFromFormat("%#.17g", value); -} - -std::string ValueToString(int value) -{ - return std::to_string(value); -} - -std::string ValueToString(bool value) -{ - return StringFromBool(value); -} - -std::string ValueToString(const std::string& value) -{ - return value; -} -} - ConfigLayerLoader::ConfigLayerLoader(LayerType layer) : m_layer(layer) { } diff --git a/Source/Core/Common/Config/Layer.h b/Source/Core/Common/Config/Layer.h index 3e01b83fed..2e84d6c3d1 100644 --- a/Source/Core/Common/Config/Layer.h +++ b/Source/Core/Common/Config/Layer.h @@ -19,19 +19,6 @@ namespace Config { namespace detail { -std::string ValueToString(u16 value); -std::string ValueToString(u32 value); -std::string ValueToString(float value); -std::string ValueToString(double value); -std::string ValueToString(int value); -std::string ValueToString(bool value); -std::string ValueToString(const std::string& value); -template ::value>* = nullptr> -std::string ValueToString(T value) -{ - return ValueToString(static_cast>(value)); -} - template ::value>* = nullptr> std::optional TryParse(const std::string& str_value) { @@ -133,13 +120,17 @@ public: template void Set(const ConfigInfo& config_info, const std::common_type_t& value) { - Set(config_info.location, value); + Set(config_info.location, value); } template void Set(const ConfigLocation& location, const T& value) { - const std::string new_value = detail::ValueToString(value); + Set(location, ValueToString(value)); + } + + void Set(const ConfigLocation& location, const std::string& new_value) + { std::optional& current_value = m_map[location]; if (current_value == new_value) return; diff --git a/Source/Core/Common/IniFile.cpp b/Source/Core/Common/IniFile.cpp index ddaf64b0e3..604c4b0fc9 100644 --- a/Source/Core/Common/IniFile.cpp +++ b/Source/Core/Common/IniFile.cpp @@ -57,55 +57,11 @@ void IniFile::Section::Set(const std::string& key, const std::string& newValue) } } -void IniFile::Section::Set(const std::string& key, const std::string& newValue, - const std::string& defaultValue) -{ - if (newValue != defaultValue) - Set(key, newValue); - else - Delete(key); -} - void IniFile::Section::Set(const std::string& key, const std::vector& newValues) { Set(key, JoinStrings(newValues, ",")); } -void IniFile::Section::Set(const std::string& key, u32 newValue) -{ - Set(key, StringFromFormat("0x%08x", newValue)); -} - -void IniFile::Section::Set(const std::string& key, u64 new_value) -{ - Set(key, StringFromFormat("0x%016" PRIx64, new_value)); -} - -void IniFile::Section::Set(const std::string& key, float newValue) -{ - Set(key, StringFromFormat("%#.9g", newValue)); -} - -void IniFile::Section::Set(const std::string& key, double newValue) -{ - Set(key, StringFromFormat("%#.17g", newValue)); -} - -void IniFile::Section::Set(const std::string& key, int newValue) -{ - Set(key, std::to_string(newValue)); -} - -void IniFile::Section::Set(const std::string& key, s64 newValue) -{ - Set(key, StringFromFormat("%" PRId64, newValue)); -} - -void IniFile::Section::Set(const std::string& key, bool newValue) -{ - Set(key, StringFromBool(newValue)); -} - bool IniFile::Section::Get(const std::string& key, std::string* value, const std::string& defaultValue) const { @@ -154,90 +110,6 @@ bool IniFile::Section::Get(const std::string& key, std::vector* out return true; } -bool IniFile::Section::Get(const std::string& key, int* value, int defaultValue) const -{ - std::string temp; - bool retval = Get(key, &temp); - - if (retval && TryParse(temp, value)) - return true; - - *value = defaultValue; - return false; -} - -bool IniFile::Section::Get(const std::string& key, s64* value, s64 default_value) const -{ - std::string temp; - bool retval = Get(key, &temp); - - if (retval && TryParse(temp, value)) - return true; - - *value = default_value; - return false; -} - -bool IniFile::Section::Get(const std::string& key, u32* value, u32 defaultValue) const -{ - std::string temp; - bool retval = Get(key, &temp); - - if (retval && TryParse(temp, value)) - return true; - - *value = defaultValue; - return false; -} - -bool IniFile::Section::Get(const std::string& key, u64* value, u64 default_value) const -{ - std::string temp; - bool retval = Get(key, &temp); - - if (retval && TryParse(temp, value)) - return true; - - *value = default_value; - return false; -} - -bool IniFile::Section::Get(const std::string& key, bool* value, bool defaultValue) const -{ - std::string temp; - bool retval = Get(key, &temp); - - if (retval && TryParse(temp, value)) - return true; - - *value = defaultValue; - return false; -} - -bool IniFile::Section::Get(const std::string& key, float* value, float defaultValue) const -{ - std::string temp; - bool retval = Get(key, &temp); - - if (retval && TryParse(temp, value)) - return true; - - *value = defaultValue; - return false; -} - -bool IniFile::Section::Get(const std::string& key, double* value, double defaultValue) const -{ - std::string temp; - bool retval = Get(key, &temp); - - if (retval && TryParse(temp, value)) - return true; - - *value = defaultValue; - return false; -} - bool IniFile::Section::Exists(const std::string& key) const { return values.find(key) != values.end(); diff --git a/Source/Core/Common/IniFile.h b/Source/Core/Common/IniFile.h index 697e700e7e..f11a4b9d32 100644 --- a/Source/Core/Common/IniFile.h +++ b/Source/Core/Common/IniFile.h @@ -12,6 +12,7 @@ #include "Common/CommonFuncs.h" #include "Common/CommonTypes.h" +#include "Common/StringUtil.h" struct CaseInsensitiveStringCompare { @@ -35,20 +36,17 @@ public: bool Delete(const std::string& key); void Set(const std::string& key, const std::string& newValue); - void Set(const std::string& key, const std::string& newValue, const std::string& defaultValue); - void Set(const std::string& key, u32 newValue); - void Set(const std::string& key, u64 new_value); - void Set(const std::string& key, float newValue); - void Set(const std::string& key, double newValue); - void Set(const std::string& key, int newValue); - void Set(const std::string& key, s64 new_value); - void Set(const std::string& key, bool newValue); + template + void Set(const std::string& key, const T& new_value) + { + Set(key, ValueToString(new_value)); + } template - void Set(const std::string& key, T newValue, const T defaultValue) + void Set(const std::string& key, const T& new_value, const std::common_type_t& default_value) { - if (newValue != defaultValue) - Set(key, newValue); + if (new_value != default_value) + Set(key, new_value); else Delete(key); } @@ -57,13 +55,17 @@ public: bool Get(const std::string& key, std::string* value, const std::string& defaultValue = NULL_STRING) const; - bool Get(const std::string& key, int* value, int defaultValue = 0) const; - bool Get(const std::string& key, s64* value, s64 default_value = 0) const; - bool Get(const std::string& key, u32* value, u32 defaultValue = 0) const; - bool Get(const std::string& key, u64* value, u64 default_value = 0) const; - bool Get(const std::string& key, bool* value, bool defaultValue = false) const; - bool Get(const std::string& key, float* value, float defaultValue = 0.0f) const; - bool Get(const std::string& key, double* value, double defaultValue = 0.0) const; + template + bool Get(const std::string& key, T* value, + const std::common_type_t& default_value = {}) const + { + std::string temp; + bool retval = Get(key, &temp); + if (retval && TryParse(temp, value)) + return true; + *value = default_value; + return false; + } bool Get(const std::string& key, std::vector* values) const; void SetLines(const std::vector& lines); diff --git a/Source/Core/Common/StringUtil.cpp b/Source/Core/Common/StringUtil.cpp index cc1ffaa949..c2a5a62b2d 100644 --- a/Source/Core/Common/StringUtil.cpp +++ b/Source/Core/Common/StringUtil.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include #include #include #include @@ -291,7 +292,42 @@ bool TryParse(const std::string& str, bool* const output) return true; } -std::string StringFromBool(bool value) +std::string ValueToString(u16 value) +{ + return StringFromFormat("0x%04x", value); +} + +std::string ValueToString(u32 value) +{ + return StringFromFormat("0x%08x", value); +} + +std::string ValueToString(u64 value) +{ + return StringFromFormat("0x%016" PRIx64, value); +} + +std::string ValueToString(float value) +{ + return StringFromFormat("%#.9g", value); +} + +std::string ValueToString(double value) +{ + return StringFromFormat("%#.17g", value); +} + +std::string ValueToString(int value) +{ + return std::to_string(value); +} + +std::string ValueToString(s64 value) +{ + return StringFromFormat("%" PRId64, value); +} + +std::string ValueToString(bool value) { return value ? "True" : "False"; } diff --git a/Source/Core/Common/StringUtil.h b/Source/Core/Common/StringUtil.h index 2e6089ef14..11c873bdae 100644 --- a/Source/Core/Common/StringUtil.h +++ b/Source/Core/Common/StringUtil.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "Common/CommonTypes.h" @@ -41,8 +42,6 @@ std::string ArrayToString(const u8* data, u32 size, int line_len = 20, bool spac std::string StripSpaces(const std::string& s); std::string StripQuotes(const std::string& s); -std::string StringFromBool(bool value); - bool TryParse(const std::string& str, bool* output); bool TryParse(const std::string& str, u16* output); bool TryParse(const std::string& str, u32* output); @@ -83,6 +82,20 @@ bool TryParseVector(const std::string& str, std::vector* output, const char d return true; } +std::string ValueToString(u16 value); +std::string ValueToString(u32 value); +std::string ValueToString(u64 value); +std::string ValueToString(float value); +std::string ValueToString(double value); +std::string ValueToString(int value); +std::string ValueToString(s64 value); +std::string ValueToString(bool value); +template ::value>* = nullptr> +std::string ValueToString(T value) +{ + return ValueToString(static_cast>(value)); +} + // Generates an hexdump-like representation of a binary data blob. std::string HexDump(const u8* data, size_t size); diff --git a/Source/Core/UICommon/CommandLineParse.cpp b/Source/Core/UICommon/CommandLineParse.cpp index e2ca7038c0..bc8da4d92b 100644 --- a/Source/Core/UICommon/CommandLineParse.cpp +++ b/Source/Core/UICommon/CommandLineParse.cpp @@ -30,7 +30,7 @@ public: if (audio_backend.size()) m_values.emplace_back( - std::make_tuple(Config::MAIN_DSP_HLE.location, StringFromBool(audio_backend == "HLE"))); + std::make_tuple(Config::MAIN_DSP_HLE.location, ValueToString(audio_backend == "HLE"))); // Arguments are in the format of .
.=Value for (const auto& arg : args) diff --git a/Source/UnitTests/Common/StringUtilTest.cpp b/Source/UnitTests/Common/StringUtilTest.cpp index 39a0d44944..cae007fdbe 100644 --- a/Source/UnitTests/Common/StringUtilTest.cpp +++ b/Source/UnitTests/Common/StringUtilTest.cpp @@ -84,3 +84,24 @@ TEST(StringUtil, UTF8ToSHIFTJIS) EXPECT_STREQ(SHIFTJISToUTF8(UTF8ToSHIFTJIS(kirby_unicode)).c_str(), kirby_unicode.c_str()); EXPECT_STREQ(UTF8ToSHIFTJIS(kirby_unicode).c_str(), kirby_sjis.c_str()); } + +template +static void DoRoundTripTest(const std::vector& data) +{ + for (const T& e : data) + { + const std::string s = ValueToString(e); + T out; + EXPECT_TRUE(TryParse(s, &out)); + EXPECT_EQ(e, out); + } +} + +TEST(StringUtil, ToString_TryParse_Roundtrip) +{ + DoRoundTripTest({true, false}); + DoRoundTripTest({0, -1, 1, 123, -123, 123456789, -123456789}); + DoRoundTripTest({0u, 1u, 123u, 123456789u, 4023456789u}); + DoRoundTripTest({0.0f, 1.0f, -1.0f, -0.5f, 0.5f, -1e-3f, 1e-3f, 1e3f, -1e3f}); + DoRoundTripTest({0.0, 1.0, -1.0, -0.5, 0.5, -1e-3, 1e-3, 1e3, -1e3}); +}