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:
parent
dbd7bd41bb
commit
ebecd60eb8
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
23
src/color.hh
23
src/color.hh
|
@ -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
|
||||||
|
|
|
@ -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 = {
|
||||||
{ '(', ')' }, { '[', ']' }, { '{', '}' }, { '<', '>' }
|
{ '(', ')' }, { '[', ']' }, { '{', '}' }, { '<', '>' }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
16
src/coord.hh
16
src/coord.hh
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
68
src/hash.cc
Normal 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
57
src/hash.hh
Normal 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
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
18
src/keys.hh
18
src/keys.hh
|
@ -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
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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, '\\');
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
17
src/unordered_map.hh
Normal 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
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
17
src/utils.hh
17
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
|
#endif // utils_hh_INCLUDED
|
||||||
|
|
25
src/value.hh
25
src/value.hh
|
@ -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
|
||||||
|
|
|
@ -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>>;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user