Replace IdMap with HashMap

main
Maxime Coste 2017-03-07 01:12:37 +00:00
parent 6373338c50
commit f0ae0b8410
22 changed files with 60 additions and 225 deletions

View File

@ -12,7 +12,7 @@ void AliasRegistry::add_alias(String alias, String command)
kak_assert(CommandManager::instance().command_defined(command));
auto it = m_aliases.find(alias);
if (it == m_aliases.end())
m_aliases.append({std::move(alias), std::move(command) });
m_aliases.insert({std::move(alias), std::move(command) });
else
it->value = std::move(command);
}

View File

@ -3,7 +3,7 @@
#include "safe_ptr.hh"
#include "string.hh"
#include "id_map.hh"
#include "hash_map.hh"
namespace Kakoune
{
@ -16,7 +16,7 @@ public:
void remove_alias(StringView alias);
StringView operator[](StringView name) const;
using AliasMap = IdMap<String, MemoryDomain::Aliases>;
using AliasMap = HashMap<String, String, MemoryDomain::Aliases>;
using iterator = AliasMap::const_iterator;
Vector<StringView> aliases_for(StringView command) const;

View File

@ -663,7 +663,7 @@ Completions add_highlighter_completer(
if (token_to_complete == 1 and params[0] == "-group")
return complete_highlighter(context, params[1], pos_in_token, true);
else if (token_to_complete == 0 or (token_to_complete == 2 and params[0] == "-group"))
return { 0_byte, arg.length(), complete(arg, pos_in_token, HighlighterRegistry::instance() | transform(HighlighterRegistry::get_id)) };
return { 0_byte, arg.length(), complete(arg, pos_in_token, HighlighterRegistry::instance() | transform(std::mem_fn(&HighlighterRegistry::Item::key))) };
return Completions{};
}

View File

@ -16,7 +16,7 @@ EnvVarMap get_env_vars()
const char* value = name;
while (*value != 0 and *value != '=')
++value;
env_vars.append({{name, value}, (*value == '=') ? value+1 : String{}});
env_vars.insert({{name, value}, (*value == '=') ? value+1 : String{}});
}
return env_vars;
}

View File

@ -1,13 +1,13 @@
#ifndef env_vars_hh_INCLUDED
#define env_vars_hh_INCLUDED
#include "id_map.hh"
#include "hash_map.hh"
namespace Kakoune
{
class String;
using EnvVarMap = IdMap<String, MemoryDomain::EnvVars>;
using EnvVarMap = HashMap<String, String, MemoryDomain::EnvVars>;
EnvVarMap get_env_vars();

View File

@ -50,8 +50,8 @@ UnitTest test_hash_map{[] {
{
HashMap<String, int> map;
map.insert({"test", 10});
kak_assert(map["test"_sv] == 10);
map.remove("test"_sv);
kak_assert(map[StringView{"test"}] == 10);
map.remove(StringView{"test"});
}
// make sure we get what we expect from the hash map

View File

@ -160,11 +160,6 @@ struct HashMap
HashCompatible<Key, typename std::decay<KeyType>::type>::value
>::type;
// For IdMap inteface compatibility, to remove
using Element = Item;
Value& append(Item item) { return insert(std::move(item)); }
static const String& get_id(const Element& e) { return e.key; }
template<typename KeyType, typename = EnableIfHashCompatible<KeyType>>
int find_index(const KeyType& key, size_t hash) const
{

View File

@ -5,7 +5,7 @@
#include "completion.hh"
#include "display_buffer.hh"
#include "exception.hh"
#include "id_map.hh"
#include "hash_map.hh"
#include "array_view.hh"
#include "string.hh"
#include "utils.hh"
@ -71,7 +71,7 @@ struct HighlighterFactoryAndDocstring
String docstring;
};
struct HighlighterRegistry : IdMap<HighlighterFactoryAndDocstring, MemoryDomain::Highlight>,
struct HighlighterRegistry : HashMap<String, HighlighterFactoryAndDocstring, MemoryDomain::Highlight>,
Singleton<HighlighterRegistry>
{};

View File

@ -19,7 +19,7 @@ void HighlighterGroup::add_child(HighlighterAndId&& hl)
if (m_highlighters.contains(hl.first))
throw runtime_error(format("duplicate id: '{}'", hl.first));
m_highlighters.append({ std::move(hl.first), std::move(hl.second) });
m_highlighters.insert({std::move(hl.first), std::move(hl.second)});
}
void HighlighterGroup::remove_child(StringView id)
@ -52,9 +52,9 @@ Completions HighlighterGroup::complete_child(StringView path, ByteCount cursor_p
auto candidates = complete(
path, cursor_pos,
m_highlighters | filter([=](const HighlighterMap::Element& hl)
m_highlighters | filter([=](const HighlighterMap::Item& hl)
{ return not group or hl.value->has_children(); })
| transform(HighlighterMap::get_id));
| transform(std::mem_fn(&HighlighterMap::Item::key)));
return { 0, 0, std::move(candidates) };
}

View File

@ -2,7 +2,7 @@
#define highlighter_group_hh_INCLUDED
#include "exception.hh"
#include "id_map.hh"
#include "hash_map.hh"
#include "highlighter.hh"
#include "utils.hh"
@ -28,7 +28,7 @@ public:
Completions complete_child(StringView path, ByteCount cursor_pos, bool group) const override;
private:
using HighlighterMap = IdMap<std::unique_ptr<Highlighter>, MemoryDomain::Highlight>;
using HighlighterMap = HashMap<String, std::unique_ptr<Highlighter>, MemoryDomain::Highlight>;
HighlighterMap m_highlighters;
};

View File

@ -1291,12 +1291,12 @@ public:
for (auto& region : m_regions)
{
m_groups.append({region.m_name, HighlighterGroup{}});
m_groups.insert({region.m_name, HighlighterGroup{}});
if (region.m_begin.empty() or region.m_end.empty())
throw runtime_error("invalid regex for region highlighter");
}
if (not m_default_group.empty())
m_groups.append({m_default_group, HighlighterGroup{}});
m_groups.insert({m_default_group, HighlighterGroup{}});
}
void highlight(const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer, BufferRange range) override
@ -1371,7 +1371,7 @@ public:
return offset_pos(hl.complete_child(path.substr(offset), cursor_pos - offset, group), offset);
}
auto container = m_groups | transform(decltype(m_groups)::get_id);
auto container = m_groups | transform(std::mem_fn(&decltype(m_groups)::Item::key));
return { 0, 0, complete(path, cursor_pos, container) };
}
@ -1411,7 +1411,7 @@ public:
private:
const RegionDescList m_regions;
const String m_default_group;
IdMap<HighlighterGroup, MemoryDomain::Highlight> m_groups;
HashMap<String, HighlighterGroup, MemoryDomain::Highlight> m_groups;
struct Region
{
@ -1521,66 +1521,66 @@ void register_highlighters()
{
HighlighterRegistry& registry = HighlighterRegistry::instance();
registry.append({
registry.insert({
"number_lines",
{ number_lines_factory,
"Display line numbers \n"
"Parameters: -relative, -hlcursor, -separator <separator text>\n" } });
registry.append({
registry.insert({
"show_matching",
{ create_matching_char_highlighter,
"Apply the MatchingChar face to the char matching the one under the cursor" } });
registry.append({
registry.insert({
"show_whitespaces",
{ show_whitespaces_factory,
"Display whitespaces using symbols \n"
"Parameters: -tab <separator> -tabpad <separator> -lf <separator> -spc <separator> -nbsp <separator>\n" } });
registry.append({
registry.insert({
"fill",
{ create_fill_highlighter,
"Fill the whole highlighted range with the given face" } });
registry.append({
registry.insert({
"regex",
{ RegexHighlighter::create,
"Parameters: <regex> <capture num>:<face> <capture num>:<face>...\n"
"Highlights the matches for captures from the regex with the given faces" } });
registry.append({
registry.insert({
"dynregex",
{ create_dynamic_regex_highlighter,
"Parameters: <expr> <capture num>:<face> <capture num>:<face>...\n"
"Evaluate expression at every redraw to gather a regex" } });
registry.append({
registry.insert({
"group",
{ create_highlighter_group,
"Parameters: <group name>\n"
"Creates a named group that can contain other highlighters" } });
registry.append({
registry.insert({
"flag_lines",
{ create_flag_lines_highlighter,
"Parameters: <option name> <bg color>\n"
"Display flags specified in the line-flag-list option <option name>\n"
"A line-flag is written: <line>|<fg color>|<text>, the list is : separated" } });
registry.append({
registry.insert({
"ranges",
{ create_ranges_highlighter,
"Parameters: <option name>\n"
"Use the range-faces option given as parameter to highlight buffer\n" } });
registry.append({
registry.insert({
"line",
{ create_line_highlighter,
"Parameters: <value string> <face>\n"
"Highlight the line given by evaluating <value string> with <face>" } });
registry.append({
registry.insert({
"column",
{ create_column_highlighter,
"Parameters: <value string> <face>\n"
"Highlight the column given by evaluating <value string> with <face>" } });
registry.append({
registry.insert({
"ref",
{ create_reference_highlighter,
"Parameters: <path>\n"
"Reference the highlighter at <path> in shared highglighters" } });
registry.append({
registry.insert({
"regions",
{ RegionsHighlighter::create,
"Parameters: [-default <default group>] [-match-capture] <name> {<region name> <begin> <end> <recurse>}..."

View File

@ -14,7 +14,7 @@ namespace Kakoune
void HookManager::add_hook(StringView hook_name, String group, HookFunc hook)
{
auto& hooks = m_hooks[hook_name];
hooks.append({std::move(group), std::move(hook)});
hooks.insert({std::move(group), std::move(hook)});
}
void HookManager::remove_hooks(StringView group)
@ -30,7 +30,7 @@ CandidateList HookManager::complete_hook_group(StringView prefix, ByteCount pos_
CandidateList res;
for (auto& list : m_hooks)
{
auto container = list.value | transform(decltype(list.value)::get_id);
auto container = list.value | transform(std::mem_fn(&decltype(list.value)::Item::key));
for (auto& c : complete(prefix, pos_in_token, container))
{
if (!contains(res, c))

View File

@ -1,7 +1,7 @@
#ifndef hook_manager_hh_INCLUDED
#define hook_manager_hh_INCLUDED
#include "id_map.hh"
#include "hash_map.hh"
#include "completion.hh"
#include "safe_ptr.hh"
@ -29,7 +29,7 @@ private:
friend class Scope;
SafePtr<HookManager> m_parent;
IdMap<IdMap<HookFunc, MemoryDomain::Hooks>, MemoryDomain::Hooks> m_hooks;
HashMap<String, HashMap<String, HookFunc, MemoryDomain::Hooks>, MemoryDomain::Hooks> m_hooks;
mutable Vector<std::pair<StringView, StringView>, MemoryDomain::Hooks> m_running_hooks;
};

View File

@ -1,124 +0,0 @@
#ifndef id_map_hh_INCLUDED
#define id_map_hh_INCLUDED
#include "string.hh"
#include "vector.hh"
#include <algorithm>
namespace Kakoune
{
template<typename Value, MemoryDomain domain = MemoryDomain::Undefined>
class IdMap
{
public:
struct Element
{
Element(String k, Value v)
: hash(hash_value(k)), key(std::move(k)), value(std::move(v)) {}
size_t hash;
String key;
Value value;
bool operator==(const Element& other) const
{
return hash == other.hash and key == other.key and value == other.value;
}
};
using container_type = Vector<Element, domain>;
using iterator = typename container_type::iterator;
using const_iterator = typename container_type::const_iterator;
IdMap() = default;
IdMap(std::initializer_list<Element> val) : m_content{val} {}
void append(const Element& value)
{
m_content.push_back(value);
}
void append(Element&& value)
{
m_content.push_back(std::move(value));
}
iterator find(StringView id)
{
const size_t hash = hash_value(id);
return std::find_if(begin(), end(),
[id, hash](const Element& e)
{ return e.hash == hash and e.key == id; });
}
const_iterator find(StringView id) const
{
return const_cast<IdMap*>(this)->find(id);
}
bool contains(StringView id) const
{
return find(id) != end();
}
void remove(StringView id)
{
auto it = find(id);
if (it != end())
m_content.erase(it);
}
void remove_all(StringView id)
{
const size_t hash = hash_value(id);
auto it = std::remove_if(begin(), end(), [id, hash](const Element& e)
{ return e.hash == hash and e.key == id; });
m_content.erase(it, end());
}
Value& operator[](StringView id)
{
auto it = find(id);
if (it != m_content.end())
return it->value;
append({ id.str(), Value{} });
return (m_content.end()-1)->value;
}
template<MemoryDomain dom>
bool operator==(const IdMap<Value, dom>& other) const
{
return size() == other.size() and std::equal(begin(), end(), other.begin());
}
template<MemoryDomain dom>
bool operator!=(const IdMap<Value, dom>& other) const
{
return not (*this == other);
}
void reserve(size_t size) { m_content.reserve(size); }
size_t size() const { return m_content.size(); }
void clear() { m_content.clear(); }
void erase(iterator it) { m_content.erase(it); }
static const String& get_id(const Element& e) { return e.key; }
bool empty() const { return m_content.empty(); }
iterator begin() { return m_content.begin(); }
iterator end() { return m_content.end(); }
const_iterator begin() const { return m_content.begin(); }
const_iterator end() const { return m_content.end(); }
private:
container_type m_content;
};
}
#endif // id_map_hh_INCLUDED

View File

@ -230,7 +230,7 @@ void JsonUI::set_on_key(OnKeyCallback callback)
}
using JsonArray = Vector<Value>;
using JsonObject = IdMap<Value>;
using JsonObject = HashMap<String, Value>;
static bool is_digit(char c) { return c >= '0' and c <= '9'; }
@ -324,7 +324,7 @@ parse_json(const char* pos, const char* end)
std::tie(element, pos) = parse_json(pos, end);
if (not element)
return {};
object.append({ std::move(name), std::move(element) });
object.insert({ std::move(name), std::move(element) });
if (not skip_while(pos, end, is_blank))
return {};

View File

@ -4,6 +4,7 @@
#include "user_interface.hh"
#include "event_manager.hh"
#include "coord.hh"
#include "string.hh"
namespace Kakoune
{

View File

@ -1,12 +1,14 @@
#ifndef ncurses_hh_INCLUDED
#define ncurses_hh_INCLUDED
#include "array_view.hh"
#include "coord.hh"
#include "event_manager.hh"
#include "face.hh"
#include "user_interface.hh"
#include "array_view.hh"
#include "hash_map.hh"
#include "optional.hh"
#include "string.hh"
#include "user_interface.hh"
namespace Kakoune
{

View File

@ -6,7 +6,6 @@
#include "units.hh"
#include "coord.hh"
#include "array_view.hh"
#include "id_map.hh"
#include "hash_map.hh"
#include "flags.hh"
#include "enum.hh"
@ -107,44 +106,6 @@ struct option_type_name<Vector<T, D>>
static String name() { return option_type_name<T>::name() + StringView{"-list"}; }
};
template<typename Value, MemoryDomain domain>
String option_to_string(const IdMap<Value, domain>& opt)
{
String res;
for (auto it = begin(opt); it != end(opt); ++it)
{
if (it != begin(opt))
res += list_separator;
String elem = escape(option_to_string(it->key), '=', '\\') + "=" +
escape(option_to_string(it->value), '=', '\\');
res += escape(elem, list_separator, '\\');
}
return res;
}
template<typename Value, MemoryDomain domain>
void option_from_string(StringView str, IdMap<Value, domain>& opt)
{
opt.clear();
for (auto& elem : split(str, list_separator, '\\'))
{
Vector<String> pair_str = split(elem, '=', '\\');
if (pair_str.size() != 2)
throw runtime_error("map option expects key=value");
String key;
Value value;
option_from_string(pair_str[0], key);
option_from_string(pair_str[1], value);
opt.append({ std::move(key), std::move(value) });
}
}
template<typename T, MemoryDomain D>
struct option_type_name<IdMap<T, D>>
{
static String name() { return format("str-to-{}-map", option_type_name<T>::name()); }
};
template<typename Key, typename Value, MemoryDomain domain>
String option_to_string(const HashMap<Key, Value, domain>& opt)
{

View File

@ -2,7 +2,7 @@
#define parameters_parser_hh_INCLUDED
#include "exception.hh"
#include "id_map.hh"
#include "hash_map.hh"
#include "array_view.hh"
#include "flags.hh"
#include "optional.hh"
@ -41,7 +41,7 @@ struct SwitchDesc
String description;
};
using SwitchMap = IdMap<SwitchDesc, MemoryDomain::Commands>;
using SwitchMap = HashMap<String, SwitchDesc, MemoryDomain::Commands>;
String generate_switches_doc(const SwitchMap& opts);

View File

@ -1,7 +1,7 @@
#include "register_manager.hh"
#include "assert.hh"
#include "id_map.hh"
#include "hash_map.hh"
namespace Kakoune
{
@ -11,7 +11,7 @@ Register& RegisterManager::operator[](StringView reg) const
if (reg.length() == 1)
return (*this)[reg[0_byte]];
static const IdMap<Codepoint> reg_names = {
static const HashMap<String, Codepoint> reg_names = {
{ "slash", '/' },
{ "dquote", '"' },
{ "pipe", '|' },

View File

@ -7,7 +7,7 @@
#include "display_buffer.hh"
#include "event_manager.hh"
#include "file.hh"
#include "id_map.hh"
#include "hash_map.hh"
#include "optional.hh"
#include "user_interface.hh"
@ -92,8 +92,8 @@ public:
write(ConstArrayView<T>(vec));
}
template<typename Val, MemoryDomain domain>
void write(const IdMap<Val, domain>& map)
template<typename Key, typename Val, MemoryDomain domain>
void write(const HashMap<Key, Val, domain>& map)
{
write<uint32_t>(map.size());
for (auto& val : map)
@ -213,17 +213,17 @@ public:
return res;
}
template<typename Val, MemoryDomain domain>
IdMap<Val, domain> read_idmap()
template<typename Key, typename Val, MemoryDomain domain>
HashMap<Key, Val, domain> read_hash_map()
{
uint32_t size = read<uint32_t>();
IdMap<Val, domain> res;
HashMap<Key, Val, domain> res;
res.reserve(size);
while (size--)
{
auto key = read<String>();
auto key = read<Key>();
auto val = read<Val>();
res.append({std::move(key), std::move(val)});
res.insert({std::move(key), std::move(val)});
}
return res;
}
@ -615,7 +615,7 @@ RemoteClient::RemoteClient(StringView session, std::unique_ptr<UserInterface>&&
m_ui->refresh(reader.read<bool>());
break;
case MessageType::SetOptions:
m_ui->set_ui_options(reader.read_idmap<String, MemoryDomain::Options>());
m_ui->set_ui_options(reader.read_hash_map<String, String, MemoryDomain::Options>());
break;
default:
kak_assert(false);
@ -673,7 +673,7 @@ private:
auto init_cmds = m_reader.read<String>();
auto init_coord = m_reader.read_optional<BufferCoord>();
auto dimensions = m_reader.read<DisplayCoord>();
auto env_vars = m_reader.read_idmap<String, MemoryDomain::EnvVars>();
auto env_vars = m_reader.read_hash_map<String, String, MemoryDomain::EnvVars>();
auto* ui = new RemoteUI{sock, dimensions};
if (auto* client = ClientManager::instance().create_client(
std::unique_ptr<UserInterface>(ui),

View File

@ -2,7 +2,7 @@
#define user_interface_hh_INCLUDED
#include "array_view.hh"
#include "id_map.hh"
#include "hash_map.hh"
#include <functional>
@ -66,7 +66,7 @@ public:
virtual void set_on_key(OnKeyCallback callback) = 0;
using Options = IdMap<String, MemoryDomain::Options>;
using Options = HashMap<String, String, MemoryDomain::Options>;
virtual void set_ui_options(const Options& options) = 0;
};