mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-12-06 07:12:28 +01:00
Config: Implement 128-bit setting entry type
Some checks are pending
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (/rpcs3/.ci/build-linux-aarch64.sh, gcc, rpcs3/rpcs3-ci-jammy-aarch64:1.6, ubuntu-24.04-arm) (push) Waiting to run
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (/rpcs3/.ci/build-linux.sh, gcc, rpcs3/rpcs3-ci-jammy:1.6, ubuntu-24.04) (push) Waiting to run
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (a1d35836e8d45bfc6f63c26f0a3e5d46ef622fe1, rpcs3/rpcs3-binaries-linux-arm64, /rpcs3/.ci/build-linux-aarch64.sh, clang, rpcs3/rpcs3-ci-jammy-aarch64:1.6, ubuntu-24.04-arm) (push) Waiting to run
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (d812f1254a1157c80fd402f94446310560f54e5f, rpcs3/rpcs3-binaries-linux, /rpcs3/.ci/build-linux.sh, clang, rpcs3/rpcs3-ci-jammy:1.6, ubuntu-24.04) (push) Waiting to run
Build RPCS3 / RPCS3 Mac ${{ matrix.name }} (51ae32f468089a8169aaf1567de355ff4a3e0842, rpcs3/rpcs3-binaries-mac, .ci/build-mac.sh, Intel) (push) Waiting to run
Build RPCS3 / RPCS3 Mac ${{ matrix.name }} (8e21bdbc40711a3fccd18fbf17b742348b0f4281, rpcs3/rpcs3-binaries-mac-arm64, .ci/build-mac-arm64.sh, Apple Silicon) (push) Waiting to run
Build RPCS3 / RPCS3 Windows (push) Waiting to run
Build RPCS3 / RPCS3 Windows Clang (win64, clang, clang64) (push) Waiting to run
Build RPCS3 / RPCS3 FreeBSD (push) Waiting to run
Some checks are pending
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (/rpcs3/.ci/build-linux-aarch64.sh, gcc, rpcs3/rpcs3-ci-jammy-aarch64:1.6, ubuntu-24.04-arm) (push) Waiting to run
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (/rpcs3/.ci/build-linux.sh, gcc, rpcs3/rpcs3-ci-jammy:1.6, ubuntu-24.04) (push) Waiting to run
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (a1d35836e8d45bfc6f63c26f0a3e5d46ef622fe1, rpcs3/rpcs3-binaries-linux-arm64, /rpcs3/.ci/build-linux-aarch64.sh, clang, rpcs3/rpcs3-ci-jammy-aarch64:1.6, ubuntu-24.04-arm) (push) Waiting to run
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (d812f1254a1157c80fd402f94446310560f54e5f, rpcs3/rpcs3-binaries-linux, /rpcs3/.ci/build-linux.sh, clang, rpcs3/rpcs3-ci-jammy:1.6, ubuntu-24.04) (push) Waiting to run
Build RPCS3 / RPCS3 Mac ${{ matrix.name }} (51ae32f468089a8169aaf1567de355ff4a3e0842, rpcs3/rpcs3-binaries-mac, .ci/build-mac.sh, Intel) (push) Waiting to run
Build RPCS3 / RPCS3 Mac ${{ matrix.name }} (8e21bdbc40711a3fccd18fbf17b742348b0f4281, rpcs3/rpcs3-binaries-mac-arm64, .ci/build-mac-arm64.sh, Apple Silicon) (push) Waiting to run
Build RPCS3 / RPCS3 Windows (push) Waiting to run
Build RPCS3 / RPCS3 Windows Clang (win64, clang, clang64) (push) Waiting to run
Build RPCS3 / RPCS3 FreeBSD (push) Waiting to run
This commit is contained in:
parent
4141f76105
commit
e8aa1caa4e
|
|
@ -166,6 +166,55 @@ bool try_to_uint64(u64* out, std::string_view value, u64 min, u64 max)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool try_to_uint128(u128* out, std::string_view value)
|
||||||
|
{
|
||||||
|
if (value.empty())
|
||||||
|
{
|
||||||
|
if (out) cfg_log.error("cfg::try_to_uint128(): called with an empty string");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 result_low = 0, result_high = 0;
|
||||||
|
const char* start_high64 = value.data();
|
||||||
|
const char* end = value.data() + value.size();
|
||||||
|
|
||||||
|
if (start_high64[0] == '0' && value.size() >= 2 && (start_high64[1] == 'x' || start_high64[1] == 'X'))
|
||||||
|
{
|
||||||
|
// Hex support
|
||||||
|
start_high64 += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* start_low64 = end - std::min<usz>(end - start_high64, 16);
|
||||||
|
|
||||||
|
// Hexadecimal-only
|
||||||
|
constexpr int base = 16;
|
||||||
|
|
||||||
|
auto ret = std::from_chars(start_low64, end, result_low, base);
|
||||||
|
|
||||||
|
if (ret.ec != std::errc() || ret.ptr != end)
|
||||||
|
{
|
||||||
|
if (out) cfg_log.error("cfg::try_to_uint128('%s'): invalid integer", value);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start_high64 == start_low64)
|
||||||
|
{
|
||||||
|
if (out) *out = result_low;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = std::from_chars(start_high64, start_low64, result_high, base);
|
||||||
|
|
||||||
|
if (ret.ec != std::errc() || ret.ptr != start_low64)
|
||||||
|
{
|
||||||
|
if (out) cfg_log.error("cfg::try_to_uint128('%s'): invalid integer", value);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (out) *out = result_low + (u128{result_high} << 64);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> cfg::make_float_range(f64 min, f64 max)
|
std::vector<std::string> cfg::make_float_range(f64 min, f64 max)
|
||||||
{
|
{
|
||||||
return {std::to_string(min), std::to_string(max)};
|
return {std::to_string(min), std::to_string(max)};
|
||||||
|
|
@ -278,6 +327,19 @@ bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) f
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string cfg::uint128::to_string(u128 value) noexcept
|
||||||
|
{
|
||||||
|
std::string result = "0x";
|
||||||
|
result.resize(result.size() + 32);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < 32; i++)
|
||||||
|
{
|
||||||
|
result[result.size() - 1 - i] = "0123456789ABCDEF"[static_cast<u64>(value >> (i * 4)) % 16];
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> cfg::try_to_enum_list(decltype(&fmt_class_string<int>::format) func)
|
std::vector<std::string> cfg::try_to_enum_list(decltype(&fmt_class_string<int>::format) func)
|
||||||
{
|
{
|
||||||
std::vector<std::string> result;
|
std::vector<std::string> result;
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ namespace cfg
|
||||||
_enum, // cfg::_enum type
|
_enum, // cfg::_enum type
|
||||||
_int, // cfg::_int type
|
_int, // cfg::_int type
|
||||||
uint, // cfg::uint type
|
uint, // cfg::uint type
|
||||||
|
uint128, // cfg::uint128 type
|
||||||
string, // cfg::string type
|
string, // cfg::string type
|
||||||
set, // cfg::set_entry type
|
set, // cfg::set_entry type
|
||||||
map, // cfg::map_entry type
|
map, // cfg::map_entry type
|
||||||
|
|
@ -578,6 +579,86 @@ namespace cfg
|
||||||
// Alias for 64 bit int
|
// Alias for 64 bit int
|
||||||
using uint64 = uint<0, u64{umax}>;
|
using uint64 = uint<0, u64{umax}>;
|
||||||
|
|
||||||
|
// Unsigned 128-bit integer entry.
|
||||||
|
class uint128 final : public _base
|
||||||
|
{
|
||||||
|
using int_type = u128;
|
||||||
|
|
||||||
|
atomic_t<int_type> m_value{};
|
||||||
|
int_type original_def = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
int_type def;
|
||||||
|
|
||||||
|
uint128(node* owner, const std::string& name, int_type def = 0, bool dynamic = false)
|
||||||
|
: _base(type::uint128, owner, name, dynamic)
|
||||||
|
, m_value(def)
|
||||||
|
, original_def(def)
|
||||||
|
, def(def)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
operator int_type() const
|
||||||
|
{
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator ullong() const
|
||||||
|
{
|
||||||
|
return static_cast<ullong>(m_value.load());
|
||||||
|
}
|
||||||
|
|
||||||
|
int_type get() const
|
||||||
|
{
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void from_default() override
|
||||||
|
{
|
||||||
|
m_value = def;
|
||||||
|
}
|
||||||
|
|
||||||
|
void restore_defaults() override
|
||||||
|
{
|
||||||
|
def = original_def;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string to_string(u128 value) noexcept;
|
||||||
|
|
||||||
|
std::string to_string() const override
|
||||||
|
{
|
||||||
|
return to_string(m_value.load());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string def_to_string() const override
|
||||||
|
{
|
||||||
|
return to_string(def);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool from_string(std::string_view value, bool /*dynamic*/ = false) override
|
||||||
|
{
|
||||||
|
u128 result;
|
||||||
|
if (try_to_uint128(&result, value))
|
||||||
|
{
|
||||||
|
m_value = result;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(u128 value)
|
||||||
|
{
|
||||||
|
m_value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> to_list() const override
|
||||||
|
{
|
||||||
|
// Should not be used
|
||||||
|
return make_uint_range(0, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Simple string entry with mutex
|
// Simple string entry with mutex
|
||||||
class string : public _base
|
class string : public _base
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,9 @@ bool try_to_int64(s64* out, std::string_view value, s64 min, s64 max);
|
||||||
// Convert string to unsigned integer
|
// Convert string to unsigned integer
|
||||||
bool try_to_uint64(u64* out, std::string_view value, u64 min, u64 max);
|
bool try_to_uint64(u64* out, std::string_view value, u64 min, u64 max);
|
||||||
|
|
||||||
|
// Convert string to unsigned int128_t
|
||||||
|
bool try_to_uint128(u128* out, std::string_view value);
|
||||||
|
|
||||||
// Convert string to float
|
// Convert string to float
|
||||||
bool try_to_float(f64* out, std::string_view value, f64 min, f64 max);
|
bool try_to_float(f64* out, std::string_view value, f64 min, f64 max);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue