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.
This commit is contained in:
Maxime Coste 2014-12-16 18:57:19 +00:00
parent dbd7bd41bb
commit ebecd60eb8
31 changed files with 240 additions and 214 deletions

View File

@ -3,8 +3,7 @@
#include "safe_ptr.hh" #include "safe_ptr.hh"
#include "string.hh" #include "string.hh"
#include "unordered_map.hh"
#include <unordered_map>
namespace Kakoune namespace Kakoune
{ {
@ -24,7 +23,7 @@ private:
AliasRegistry() {} AliasRegistry() {}
safe_ptr<AliasRegistry> m_parent; safe_ptr<AliasRegistry> m_parent;
std::unordered_map<String, String> m_aliases; UnorderedMap<String, String> m_aliases;
}; };
} }

View File

@ -1,6 +1,8 @@
#ifndef color_hh_INCLUDED #ifndef color_hh_INCLUDED
#define color_hh_INCLUDED #define color_hh_INCLUDED
#include "hash.hh"
namespace Kakoune namespace Kakoune
{ {
@ -32,13 +34,19 @@ struct Color
Color(Colors c) : color{c}, r{0}, g{0}, b{0} {} Color(Colors c) : color{c}, r{0}, g{0}, b{0} {}
Color(unsigned char r, unsigned char g, unsigned char b) Color(unsigned char r, unsigned char g, unsigned char b)
: color{Colors::RGB}, r{r}, g{g}, b{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); Color str_to_color(StringView color);
String color_to_str(Color 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); 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 #endif // color_hh_INCLUDED

View File

@ -189,7 +189,7 @@ Token parse_percent_token(StringView line, ByteCount& pos)
type_name + "'"}; type_name + "'"};
Token::Type type = token_type<throw_on_unterminated>(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 = {
{ '(', ')' }, { '[', ']' }, { '{', '}' }, { '<', '>' } { '(', ')' }, { '[', ']' }, { '{', '}' }, { '<', '>' }
}; };

View File

@ -9,8 +9,8 @@
#include "parameters_parser.hh" #include "parameters_parser.hh"
#include "string.hh" #include "string.hh"
#include "utils.hh" #include "utils.hh"
#include "unordered_map.hh"
#include <unordered_map>
#include <functional> #include <functional>
#include <initializer_list> #include <initializer_list>
@ -88,7 +88,7 @@ private:
CommandFlags flags; CommandFlags flags;
CommandCompleter completer; CommandCompleter completer;
}; };
using CommandMap = std::unordered_map<String, CommandDescriptor>; using CommandMap = UnorderedMap<String, CommandDescriptor>;
CommandMap m_commands; CommandMap m_commands;
CommandMap::const_iterator find_command(const Context& context, CommandMap::const_iterator find_command(const Context& context,

View File

@ -2,6 +2,7 @@
#define coord_hh_INCLUDED #define coord_hh_INCLUDED
#include "units.hh" #include "units.hh"
#include "hash.hh"
namespace Kakoune namespace Kakoune
{ {
@ -92,6 +93,11 @@ struct ByteCoord : LineAndColumn<ByteCoord, LineCount, ByteCount>
: LineAndColumn(line, column) {} : LineAndColumn(line, column) {}
}; };
inline size_t hash_value(const ByteCoord& val)
{
return hash_values(val.line, val.column);
}
struct CharCoord : LineAndColumn<CharCoord, LineCount, CharCount> struct CharCoord : LineAndColumn<CharCoord, LineCount, CharCount>
{ {
[[gnu::always_inline]] [[gnu::always_inline]]
@ -99,6 +105,11 @@ struct CharCoord : LineAndColumn<CharCoord, LineCount, CharCount>
: LineAndColumn(line, column) {} : LineAndColumn(line, column) {}
}; };
inline size_t hash_value(const CharCoord& val)
{
return hash_values(val.line, val.column);
}
struct ByteCoordAndTarget : ByteCoord struct ByteCoordAndTarget : ByteCoord
{ {
[[gnu::always_inline]] [[gnu::always_inline]]
@ -112,6 +123,11 @@ struct ByteCoordAndTarget : ByteCoord
CharCount target; CharCount target;
}; };
inline size_t hash_value(const ByteCoordAndTarget& val)
{
return hash_values(val.line, val.column, val.target);
}
} }
#endif // coord_hh_INCLUDED #endif // coord_hh_INCLUDED

View File

@ -1,13 +1,13 @@
#ifndef env_vars_hh_INCLUDED #ifndef env_vars_hh_INCLUDED
#define env_vars_hh_INCLUDED #define env_vars_hh_INCLUDED
#include <unordered_map> #include "unordered_map.hh"
namespace Kakoune namespace Kakoune
{ {
class String; class String;
using EnvVarMap = std::unordered_map<String, String>; using EnvVarMap = UnorderedMap<String, String>;
EnvVarMap get_env_vars(); EnvVarMap get_env_vars();

View File

@ -4,8 +4,7 @@
#include "face.hh" #include "face.hh"
#include "utils.hh" #include "utils.hh"
#include "completion.hh" #include "completion.hh"
#include "unordered_map.hh"
#include <unordered_map>
namespace Kakoune namespace Kakoune
{ {
@ -30,7 +29,7 @@ private:
FaceOrAlias(Face face = Face{}) : face(face) {} 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) inline Face get_face(const String& facedesc)

View File

@ -356,7 +356,7 @@ std::vector<String> complete_command(StringView prefix, ByteCount cursor_pos)
TimeSpec mtime = {}; TimeSpec mtime = {};
std::vector<String> commands; std::vector<String> commands;
}; };
static std::unordered_map<String, CommandCache> command_cache; static UnorderedMap<String, CommandCache> command_cache;
std::vector<StringView> path; std::vector<StringView> path;
if (dir_end != -1) if (dir_end != -1)

68
src/hash.cc Normal file
View File

@ -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;
}
}

57
src/hash.hh Normal file
View File

@ -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

View File

@ -9,22 +9,6 @@
#include <functional> #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 namespace Kakoune
{ {

View File

@ -1017,7 +1017,7 @@ private:
{ {
size_t timestamp = 0; size_t timestamp = 0;
std::vector<RegionMatches> matches; std::vector<RegionMatches> matches;
std::unordered_map<BufferRange, RegionList> regions; UnorderedMap<BufferRange, RegionList> regions;
}; };
BufferSideCache<Cache> m_cache; BufferSideCache<Cache> m_cache;

View File

@ -2,8 +2,7 @@
#define hook_manager_hh_INCLUDED #define hook_manager_hh_INCLUDED
#include "id_map.hh" #include "id_map.hh"
#include "unordered_map.hh"
#include <unordered_map>
namespace Kakoune namespace Kakoune
{ {
@ -29,7 +28,7 @@ private:
friend class Scope; friend class Scope;
HookManager* m_parent; HookManager* m_parent;
std::unordered_map<String, id_map<HookFunc>> m_hook; UnorderedMap<String, id_map<HookFunc>> m_hook;
}; };
} }

View File

@ -9,12 +9,11 @@
#include "normal.hh" #include "normal.hh"
#include "regex.hh" #include "regex.hh"
#include "register_manager.hh" #include "register_manager.hh"
#include "unordered_map.hh"
#include "user_interface.hh" #include "user_interface.hh"
#include "utf8.hh" #include "utf8.hh"
#include "window.hh" #include "window.hh"
#include <unordered_map>
namespace Kakoune namespace Kakoune
{ {
@ -736,10 +735,10 @@ private:
bool m_autoshowcompl; bool m_autoshowcompl;
Mode m_mode = Mode::Default; 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::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 class NextKey : public InputMode
{ {

View File

@ -3,8 +3,7 @@
#include "string.hh" #include "string.hh"
#include "utils.hh" #include "utils.hh"
#include "unordered_map.hh"
#include <unordered_map>
namespace Kakoune namespace Kakoune
{ {
@ -20,7 +19,7 @@ private:
void acquire(size_t slot); void acquire(size_t slot);
void release(size_t slot) noexcept; 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; std::vector<size_t> m_free_slots;
using DataAndRefCount = std::pair<std::vector<char>, int>; using DataAndRefCount = std::pair<std::vector<char>, int>;
std::vector<DataAndRefCount> m_storage; std::vector<DataAndRefCount> m_storage;
@ -118,18 +117,11 @@ private:
size_t m_slot = -1; 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 #endif // interned_string_hh_INCLUDED

View File

@ -1,19 +1,7 @@
#include "keymap_manager.hh" #include "keymap_manager.hh"
#include "memoryview.hh" #include "memoryview.hh"
#include "assert.hh"
namespace std
{
template<> struct hash<Kakoune::KeymapMode>
{
size_t operator()(Kakoune::KeymapMode val) const
{
return hash<int>{}((int)val);
}
};
}
namespace Kakoune namespace Kakoune
{ {

View File

@ -2,9 +2,9 @@
#define keymap_manager_hh_INCLUDED #define keymap_manager_hh_INCLUDED
#include "keys.hh" #include "keys.hh"
#include "utils.hh" #include "hash.hh"
#include "unordered_map.hh"
#include <unordered_map>
#include <vector> #include <vector>
namespace Kakoune namespace Kakoune
@ -43,7 +43,8 @@ private:
KeymapManager* m_parent; KeymapManager* m_parent;
using KeyList = std::vector<Key>; 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; Keymap m_mapping;
}; };

View File

@ -3,6 +3,7 @@
#include "unicode.hh" #include "unicode.hh"
#include "flags.hh" #include "flags.hh"
#include "hash.hh"
#include <vector> #include <vector>
@ -11,7 +12,7 @@ namespace Kakoune
struct Key struct Key
{ {
enum class Modifiers enum class Modifiers : int
{ {
None = 0, None = 0,
Control = 1 << 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 ctrl(Codepoint key) { return { Key::Modifiers::Control, key }; }
constexpr Key ctrlalt(Codepoint key) { return { Key::Modifiers::ControlAlt, key }; } constexpr Key ctrlalt(Codepoint key) { return { Key::Modifiers::ControlAlt, key }; }
} inline size_t hash_value(const Key& key) { return hash_values(key.modifiers, key.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;
}
};
} }
#endif // keys_hh_INCLUDED #endif // keys_hh_INCLUDED

View File

@ -166,7 +166,7 @@ static int nc_color(Color color)
static int get_color_pair(const Face& face) static int get_color_pair(const Face& face)
{ {
using ColorPair = std::pair<Color, Color>; using ColorPair = std::pair<Color, Color>;
static std::map<ColorPair, int> colorpairs; static UnorderedMap<ColorPair, int> colorpairs;
static int next_pair = 1; static int next_pair = 1;
ColorPair colors{face.fg, face.bg}; ColorPair colors{face.fg, face.bg};

View File

@ -2,9 +2,9 @@
#define normal_hh_INCLUDED #define normal_hh_INCLUDED
#include "keys.hh" #include "keys.hh"
#include "unordered_map.hh"
#include <functional> #include <functional>
#include <unordered_map>
namespace Kakoune namespace Kakoune
{ {
@ -23,7 +23,7 @@ struct NormalCmdDesc
std::function<void (Context& context, NormalParams params)> func; std::function<void (Context& context, NormalParams params)> func;
}; };
using KeyMap = std::unordered_map<Key, NormalCmdDesc>; using KeyMap = UnorderedMap<Key, NormalCmdDesc>;
extern KeyMap keymap; extern KeyMap keymap;
} }

View File

@ -6,10 +6,10 @@
#include "units.hh" #include "units.hh"
#include "coord.hh" #include "coord.hh"
#include "memoryview.hh" #include "memoryview.hh"
#include "unordered_map.hh"
#include <tuple> #include <tuple>
#include <vector> #include <vector>
#include <unordered_map>
namespace Kakoune namespace Kakoune
{ {
@ -68,7 +68,7 @@ bool option_add(std::vector<T>& opt, const std::vector<T>& vec)
} }
template<typename Key, typename Value> 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; String res;
for (auto it = begin(opt); it != end(opt); ++it) 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> 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(); opt.clear();
std::vector<String> elems = split(str, list_separator, '\\'); std::vector<String> elems = split(str, list_separator, '\\');

View File

@ -3,8 +3,8 @@
#include "register.hh" #include "register.hh"
#include "utils.hh" #include "utils.hh"
#include "unordered_map.hh"
#include <unordered_map>
#include <vector> #include <vector>
#include <functional> #include <functional>
@ -21,7 +21,7 @@ public:
void register_dynamic_register(char reg, RegisterRetriever function); void register_dynamic_register(char reg, RegisterRetriever function);
protected: protected:
std::unordered_map<char, std::unique_ptr<Register>> m_registers; UnorderedMap<char, std::unique_ptr<Register>> m_registers;
}; };
} }

View File

@ -82,7 +82,7 @@ public:
} }
template<typename Key, typename Val> 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()); write<uint32_t>(map.size());
for (auto& val : map) for (auto& val : map)
@ -230,10 +230,10 @@ DisplayBuffer read<DisplayBuffer>(int socket)
} }
template<typename Key, typename Val> 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); uint32_t size = read<uint32_t>(socket);
std::unordered_map<Key, Val> res; UnorderedMap<Key, Val> res;
while (size--) while (size--)
{ {
auto key = read<Key>(socket); auto key = read<Key>(socket);

View File

@ -173,64 +173,4 @@ std::vector<StringView> wrap_lines(StringView text, CharCount max_width)
return lines; 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;
}
} }

View File

@ -3,6 +3,7 @@
#include "units.hh" #include "units.hh"
#include "utf8.hh" #include "utf8.hh"
#include "hash.hh"
#include <string> #include <string>
#include <climits> #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); 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<> return hash_data(str.data(), (int)str.length());
struct hash<Kakoune::String> : hash<std::string> }
{
size_t operator()(const Kakoune::String& str) const
{
return hash<std::string>::operator()(str);
}
};
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 #endif // string_hh_INCLUDED

View File

@ -1,6 +1,8 @@
#ifndef units_hh_INCLUDED #ifndef units_hh_INCLUDED
#define units_hh_INCLUDED #define units_hh_INCLUDED
#include "hash.hh"
#include <type_traits> #include <type_traits>
namespace Kakoune namespace Kakoune
@ -119,6 +121,8 @@ struct LineCount : public StronglyTypedNumber<LineCount, int>
constexpr LineCount(int value = 0) : StronglyTypedNumber<LineCount>(value) {} constexpr LineCount(int value = 0) : StronglyTypedNumber<LineCount>(value) {}
}; };
inline size_t hash_value(LineCount val) { return hash_value((int)val); }
[[gnu::always_inline]] [[gnu::always_inline]]
inline constexpr LineCount operator"" _line(unsigned long long int value) 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) {} constexpr ByteCount(int value = 0) : StronglyTypedNumber<ByteCount>(value) {}
}; };
inline size_t hash_value(ByteCount val) { return hash_value((int)val); }
[[gnu::always_inline]] [[gnu::always_inline]]
inline constexpr ByteCount operator"" _byte(unsigned long long int value) 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); return CharCount(value);
} }
inline size_t hash_value(CharCount val) { return hash_value((int)val); }
} }
#endif // units_hh_INCLUDED #endif // units_hh_INCLUDED

17
src/unordered_map.hh Normal file
View File

@ -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

View File

@ -2,9 +2,9 @@
#define user_interface_hh_INCLUDED #define user_interface_hh_INCLUDED
#include "safe_ptr.hh" #include "safe_ptr.hh"
#include "unordered_map.hh"
#include <functional> #include <functional>
#include <unordered_map>
namespace Kakoune namespace Kakoune
{ {
@ -63,7 +63,7 @@ public:
virtual void set_input_callback(InputCallback callback) = 0; 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; virtual void set_ui_options(const Options& options) = 0;
}; };

View File

@ -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 #endif // utils_hh_INCLUDED

View File

@ -1,11 +1,11 @@
#ifndef value_hh_INCLUDED #ifndef value_hh_INCLUDED
#define value_hh_INCLUDED #define value_hh_INCLUDED
#include <memory> #include "unordered_map.hh"
#include <unordered_map>
#include "units.hh" #include "units.hh"
#include <memory>
namespace Kakoune 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); }
using ValueMap = UnorderedMap<ValueId, Value>;
} }
namespace std
{
template<>
struct hash<Kakoune::ValueId>
{
size_t operator()(Kakoune::ValueId val) const
{
return std::hash<int>()((int)val);
}
};
}
#endif // value_hh_INCLUDED #endif // value_hh_INCLUDED

View File

@ -28,7 +28,7 @@ public:
UsedChars letters; UsedChars letters;
int refcount; int refcount;
}; };
using WordList = std::unordered_map<InternedString, WordInfo>; using WordList = UnorderedMap<InternedString, WordInfo>;
private: private:
using LineToWords = std::vector<std::vector<InternedString>>; using LineToWords = std::vector<std::vector<InternedString>>;