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
|