summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2014-12-16 18:57:19 +0000
committerMaxime Coste <frrrwww@gmail.com>2014-12-16 18:57:19 +0000
commitebecd60eb810246cfa682a1fbd72270aa9861f0b (patch)
tree0c5c707b68cb08fc93ace2433291deb8a52db5bc
parentdbd7bd41bbf39d1fd5736997122a4652c78ddc50 (diff)
Rework hashing, use a more extensible framework similar to n3876 proposal
std::hash specialization is a pain to work with, stop using that, and just specialize a 'size_t hash_value(const T&)' free function.
-rw-r--r--src/alias_registry.hh5
-rw-r--r--src/color.hh23
-rw-r--r--src/command_manager.cc2
-rw-r--r--src/command_manager.hh4
-rw-r--r--src/coord.hh16
-rw-r--r--src/env_vars.hh4
-rw-r--r--src/face_registry.hh5
-rw-r--r--src/file.cc2
-rw-r--r--src/hash.cc68
-rw-r--r--src/hash.hh57
-rw-r--r--src/highlighter.hh16
-rw-r--r--src/highlighters.cc2
-rw-r--r--src/hook_manager.hh5
-rw-r--r--src/input_handler.cc7
-rw-r--r--src/interned_string.hh18
-rw-r--r--src/keymap_manager.cc14
-rw-r--r--src/keymap_manager.hh7
-rw-r--r--src/keys.hh18
-rw-r--r--src/ncurses_ui.cc2
-rw-r--r--src/normal.hh4
-rw-r--r--src/option_types.hh6
-rw-r--r--src/register_manager.hh4
-rw-r--r--src/remote.cc6
-rw-r--r--src/string.cc60
-rw-r--r--src/string.hh26
-rw-r--r--src/units.hh8
-rw-r--r--src/unordered_map.hh17
-rw-r--r--src/user_interface.hh4
-rw-r--r--src/utils.hh17
-rw-r--r--src/value.hh23
-rw-r--r--src/word_db.hh2
31 files changed, 239 insertions, 213 deletions
diff --git a/src/alias_registry.hh b/src/alias_registry.hh
index e2d4e271..3010ce49 100644
--- a/src/alias_registry.hh
+++ b/src/alias_registry.hh
@@ -3,8 +3,7 @@
#include "safe_ptr.hh"
#include "string.hh"
-
-#include <unordered_map>
+#include "unordered_map.hh"
namespace Kakoune
{
@@ -24,7 +23,7 @@ private:
AliasRegistry() {}
safe_ptr<AliasRegistry> m_parent;
- std::unordered_map<String, String> m_aliases;
+ UnorderedMap<String, String> m_aliases;
};
}
diff --git a/src/color.hh b/src/color.hh
index 1de59fcd..1b3ba9c6 100644
--- a/src/color.hh
+++ b/src/color.hh
@@ -1,6 +1,8 @@
#ifndef color_hh_INCLUDED
#define color_hh_INCLUDED
+#include "hash.hh"
+
namespace Kakoune
{
@@ -32,13 +34,19 @@ struct Color
Color(Colors c) : color{c}, r{0}, g{0}, b{0} {}
Color(unsigned char r, unsigned char g, unsigned char b)
: color{Colors::RGB}, r{r}, g{g}, b{b} {}
-
- bool operator==(Color c) const
- { return color == c.color and r == c.r and g == c.g and b == c.b; }
- bool operator!=(Color c) const
- { return color != c.color or r != c.r or g != c.g or b != c.b; }
};
+inline bool operator==(Color lhs, Color rhs)
+{
+ return lhs.color == rhs.color and
+ lhs.r == rhs.r and lhs.g == rhs.g and lhs.b == rhs.b;
+}
+
+inline bool operator!=(Color lhs, Color rhs)
+{
+ return not (lhs == rhs);
+}
+
Color str_to_color(StringView color);
String color_to_str(Color color);
@@ -47,6 +55,11 @@ void option_from_string(StringView str, Color& color);
bool is_color_name(StringView color);
+inline size_t hash_value(const Color& val)
+{
+ return hash_values(val.color, val.r, val.g, val.b);
+}
+
}
#endif // color_hh_INCLUDED
diff --git a/src/command_manager.cc b/src/command_manager.cc
index 02d95949..390b3e99 100644
--- a/src/command_manager.cc
+++ b/src/command_manager.cc
@@ -189,7 +189,7 @@ Token parse_percent_token(StringView line, ByteCount& pos)
type_name + "'"};
Token::Type type = token_type<throw_on_unterminated>(type_name);
- static const std::unordered_map<char, char> matching_delimiters = {
+ static const UnorderedMap<char, char> matching_delimiters = {
{ '(', ')' }, { '[', ']' }, { '{', '}' }, { '<', '>' }
};
diff --git a/src/command_manager.hh b/src/command_manager.hh
index ca397a8f..90b583f9 100644
--- a/src/command_manager.hh
+++ b/src/command_manager.hh
@@ -9,8 +9,8 @@
#include "parameters_parser.hh"
#include "string.hh"
#include "utils.hh"
+#include "unordered_map.hh"
-#include <unordered_map>
#include <functional>
#include <initializer_list>
@@ -88,7 +88,7 @@ private:
CommandFlags flags;
CommandCompleter completer;
};
- using CommandMap = std::unordered_map<String, CommandDescriptor>;
+ using CommandMap = UnorderedMap<String, CommandDescriptor>;
CommandMap m_commands;
CommandMap::const_iterator find_command(const Context& context,
diff --git a/src/coord.hh b/src/coord.hh
index dbae5001..ed9347a5 100644
--- a/src/coord.hh
+++ b/src/coord.hh
@@ -2,6 +2,7 @@
#define coord_hh_INCLUDED
#include "units.hh"
+#include "hash.hh"
namespace Kakoune
{
@@ -92,6 +93,11 @@ struct ByteCoord : LineAndColumn<ByteCoord, LineCount, ByteCount>
: LineAndColumn(line, column) {}
};
+inline size_t hash_value(const ByteCoord& val)
+{
+ return hash_values(val.line, val.column);
+}
+
struct CharCoord : LineAndColumn<CharCoord, LineCount, CharCount>
{
[[gnu::always_inline]]
@@ -99,6 +105,11 @@ struct CharCoord : LineAndColumn<CharCoord, LineCount, CharCount>
: LineAndColumn(line, column) {}
};
+inline size_t hash_value(const CharCoord& val)
+{
+ return hash_values(val.line, val.column);
+}
+
struct ByteCoordAndTarget : ByteCoord
{
[[gnu::always_inline]]
@@ -112,6 +123,11 @@ struct ByteCoordAndTarget : ByteCoord
CharCount target;
};
+inline size_t hash_value(const ByteCoordAndTarget& val)
+{
+ return hash_values(val.line, val.column, val.target);
+}
+
}
#endif // coord_hh_INCLUDED
diff --git a/src/env_vars.hh b/src/env_vars.hh
index 89d3459e..cbab16ed 100644
--- a/src/env_vars.hh
+++ b/src/env_vars.hh
@@ -1,13 +1,13 @@
#ifndef env_vars_hh_INCLUDED
#define env_vars_hh_INCLUDED
-#include <unordered_map>
+#include "unordered_map.hh"
namespace Kakoune
{
class String;
-using EnvVarMap = std::unordered_map<String, String>;
+using EnvVarMap = UnorderedMap<String, String>;
EnvVarMap get_env_vars();
diff --git a/src/face_registry.hh b/src/face_registry.hh
index 7e77c1cc..f99d6b12 100644
--- a/src/face_registry.hh
+++ b/src/face_registry.hh
@@ -4,8 +4,7 @@
#include "face.hh"
#include "utils.hh"
#include "completion.hh"
-
-#include <unordered_map>
+#include "unordered_map.hh"
namespace Kakoune
{
@@ -30,7 +29,7 @@ private:
FaceOrAlias(Face face = Face{}) : face(face) {}
};
- std::unordered_map<String, FaceOrAlias> m_aliases;
+ UnorderedMap<String, FaceOrAlias> m_aliases;
};
inline Face get_face(const String& facedesc)
diff --git a/src/file.cc b/src/file.cc
index 19ef313a..5bab7304 100644
--- a/src/file.cc
+++ b/src/file.cc
@@ -356,7 +356,7 @@ std::vector<String> complete_command(StringView prefix, ByteCount cursor_pos)
TimeSpec mtime = {};
std::vector<String> commands;
};
- static std::unordered_map<String, CommandCache> command_cache;
+ static UnorderedMap<String, CommandCache> command_cache;
std::vector<StringView> path;
if (dir_end != -1)
diff --git a/src/hash.cc b/src/hash.cc
new file mode 100644
index 00000000..2ef9262d
--- /dev/null
+++ b/src/hash.cc
@@ -0,0 +1,68 @@
+#include "hash.hh"
+
+#include <cstdint>
+
+namespace Kakoune
+{
+
+[[gnu::always_inline]]
+static inline uint32_t rotl(uint32_t x, int8_t r)
+{
+ return (x << r) | (x >> (32 - r));
+}
+
+[[gnu::always_inline]]
+static inline uint32_t fmix(uint32_t h)
+{
+ h ^= h >> 16;
+ h *= 0x85ebca6b;
+ h ^= h >> 13;
+ h *= 0xc2b2ae35;
+ h ^= h >> 16;
+
+ return h;
+}
+
+// murmur3 hash, based on https://github.com/PeterScott/murmur3
+size_t hash_data(const char* input, size_t len)
+{
+ const uint8_t* data = reinterpret_cast<const uint8_t*>(input);
+ uint32_t hash = 0x1235678;
+ constexpr uint32_t c1 = 0xcc9e2d51;
+ constexpr uint32_t c2 = 0x1b873593;
+
+ const int nblocks = len / 4;
+ const uint32_t* blocks = reinterpret_cast<const uint32_t*>(data + nblocks*4);
+
+ for (int i = -nblocks; i; ++i)
+ {
+ uint32_t key = blocks[i];
+ key *= c1;
+ key = rotl(key, 15);
+ key *= c2;
+
+ hash ^= key;
+ hash = rotl(hash, 13);
+ hash = hash * 5 + 0xe6546b64;
+ }
+
+ const uint8_t* tail = data + nblocks * 4;
+ uint32_t key = 0;
+ switch (len & 3)
+ {
+ case 3: key ^= tail[2] << 16;
+ case 2: key ^= tail[1] << 8;
+ case 1: key ^= tail[0];
+ key *= c1;
+ key = rotl(key,15);
+ key *= c2;
+ hash ^= key;
+ }
+
+ hash ^= len;
+ hash = fmix(hash);
+
+ return hash;
+}
+
+}
diff --git a/src/hash.hh b/src/hash.hh
new file mode 100644
index 00000000..838fdffa
--- /dev/null
+++ b/src/hash.hh
@@ -0,0 +1,57 @@
+#ifndef hash_hh_INCLUDED
+#define hash_hh_INCLUDED
+
+#include <type_traits>
+#include <functional>
+
+namespace Kakoune
+{
+
+size_t hash_data(const char* data, size_t len);
+
+template<typename Type>
+typename std::enable_if<not std::is_enum<Type>::value, size_t>::type
+hash_value(const Type& val)
+{
+ return std::hash<Type>()(val);
+}
+
+template<typename Type>
+typename std::enable_if<std::is_enum<Type>::value, size_t>::type
+hash_value(const Type& val)
+{
+ return hash_value((typename std::underlying_type<Type>::type)val);
+}
+
+template<typename Type>
+size_t hash_values(Type&& t)
+{
+ return hash_value(std::forward<Type>(t));
+}
+
+template<typename Type, typename... RemainingTypes>
+size_t hash_values(Type&& t, RemainingTypes&&... rt)
+{
+ size_t seed = hash_values(std::forward<RemainingTypes>(rt)...);
+ return seed ^ (hash_value(std::forward<Type>(t)) + 0x9e3779b9 +
+ (seed << 6) + (seed >> 2));
+}
+
+template<typename T1, typename T2>
+size_t hash_value(const std::pair<T1, T2>& val)
+{
+ return hash_values(val.first, val.second);
+}
+
+template<typename Type>
+struct Hash
+{
+ size_t operator()(const Type& val) const
+ {
+ return hash_value(val);
+ }
+};
+
+}
+
+#endif // hash_hh_INCLUDED
diff --git a/src/highlighter.hh b/src/highlighter.hh
index 88003dc0..bf67cbcb 100644
--- a/src/highlighter.hh
+++ b/src/highlighter.hh
@@ -9,22 +9,6 @@
#include <functional>
-namespace std
-{
-
-template<>
-struct hash<Kakoune::ByteCoord>
-{
- size_t operator()(const Kakoune::ByteCoord& val) const
- {
- size_t seed = std::hash<int>()((int)val.line);
- return seed ^ (std::hash<int>()((int)val.column) + 0x9e3779b9 +
- (seed << 6) + (seed >> 2));
- }
-};
-
-}
-
namespace Kakoune
{
diff --git a/src/highlighters.cc b/src/highlighters.cc
index 354bed0d..4f999230 100644
--- a/src/highlighters.cc
+++ b/src/highlighters.cc
@@ -1017,7 +1017,7 @@ private:
{
size_t timestamp = 0;
std::vector<RegionMatches> matches;
- std::unordered_map<BufferRange, RegionList> regions;
+ UnorderedMap<BufferRange, RegionList> regions;
};
BufferSideCache<Cache> m_cache;
diff --git a/src/hook_manager.hh b/src/hook_manager.hh
index 93a67ef7..5aa52b2f 100644
--- a/src/hook_manager.hh
+++ b/src/hook_manager.hh
@@ -2,8 +2,7 @@
#define hook_manager_hh_INCLUDED
#include "id_map.hh"
-
-#include <unordered_map>
+#include "unordered_map.hh"
namespace Kakoune
{
@@ -29,7 +28,7 @@ private:
friend class Scope;
HookManager* m_parent;
- std::unordered_map<String, id_map<HookFunc>> m_hook;
+ UnorderedMap<String, id_map<HookFunc>> m_hook;
};
}
diff --git a/src/input_handler.cc b/src/input_handler.cc
index ea6da4b0..ae6ac83b 100644
--- a/src/input_handler.cc
+++ b/src/input_handler.cc
@@ -9,12 +9,11 @@
#include "normal.hh"
#include "regex.hh"
#include "register_manager.hh"
+#include "unordered_map.hh"
#include "user_interface.hh"
#include "utf8.hh"
#include "window.hh"
-#include <unordered_map>
-
namespace Kakoune
{
@@ -736,10 +735,10 @@ private:
bool m_autoshowcompl;
Mode m_mode = Mode::Default;
- static std::unordered_map<String, std::vector<String>> ms_history;
+ static UnorderedMap<String, std::vector<String>> ms_history;
std::vector<String>::iterator m_history_it;
};
-std::unordered_map<String, std::vector<String>> Prompt::ms_history;
+UnorderedMap<String, std::vector<String>> Prompt::ms_history;
class NextKey : public InputMode
{
diff --git a/src/interned_string.hh b/src/interned_string.hh
index fd79de2c..41a1b034 100644
--- a/src/interned_string.hh
+++ b/src/interned_string.hh
@@ -3,8 +3,7 @@
#include "string.hh"
#include "utils.hh"
-
-#include <unordered_map>
+#include "unordered_map.hh"
namespace Kakoune
{
@@ -20,7 +19,7 @@ private:
void acquire(size_t slot);
void release(size_t slot) noexcept;
- std::unordered_map<StringView, size_t> m_slot_map;
+ UnorderedMap<StringView, size_t> m_slot_map;
std::vector<size_t> m_free_slots;
using DataAndRefCount = std::pair<std::vector<char>, int>;
std::vector<DataAndRefCount> m_storage;
@@ -118,18 +117,11 @@ private:
size_t m_slot = -1;
};
+inline size_t hash_value(const Kakoune::InternedString& str)
+{
+ return hash_data(str.data(), (int)str.length());
}
-namespace std
-{
- template<>
- struct hash<Kakoune::InternedString>
- {
- size_t operator()(const Kakoune::InternedString& str) const
- {
- return Kakoune::hash_data(str.data(), (int)str.length());
- }
- };
}
#endif // interned_string_hh_INCLUDED
diff --git a/src/keymap_manager.cc b/src/keymap_manager.cc
index 0d376a1b..74323a84 100644
--- a/src/keymap_manager.cc
+++ b/src/keymap_manager.cc
@@ -1,19 +1,7 @@
#include "keymap_manager.hh"
#include "memoryview.hh"
-
-namespace std
-{
-
-template<> struct hash<Kakoune::KeymapMode>
-{
- size_t operator()(Kakoune::KeymapMode val) const
- {
- return hash<int>{}((int)val);
- }
-};
-
-}
+#include "assert.hh"
namespace Kakoune
{
diff --git a/src/keymap_manager.hh b/src/keymap_manager.hh
index 5743a18e..b7f7019b 100644
--- a/src/keymap_manager.hh
+++ b/src/keymap_manager.hh
@@ -2,9 +2,9 @@
#define keymap_manager_hh_INCLUDED
#include "keys.hh"
-#include "utils.hh"
+#include "hash.hh"
+#include "unordered_map.hh"
-#include <unordered_map>
#include <vector>
namespace Kakoune
@@ -43,7 +43,8 @@ private:
KeymapManager* m_parent;
using KeyList = std::vector<Key>;
- using Keymap = std::unordered_map<std::pair<Key, KeymapMode>, KeyList>;
+ using KeyAndMode = std::pair<Key, KeymapMode>;
+ using Keymap = UnorderedMap<KeyAndMode, KeyList>;
Keymap m_mapping;
};
diff --git a/src/keys.hh b/src/keys.hh
index 3123f7cc..92ae0f70 100644
--- a/src/keys.hh
+++ b/src/keys.hh
@@ -3,6 +3,7 @@
#include "unicode.hh"
#include "flags.hh"
+#include "hash.hh"
#include <vector>
@@ -11,7 +12,7 @@ namespace Kakoune
struct Key
{
- enum class Modifiers
+ enum class Modifiers : int
{
None = 0,
Control = 1 << 0,
@@ -78,21 +79,8 @@ constexpr Key alt(Codepoint key) { return { Key::Modifiers::Alt, key }; }
constexpr Key ctrl(Codepoint key) { return { Key::Modifiers::Control, key }; }
constexpr Key ctrlalt(Codepoint key) { return { Key::Modifiers::ControlAlt, key }; }
-}
-
-namespace std
-{
-
-template<>
-struct hash<Kakoune::Key>
-{
- size_t operator()(Kakoune::Key key) const
- {
- return static_cast<size_t>(key.modifiers) * 1024 + key.key;
- }
-};
+inline size_t hash_value(const Key& key) { return hash_values(key.modifiers, key.key); }
}
-
#endif // keys_hh_INCLUDED
diff --git a/src/ncurses_ui.cc b/src/ncurses_ui.cc
index 896c76a8..b11f5a58 100644
--- a/src/ncurses_ui.cc
+++ b/src/ncurses_ui.cc
@@ -166,7 +166,7 @@ static int nc_color(Color color)
static int get_color_pair(const Face& face)
{
using ColorPair = std::pair<Color, Color>;
- static std::map<ColorPair, int> colorpairs;
+ static UnorderedMap<ColorPair, int> colorpairs;
static int next_pair = 1;
ColorPair colors{face.fg, face.bg};
diff --git a/src/normal.hh b/src/normal.hh
index 45057c48..4baa21df 100644
--- a/src/normal.hh
+++ b/src/normal.hh
@@ -2,9 +2,9 @@
#define normal_hh_INCLUDED
#include "keys.hh"
+#include "unordered_map.hh"
#include <functional>
-#include <unordered_map>
namespace Kakoune
{
@@ -23,7 +23,7 @@ struct NormalCmdDesc
std::function<void (Context& context, NormalParams params)> func;
};
-using KeyMap = std::unordered_map<Key, NormalCmdDesc>;
+using KeyMap = UnorderedMap<Key, NormalCmdDesc>;
extern KeyMap keymap;
}
diff --git a/src/option_types.hh b/src/option_types.hh
index 739ab7a5..7b6dfe93 100644
--- a/src/option_types.hh
+++ b/src/option_types.hh
@@ -6,10 +6,10 @@
#include "units.hh"
#include "coord.hh"
#include "memoryview.hh"
+#include "unordered_map.hh"
#include <tuple>
#include <vector>
-#include <unordered_map>
namespace Kakoune
{
@@ -68,7 +68,7 @@ bool option_add(std::vector<T>& opt, const std::vector<T>& vec)
}
template<typename Key, typename Value>
-String option_to_string(const std::unordered_map<Key, Value>& opt)
+String option_to_string(const UnorderedMap<Key, Value>& opt)
{
String res;
for (auto it = begin(opt); it != end(opt); ++it)
@@ -83,7 +83,7 @@ String option_to_string(const std::unordered_map<Key, Value>& opt)
}
template<typename Key, typename Value>
-void option_from_string(StringView str, std::unordered_map<Key, Value>& opt)
+void option_from_string(StringView str, UnorderedMap<Key, Value>& opt)
{
opt.clear();
std::vector<String> elems = split(str, list_separator, '\\');
diff --git a/src/register_manager.hh b/src/register_manager.hh
index 97f84fc0..e4391c05 100644
--- a/src/register_manager.hh
+++ b/src/register_manager.hh
@@ -3,8 +3,8 @@
#include "register.hh"
#include "utils.hh"
+#include "unordered_map.hh"
-#include <unordered_map>
#include <vector>
#include <functional>
@@ -21,7 +21,7 @@ public:
void register_dynamic_register(char reg, RegisterRetriever function);
protected:
- std::unordered_map<char, std::unique_ptr<Register>> m_registers;
+ UnorderedMap<char, std::unique_ptr<Register>> m_registers;
};
}
diff --git a/src/remote.cc b/src/remote.cc
index 3f8cbde2..08a13e39 100644
--- a/src/remote.cc
+++ b/src/remote.cc
@@ -82,7 +82,7 @@ public:
}
template<typename Key, typename Val>
- void write(const std::unordered_map<Key, Val>& map)
+ void write(const UnorderedMap<Key, Val>& map)
{
write<uint32_t>(map.size());
for (auto& val : map)
@@ -230,10 +230,10 @@ DisplayBuffer read<DisplayBuffer>(int socket)
}
template<typename Key, typename Val>
-std::unordered_map<Key, Val> read_map(int socket)
+UnorderedMap<Key, Val> read_map(int socket)
{
uint32_t size = read<uint32_t>(socket);
- std::unordered_map<Key, Val> res;
+ UnorderedMap<Key, Val> res;
while (size--)
{
auto key = read<Key>(socket);
diff --git a/src/string.cc b/src/string.cc
index 14c680c9..152b90aa 100644
--- a/src/string.cc
+++ b/src/string.cc
@@ -173,64 +173,4 @@ std::vector<StringView> wrap_lines(StringView text, CharCount max_width)
return lines;
}
-[[gnu::always_inline]]
-static inline uint32_t rotl(uint32_t x, int8_t r)
-{
- return (x << r) | (x >> (32 - r));
-}
-
-[[gnu::always_inline]]
-static inline uint32_t fmix(uint32_t h)
-{
- h ^= h >> 16;
- h *= 0x85ebca6b;
- h ^= h >> 13;
- h *= 0xc2b2ae35;
- h ^= h >> 16;
-
- return h;
-}
-
-// murmur3 hash, based on https://github.com/PeterScott/murmur3
-size_t hash_data(const char* input, size_t len)
-{
- const uint8_t* data = reinterpret_cast<const uint8_t*>(input);
- uint32_t hash = 0x1235678;
- constexpr uint32_t c1 = 0xcc9e2d51;
- constexpr uint32_t c2 = 0x1b873593;
-
- const int nblocks = len / 4;
- const uint32_t* blocks = reinterpret_cast<const uint32_t*>(data + nblocks*4);
-
- for (int i = -nblocks; i; ++i)
- {
- uint32_t key = blocks[i];
- key *= c1;
- key = rotl(key, 15);
- key *= c2;
-
- hash ^= key;
- hash = rotl(hash, 13);
- hash = hash * 5 + 0xe6546b64;
- }
-
- const uint8_t* tail = data + nblocks * 4;
- uint32_t key = 0;
- switch (len & 3)
- {
- case 3: key ^= tail[2] << 16;
- case 2: key ^= tail[1] << 8;
- case 1: key ^= tail[0];
- key *= c1;
- key = rotl(key,15);
- key *= c2;
- hash ^= key;
- }
-
- hash ^= len;
- hash = fmix(hash);
-
- return hash;
-}
-
}
diff --git a/src/string.hh b/src/string.hh
index eefe6985..afab4486 100644
--- a/src/string.hh
+++ b/src/string.hh
@@ -3,6 +3,7 @@
#include "units.hh"
#include "utf8.hh"
+#include "hash.hh"
#include <string>
#include <climits>
@@ -267,29 +268,16 @@ String expand_tabs(StringView line, CharCount tabstop, CharCount col = 0);
std::vector<StringView> wrap_lines(StringView text, CharCount max_width);
-size_t hash_data(const char* data, size_t len);
-
+inline size_t hash_value(const Kakoune::String& str)
+{
+ return hash_data(str.data(), (int)str.length());
}
-namespace std
+inline size_t hash_value(const Kakoune::StringView& str)
{
- template<>
- struct hash<Kakoune::String> : hash<std::string>
- {
- size_t operator()(const Kakoune::String& str) const
- {
- return hash<std::string>::operator()(str);
- }
- };
+ return hash_data(str.data(), (int)str.length());
+}
- template<>
- struct hash<Kakoune::StringView>
- {
- size_t operator()(Kakoune::StringView str) const
- {
- return Kakoune::hash_data(str.data(), (int)str.length());
- }
- };
}
#endif // string_hh_INCLUDED
diff --git a/src/units.hh b/src/units.hh
index 69ecffdb..5091c324 100644
--- a/src/units.hh
+++ b/src/units.hh
@@ -1,6 +1,8 @@
#ifndef units_hh_INCLUDED
#define units_hh_INCLUDED
+#include "hash.hh"
+
#include <type_traits>
namespace Kakoune
@@ -119,6 +121,8 @@ struct LineCount : public StronglyTypedNumber<LineCount, int>
constexpr LineCount(int value = 0) : StronglyTypedNumber<LineCount>(value) {}
};
+inline size_t hash_value(LineCount val) { return hash_value((int)val); }
+
[[gnu::always_inline]]
inline constexpr LineCount operator"" _line(unsigned long long int value)
{
@@ -131,6 +135,8 @@ struct ByteCount : public StronglyTypedNumber<ByteCount, int>
constexpr ByteCount(int value = 0) : StronglyTypedNumber<ByteCount>(value) {}
};
+inline size_t hash_value(ByteCount val) { return hash_value((int)val); }
+
[[gnu::always_inline]]
inline constexpr ByteCount operator"" _byte(unsigned long long int value)
{
@@ -149,6 +155,8 @@ inline constexpr CharCount operator"" _char(unsigned long long int value)
return CharCount(value);
}
+inline size_t hash_value(CharCount val) { return hash_value((int)val); }
+
}
#endif // units_hh_INCLUDED
diff --git a/src/unordered_map.hh b/src/unordered_map.hh
new file mode 100644
index 00000000..a3074ad6
--- /dev/null
+++ b/src/unordered_map.hh
@@ -0,0 +1,17 @@
+#ifndef unordered_map_hh_INCLUDED
+#define unordered_map_hh_INCLUDED
+
+#include "hash.hh"
+
+#include <unordered_map>
+
+namespace Kakoune
+{
+
+template<typename Key, typename Value>
+using UnorderedMap = std::unordered_map<Key, Value, Hash<Key>>;
+
+}
+
+#endif // unordered_map_hh_INCLUDED
+
diff --git a/src/user_interface.hh b/src/user_interface.hh
index b0884394..f401bf14 100644
--- a/src/user_interface.hh
+++ b/src/user_interface.hh
@@ -2,9 +2,9 @@
#define user_interface_hh_INCLUDED
#include "safe_ptr.hh"
+#include "unordered_map.hh"
#include <functional>
-#include <unordered_map>
namespace Kakoune
{
@@ -63,7 +63,7 @@ public:
virtual void set_input_callback(InputCallback callback) = 0;
- using Options = std::unordered_map<String, String>;
+ using Options = UnorderedMap<String, String>;
virtual void set_ui_options(const Options& options) = 0;
};
diff --git a/src/utils.hh b/src/utils.hh
index e4d392ff..c8e29f89 100644
--- a/src/utils.hh
+++ b/src/utils.hh
@@ -185,21 +185,4 @@ bool is_in_range(const T& val, const T& min, const T& max)
}
-// std::pair hashing
-namespace std
-{
-
-template<typename T1, typename T2>
-struct hash<std::pair<T1,T2>>
-{
- size_t operator()(const std::pair<T1,T2>& val) const
- {
- size_t seed = std::hash<T2>()(val.second);
- return seed ^ (std::hash<T1>()(val.first) + 0x9e3779b9 +
- (seed << 6) + (seed >> 2));
- }
-};
-
-}
-
#endif // utils_hh_INCLUDED
diff --git a/src/value.hh b/src/value.hh
index 86bbfea2..e663513a 100644
--- a/src/value.hh
+++ b/src/value.hh
@@ -1,11 +1,11 @@
#ifndef value_hh_INCLUDED
#define value_hh_INCLUDED
-#include <memory>
-#include <unordered_map>
-
+#include "unordered_map.hh"
#include "units.hh"
+#include <memory>
+
namespace Kakoune
{
@@ -76,23 +76,10 @@ struct ValueId : public StronglyTypedNumber<ValueId, int>
}
};
-using ValueMap = std::unordered_map<ValueId, Value>;
+inline size_t hash_value(ValueId val) { return hash_value((int)val); }
-}
-
-namespace std
-{
-
-template<>
-struct hash<Kakoune::ValueId>
-{
- size_t operator()(Kakoune::ValueId val) const
- {
- return std::hash<int>()((int)val);
- }
-};
+using ValueMap = UnorderedMap<ValueId, Value>;
}
-
#endif // value_hh_INCLUDED
diff --git a/src/word_db.hh b/src/word_db.hh
index 999d03b0..1e9e4318 100644
--- a/src/word_db.hh
+++ b/src/word_db.hh
@@ -28,7 +28,7 @@ public:
UsedChars letters;
int refcount;
};
- using WordList = std::unordered_map<InternedString, WordInfo>;
+ using WordList = UnorderedMap<InternedString, WordInfo>;
private:
using LineToWords = std::vector<std::vector<InternedString>>;