[Config] Use std::less<> for std::map<...>

Reduces amount of string copies
[Utilities] fmt::replace_all: avoid creation of temporary strings
This commit is contained in:
DH 2021-11-28 09:30:41 +02:00 committed by Nekotekina
parent 2981867375
commit cccfb89aa0
14 changed files with 80 additions and 62 deletions

View file

@ -19,8 +19,8 @@ namespace cfg
}
}
_base::_base(type _type, node* owner, const std::string& name, bool dynamic)
: m_type(_type), m_dynamic(dynamic), m_name(name)
_base::_base(type _type, node* owner, std::string name, bool dynamic)
: m_type(_type), m_dynamic(dynamic), m_name(std::move(name))
{
for (const auto& node : owner->m_nodes)
{
@ -33,7 +33,7 @@ namespace cfg
owner->m_nodes.emplace_back(this);
}
bool _base::from_string(const std::string&, bool)
bool _base::from_string(std::string_view, bool)
{
cfg_log.fatal("cfg::_base::from_string() purecall");
return false;
@ -58,7 +58,7 @@ std::vector<std::string> cfg::make_int_range(s64 min, s64 max)
return {std::to_string(min), std::to_string(max)};
}
bool try_to_int64(s64* out, const std::string& value, s64 min, s64 max)
bool try_to_int64(s64* out, std::string_view value, s64 min, s64 max)
{
s64 result;
const char* start = &value.front();
@ -104,7 +104,7 @@ std::vector<std::string> cfg::make_uint_range(u64 min, u64 max)
return {std::to_string(min), std::to_string(max)};
}
bool try_to_uint64(u64* out, const std::string& value, u64 min, u64 max)
bool try_to_uint64(u64* out, std::string_view value, u64 min, u64 max)
{
u64 result;
const char* start = &value.front();
@ -136,7 +136,7 @@ bool try_to_uint64(u64* out, const std::string& value, u64 min, u64 max)
return true;
}
bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, const std::string& value)
bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, std::string_view value)
{
u64 max = umax;
@ -320,7 +320,7 @@ void cfg::decode(const YAML::Node& data, cfg::_base& rhs, bool dynamic)
return;
}
std::map<std::string, std::string> values;
map_of_type<std::string> values;
for (const auto& pair : data)
{
@ -339,7 +339,7 @@ void cfg::decode(const YAML::Node& data, cfg::_base& rhs, bool dynamic)
return; // ???
}
std::map<std::string, logs::level> values;
map_of_type<logs::level> values;
for (const auto& pair : data)
{
@ -377,9 +377,9 @@ std::string cfg::node::to_string() const
return {out.c_str(), out.size()};
}
bool cfg::node::from_string(const std::string& value, bool dynamic)
bool cfg::node::from_string(std::string_view value, bool dynamic)
{
auto [result, error] = yaml_load(value);
auto [result, error] = yaml_load(std::string(value));
if (error.empty())
{
@ -414,26 +414,31 @@ void cfg::set_entry::from_default()
m_set = {};
}
std::string cfg::map_entry::get_value(const std::string& key)
std::string cfg::map_entry::get_value(std::string_view key)
{
return m_map.contains(key) ? m_map.at(key) : "";
if (auto it = m_map.find(key); it != m_map.end())
{
return it->second;
}
return {};
}
void cfg::map_entry::set_value(const std::string& key, const std::string& value)
void cfg::map_entry::set_value(std::string key, std::string value)
{
m_map[key] = value;
m_map[std::move(key)] = std::move(value);
}
void cfg::map_entry::set_map(std::map<std::string, std::string>&& map)
void cfg::map_entry::set_map(map_of_type<std::string>&& map)
{
m_map = std::move(map);
}
void cfg::map_entry::erase(const std::string& key)
void cfg::map_entry::erase(std::string_view key)
{
if (m_map.contains(key))
if (auto it = m_map.find(key); it != m_map.end())
{
m_map.erase(key);
m_map.erase(it);
}
}
@ -442,7 +447,7 @@ void cfg::map_entry::from_default()
set_map({});
}
void cfg::log_entry::set_map(std::map<std::string, logs::level>&& map)
void cfg::log_entry::set_map(map_of_type<logs::level>&& map)
{
m_map = std::move(map);
}

View file

@ -21,7 +21,7 @@ namespace cfg
std::vector<std::string> make_uint_range(u64 min, u64 max);
// 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, std::string_view);
// Internal hack
std::vector<std::string> try_to_enum_list(decltype(&fmt_class_string<int>::format) func);
@ -53,7 +53,7 @@ namespace cfg
_base(type _type);
// Owned entry constructor
_base(type _type, class node* owner, const std::string& name, bool dynamic);
_base(type _type, class node* owner, std::string name, bool dynamic);
public:
_base(const _base&) = delete;
@ -80,7 +80,7 @@ namespace cfg
}
// Try to convert from string (optional)
virtual bool from_string(const std::string&, bool /*dynamic*/ = false);
virtual bool from_string(std::string_view, bool /*dynamic*/ = false);
// Get string list (optional)
virtual std::vector<std::string> to_list() const
@ -107,8 +107,8 @@ namespace cfg
}
// Registered node constructor
node(node* owner, const std::string& name, bool dynamic = true)
: _base(type::node, owner, name, dynamic)
node(node* owner, std::string name, bool dynamic = true)
: _base(type::node, owner, std::move(name), dynamic)
{
}
@ -122,7 +122,7 @@ namespace cfg
std::string to_string() const override;
// Deserialize node
bool from_string(const std::string& value, bool dynamic = false) override;
bool from_string(std::string_view value, bool dynamic = false) override;
// Set default values
void from_default() override;
@ -135,8 +135,8 @@ namespace cfg
public:
bool def;
_bool(node* owner, const std::string& name, bool def = false, bool dynamic = false)
: _base(type::_bool, owner, name, dynamic)
_bool(node* owner, std::string name, bool def = false, bool dynamic = false)
: _base(type::_bool, owner, std::move(name), dynamic)
, m_value(def)
, def(def)
{
@ -159,7 +159,7 @@ namespace cfg
return m_value ? "true" : "false";
}
bool from_string(const std::string& value, bool /*dynamic*/ = false) override
bool from_string(std::string_view value, bool /*dynamic*/ = false) override
{
if (value == "false")
m_value = false;
@ -220,7 +220,7 @@ namespace cfg
return result; // TODO: ???
}
bool from_string(const std::string& value, bool /*dynamic*/ = false) override
bool from_string(std::string_view value, bool /*dynamic*/ = false) override
{
u64 result;
@ -285,7 +285,7 @@ namespace cfg
return std::to_string(m_value);
}
bool from_string(const std::string& value, bool /*dynamic*/ = false) override
bool from_string(std::string_view value, bool /*dynamic*/ = false) override
{
s64 result;
if (try_to_int64(&result, value, Min, Max))
@ -359,7 +359,7 @@ namespace cfg
return std::to_string(m_value);
}
bool from_string(const std::string& value, bool /*dynamic*/ = false) override
bool from_string(std::string_view value, bool /*dynamic*/ = false) override
{
u64 result;
if (try_to_uint64(&result, value, Min, Max))
@ -430,9 +430,9 @@ namespace cfg
return *m_value.load().get();
}
bool from_string(const std::string& value, bool /*dynamic*/ = false) override
bool from_string(std::string_view value, bool /*dynamic*/ = false) override
{
m_value = value;
m_value = std::string(value);
return true;
}
};
@ -474,9 +474,12 @@ namespace cfg
}
};
template<typename T>
using map_of_type = std::map<std::string, T, std::less<>>;
class map_entry final : public _base
{
std::map<std::string, std::string> m_map{};
map_of_type<std::string> m_map{};
public:
map_entry(node* owner, const std::string& name)
@ -484,24 +487,24 @@ namespace cfg
{
}
const std::map<std::string, std::string>& get_map() const
const map_of_type<std::string>& get_map() const
{
return m_map;
}
std::string get_value(const std::string& key);
std::string get_value(std::string_view key);
void set_value(const std::string& key, const std::string& value);
void set_map(std::map<std::string, std::string>&& map);
void set_value(std::string key, std::string value);
void set_map(map_of_type<std::string>&& map);
void erase(const std::string& key);
void erase(std::string_view key);
void from_default() override;
};
class log_entry final : public _base
{
std::map<std::string, logs::level> m_map{};
map_of_type<logs::level> m_map{};
public:
log_entry(node* owner, const std::string& name)
@ -509,12 +512,12 @@ namespace cfg
{
}
const std::map<std::string, logs::level>& get_map() const
const map_of_type<logs::level>& get_map() const
{
return m_map;
}
void set_map(std::map<std::string, logs::level>&& map);
void set_map(map_of_type<logs::level>&& map);
void from_default() override;
};

View file

@ -6,6 +6,8 @@
#include <functional>
#include <string_view>
#include "util/types.hpp"
#ifdef _WIN32
std::string wchar_to_utf8(const wchar_t *src);
std::string wchar_path_to_ansi_path(const std::wstring& src);
@ -22,17 +24,17 @@ inline void strcpy_trunc(D& dst, const T& src)
}
// 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, std::string_view value, s64 min, s64 max);
// Convert string to unsigned integer
bool try_to_uint64(u64* out, const std::string& value, u64 min, u64 max);
bool try_to_uint64(u64* out, std::string_view value, u64 min, u64 max);
namespace fmt
{
std::string replace_all(std::string_view src, std::string_view from, std::string_view to, usz count = -1);
template <usz list_size>
std::string replace_all(std::string src, const std::pair<std::string, std::string> (&list)[list_size])
std::string replace_all(std::string src, const std::pair<std::string_view, std::string> (&list)[list_size])
{
for (usz pos = 0; pos < src.length(); ++pos)
{
@ -41,11 +43,14 @@ namespace fmt
const usz comp_length = list[i].first.length();
if (src.length() - pos < comp_length)
{
continue;
}
if (src.substr(pos, comp_length) == list[i].first)
{
src = (pos ? src.substr(0, pos) + list[i].second : list[i].second) + src.substr(pos + comp_length);
src.erase(pos, comp_length);
src.insert(pos, list[i].second.data(), list[i].second.length());
pos += list[i].second.length() - 1;
break;
}
@ -56,7 +61,7 @@ namespace fmt
}
template <usz list_size>
std::string replace_all(std::string src, const std::pair<std::string, std::function<std::string()>> (&list)[list_size])
std::string replace_all(std::string src, const std::pair<std::string_view, std::function<std::string()>> (&list)[list_size])
{
for (usz pos = 0; pos < src.length(); ++pos)
{
@ -65,12 +70,16 @@ namespace fmt
const usz comp_length = list[i].first.length();
if (src.length() - pos < comp_length)
{
continue;
}
if (src.substr(pos, comp_length) == list[i].first)
{
src = (pos ? src.substr(0, pos) + list[i].second() : list[i].second()) + src.substr(pos + comp_length);
pos += list[i].second().length() - 1;
src.erase(pos, comp_length);
auto replacement = list[i].second();
src.insert(pos, replacement);
pos += replacement.length() - 1;
break;
}
}

View file

@ -135,7 +135,7 @@ namespace gl
" %vars"
"\n";
const std::pair<std::string, std::string> syntax_replace[] =
const std::pair<std::string_view, std::string> syntax_replace[] =
{
{ "%loc", std::to_string(GL_COMPUTE_BUFFER_SLOT(0)) },
{ "%ws", std::to_string(optimal_group_size) },

View file

@ -139,7 +139,7 @@ std::string CgBinaryDisasm::GetCondDisAsm() const
std::string CgBinaryDisasm::FormatDisAsm(const std::string& code)
{
const std::pair<std::string, std::function<std::string()>> repl_list[] =
const std::pair<std::string_view, std::function<std::string()>> repl_list[] =
{
{ "$$", []() -> std::string { return "$"; } },
{ "$0", [this]{ return GetSrcDisAsm<SRC0>(src0); } },

View file

@ -180,7 +180,7 @@ std::string CgBinaryDisasm::GetTexDisasm()
std::string CgBinaryDisasm::FormatDisasm(const std::string& code)
{
const std::pair<std::string, std::function<std::string()>> repl_list[] =
const std::pair<std::string_view, std::function<std::string()>> repl_list[] =
{
{ "$$", []() -> std::string { return "$"; } },
{ "$0", [this]{ return GetSRCDisasm(0); } },

View file

@ -330,7 +330,7 @@ bool FragmentProgramDecompiler::DstExpectsSca() const
std::string FragmentProgramDecompiler::Format(const std::string& code, bool ignore_redirects)
{
const std::pair<std::string, std::function<std::string()>> repl_list[] =
const std::pair<std::string_view, std::function<std::string()>> repl_list[] =
{
{ "$$", []() -> std::string { return "$"; } },
{ "$0", [this]() -> std::string {return GetSRC<SRC0>(src0);} },
@ -369,7 +369,7 @@ std::string FragmentProgramDecompiler::Format(const std::string& code, bool igno
{
//Redirect parameter 0 to the x2d temp register for TEXBEM
//TODO: Organize this a little better
std::pair<std::string, std::string> repl[] = { { "$0", "x2d" } };
std::pair<std::string_view, std::string> repl[] = { { "$0", "x2d" } };
std::string result = fmt::replace_all(code, repl);
return fmt::replace_all(result, repl_list);

View file

@ -122,7 +122,7 @@ namespace program_common
" return result;\n"
"}\n\n";
std::pair<std::string, std::string> replacements[] =
std::pair<std::string_view, std::string> replacements[] =
{std::make_pair("$T", wide_vector_type),
std::make_pair("$I", input_coord)};

View file

@ -222,7 +222,7 @@ std::string VertexProgramDecompiler::GetTex()
std::string VertexProgramDecompiler::Format(const std::string& code)
{
const std::pair<std::string, std::function<std::string()>> repl_list[] =
const std::pair<std::string_view, std::function<std::string()>> repl_list[] =
{
{ "$$", []() -> std::string { return "$"; } },
{ "$0", std::bind(std::mem_fn(&VertexProgramDecompiler::GetSRC), this, 0) },

View file

@ -251,7 +251,7 @@ namespace vk
"\n";
const auto parameters_size = utils::align(push_constants_size, 16) / 16;
const std::pair<std::string, std::string> syntax_replace[] =
const std::pair<std::string_view, std::string> syntax_replace[] =
{
{ "%ws", std::to_string(optimal_group_size) },
{ "%ks", std::to_string(kernel_size) },
@ -396,7 +396,7 @@ namespace vk
" }\n"
"}\n";
const std::pair<std::string, std::string> syntax_replace[] =
const std::pair<std::string_view, std::string> syntax_replace[] =
{
{ "%ws", std::to_string(optimal_group_size) },
};

View file

@ -565,7 +565,7 @@ namespace vk
}
}
const std::pair<std::string, std::string> syntax_replace[] =
const std::pair<std::string_view, std::string> syntax_replace[] =
{
{ "%ws", std::to_string(optimal_group_size) },
{ "%_wordcount", std::to_string(sizeof(_BlockType) / 4) },

View file

@ -21,6 +21,7 @@ namespace vk
virtual ~cs_resolve_base()
{}
// FIXME: move body to cpp
void build(const std::string& kernel, const std::string& format_prefix, int direction)
{
create();
@ -39,7 +40,7 @@ namespace vk
break;
}
const std::pair<std::string, std::string> syntax_replace[] =
const std::pair<std::string_view, std::string> syntax_replace[] =
{
{ "%wx", std::to_string(cs_wave_x) },
{ "%wy", std::to_string(cs_wave_y) },

View file

@ -227,7 +227,7 @@ namespace logs
}
}
void set_channel_levels(const std::map<std::string, logs::level>& map)
void set_channel_levels(const std::map<std::string, logs::level, std::less<>>& map)
{
for (auto&& pair : map)
{

View file

@ -164,7 +164,7 @@ namespace logs
level get_level(const std::string&);
// Log level control: set specific channels to level::fatal
void set_channel_levels(const std::map<std::string, logs::level>& map);
void set_channel_levels(const std::map<std::string, logs::level, std::less<>>& map);
// Get all registered log channels
std::vector<std::string> get_channels();