axmol/core/base/hlookup.h

65 lines
2.0 KiB
C
Raw Normal View History

2021-12-28 18:10:22 +08:00
// Heterogeneous lookup support on c++17 with robin_hash
2021-12-26 23:26:34 +08:00
// C++20 demo: Heterogeneous lookup for unordered containers (transparent hashing)
// https://en.cppreference.com/w/cpp/container/unordered_map/find
#pragma once
#include <string>
#include <string_view>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
2021-12-28 17:59:44 +08:00
#include <utility>
2021-12-26 23:26:34 +08:00
#include "tsl/robin_map.h"
#include "tsl/robin_set.h"
using namespace std::string_literals;
using namespace std::string_view_literals;
namespace hlookup
{
struct string_hash
{
using hash_type = std::hash<std::string_view>;
using is_transparent = void;
size_t operator()(const char* str) const { return hash_type{}(str); }
size_t operator()(std::string_view str) const { return hash_type{}(str); }
2021-12-27 13:52:08 +08:00
size_t operator()(const std::string& str) const { return hash_type{}(str); }
2021-12-26 23:26:34 +08:00
};
struct equal_to
{
template <class _Ty1, class _Ty2>
constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
noexcept(noexcept(static_cast<_Ty1&&>(_Left) == static_cast<_Ty2&&>(_Right))) // strengthened
-> decltype(static_cast<_Ty1&&>(_Left) == static_cast<_Ty2&&>(_Right))
{
return static_cast<_Ty1&&>(_Left) == static_cast<_Ty2&&>(_Right);
}
2021-12-29 11:25:42 +08:00
using is_transparent = void;
2021-12-26 23:26:34 +08:00
};
template <typename _Valty>
using stl_string_map = std::map<std::string, _Valty, std::less<>>;
using stl_string_set = std::set<std::string, std::less<>>;
template <typename _Valty>
using string_map = tsl::robin_map<std::string, _Valty, string_hash, equal_to>;
using string_set = tsl::robin_set<std::string, string_hash, equal_to>;
template <typename _Cont, typename _Valty>
2021-12-28 17:59:44 +08:00
inline auto set_item(_Cont& cont, std::string_view k, _Valty&& v)
2021-12-26 23:26:34 +08:00
{
2021-12-28 17:59:44 +08:00
typename _Cont::iterator it = cont.find(k);
2021-12-26 23:26:34 +08:00
if (it != cont.end())
2021-12-28 17:59:44 +08:00
it->second = std::forward<_Valty>(v);
2021-12-26 23:26:34 +08:00
else
2021-12-28 18:10:22 +08:00
it = cont.emplace(k, std::forward<_Valty>(v)).first;
2021-12-26 23:26:34 +08:00
return it;
}
constexpr auto empty_sv = ""sv;
} // namespace hlookup