mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
Implement cfg::uint for unsigned integers
This commit is contained in:
parent
f05e24e8e8
commit
7f9d41ac47
@ -83,7 +83,44 @@ bool cfg::try_to_int64(s64* out, const std::string& value, s64 min, s64 max)
|
|||||||
|
|
||||||
if (result < min || result > max)
|
if (result < min || result > max)
|
||||||
{
|
{
|
||||||
if (out) cfg_log.error("cfg::try_to_int('%s'): out of bounds (%lld..%lld)", value, min, max);
|
if (out) cfg_log.error("cfg::try_to_int('%s'): out of bounds (%d..%d)", value, min, max);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (out) *out = result;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> cfg::make_uint_range(u64 min, u64 max)
|
||||||
|
{
|
||||||
|
return {std::to_string(min), std::to_string(max)};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cfg::try_to_uint64(u64* out, const std::string& value, u64 min, u64 max)
|
||||||
|
{
|
||||||
|
u64 result;
|
||||||
|
const char* start = &value.front();
|
||||||
|
const char* end = &value.back() + 1;
|
||||||
|
int base = 10;
|
||||||
|
|
||||||
|
if (start[0] == '0' && (start[1] == 'x' || start[1] == 'X'))
|
||||||
|
{
|
||||||
|
// Limited hex support
|
||||||
|
base = 16;
|
||||||
|
start += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto ret = std::from_chars(start, end, result, base);
|
||||||
|
|
||||||
|
if (ret.ec != std::errc() || ret.ptr != end)
|
||||||
|
{
|
||||||
|
if (out) cfg_log.error("cfg::try_to_int('%s'): invalid integer", value);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result < min || result > max)
|
||||||
|
{
|
||||||
|
if (out) cfg_log.error("cfg::try_to_int('%s'): out of bounds (%u..%u)", value, min, max);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,12 @@ namespace cfg
|
|||||||
// Convert string to signed integer
|
// Convert string to signed integer
|
||||||
bool try_to_int64(s64* out, const std::string& value, s64 min, s64 max);
|
bool try_to_int64(s64* out, const std::string& value, s64 min, s64 max);
|
||||||
|
|
||||||
|
// Format min and max unsigned values
|
||||||
|
std::vector<std::string> make_uint_range(u64 min, u64 max);
|
||||||
|
|
||||||
|
// Convert string to unsigned integer
|
||||||
|
bool try_to_uint64(u64* out, const std::string& value, u64 min, u64 max);
|
||||||
|
|
||||||
// Internal hack
|
// Internal hack
|
||||||
bool try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, const std::string&);
|
bool try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, const std::string&);
|
||||||
|
|
||||||
@ -27,12 +33,13 @@ namespace cfg
|
|||||||
std::vector<std::string> try_to_enum_list(decltype(&fmt_class_string<int>::format) func);
|
std::vector<std::string> try_to_enum_list(decltype(&fmt_class_string<int>::format) func);
|
||||||
|
|
||||||
// Config tree entry type.
|
// Config tree entry type.
|
||||||
enum class type : uint
|
enum class type : unsigned
|
||||||
{
|
{
|
||||||
node = 0, // cfg::node type
|
node = 0, // cfg::node type
|
||||||
_bool, // cfg::_bool type
|
_bool, // cfg::_bool type
|
||||||
_enum, // cfg::_enum type
|
_enum, // cfg::_enum type
|
||||||
_int, // cfg::_int type
|
_int, // cfg::_int type
|
||||||
|
uint, // cfg::uint type
|
||||||
string, // cfg::string type
|
string, // cfg::string type
|
||||||
set, // cfg::set_entry type
|
set, // cfg::set_entry type
|
||||||
log,
|
log,
|
||||||
@ -302,6 +309,80 @@ namespace cfg
|
|||||||
// Alias for 64 bit int
|
// Alias for 64 bit int
|
||||||
using int64 = _int<INT64_MIN, INT64_MAX>;
|
using int64 = _int<INT64_MIN, INT64_MAX>;
|
||||||
|
|
||||||
|
// Unsigned 32/64-bit integer entry with custom Min/Max range.
|
||||||
|
template <u64 Min, u64 Max>
|
||||||
|
class uint final : public _base
|
||||||
|
{
|
||||||
|
static_assert(Min < Max, "Invalid cfg::uint range");
|
||||||
|
|
||||||
|
// Prefer 32 bit type if possible
|
||||||
|
using int_type = std::conditional_t<Max <= UINT32_MAX, u32, u64>;
|
||||||
|
|
||||||
|
atomic_t<int_type> m_value;
|
||||||
|
|
||||||
|
public:
|
||||||
|
int_type def;
|
||||||
|
|
||||||
|
// Expose range
|
||||||
|
static const u64 max = Max;
|
||||||
|
static const u64 min = Min;
|
||||||
|
|
||||||
|
uint(node* owner, const std::string& name, int_type def = std::max<int_type>(Min, 0), bool dynamic = false)
|
||||||
|
: _base(type::uint, owner, name, dynamic)
|
||||||
|
, m_value(def)
|
||||||
|
, def(def)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
operator int_type() const
|
||||||
|
{
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int_type get() const
|
||||||
|
{
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void from_default() override
|
||||||
|
{
|
||||||
|
m_value = def;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_string() const override
|
||||||
|
{
|
||||||
|
return std::to_string(m_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool from_string(const std::string& value, bool /*dynamic*/ = false) override
|
||||||
|
{
|
||||||
|
u64 result;
|
||||||
|
if (try_to_uint64(&result, value, Min, Max))
|
||||||
|
{
|
||||||
|
m_value = static_cast<int_type>(result);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(const u64& value)
|
||||||
|
{
|
||||||
|
m_value = static_cast<int_type>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> to_list() const override
|
||||||
|
{
|
||||||
|
return make_uint_range(Min, Max);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Alias for 32 bit uint
|
||||||
|
using uint32 = uint<0, UINT32_MAX>;
|
||||||
|
|
||||||
|
// Alias for 64 bit int
|
||||||
|
using uint64 = uint<0, UINT64_MAX>;
|
||||||
|
|
||||||
// Simple string entry with mutex
|
// Simple string entry with mutex
|
||||||
class string final : public _base
|
class string final : public _base
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user