5#include <unordered_map>
6#include <unordered_set>
8#if __cpp_lib_generic_unordered_lookup < 201811L
9#include <boost/unordered_map.hpp>
10#include <boost/unordered_set.hpp>
13USERVER_NAMESPACE_BEGIN
15namespace utils::impl {
17template <
typename Key>
18struct TransparentHash :
public std::hash<std::string_view> {
19 static_assert(std::is_convertible_v<Key, std::string_view>,
20 "TransparentHash is only implemented for strings for far");
22 using is_transparent [[maybe_unused]] =
void;
29#if __cpp_lib_generic_unordered_lookup >= 201811L
30template <
typename Key,
typename Value,
typename Hash = TransparentHash<Key>,
31 typename Equal = std::equal_to<>>
32using TransparentMap = std::unordered_map<Key, Value, Hash, Equal>;
34template <
typename Key,
typename Hash = TransparentHash<Key>,
35 typename Equal = std::equal_to<>>
36using TransparentSet = std::unordered_set<Key, Hash, Equal>;
38template <
typename Key,
typename Value,
typename Hash = TransparentHash<Key>,
39 typename Equal = std::equal_to<>>
40using TransparentMap = boost::unordered_map<Key, Value, Hash, Equal>;
42template <
typename Key,
typename Hash = TransparentHash<Key>,
43 typename Equal = std::equal_to<>>
44using TransparentSet = boost::unordered_set<Key, Hash, Equal>;
47template <
typename TransparentContainer,
typename Key>
48auto FindTransparent(TransparentContainer&& container,
const Key& key) {
49 static_assert(!std::is_rvalue_reference_v<TransparentContainer>,
"Dangling");
50#if __cpp_lib_generic_unordered_lookup >= 201811L
51 return container.find(key);
53 return container.find(key, container.hash_function(), container.key_eq());
57template <
typename TransparentMap,
typename Key>
58auto* FindTransparentOrNullptr(TransparentMap&& map,
const Key& key) {
59 static_assert(!std::is_rvalue_reference_v<TransparentMap>,
"Dangling");
60 const auto iterator = FindTransparent(map, key);
61 return iterator == map.end() ?
nullptr : &iterator->second;
64template <
typename TransparentMap,
typename Key,
typename Value>
65void TransparentInsertOrAssign(TransparentMap& map, Key&& key, Value&& value) {
66 using StoredKey =
typename TransparentMap::key_type;
68 std::conditional_t<std::is_same_v<std::decay_t<Key>, StoredKey>, Key&&,
70#if __cpp_lib_generic_unordered_lookup >= 201811L
73 map.insert_or_assign(
static_cast<ForwardedKey>(key),
74 std::forward<Value>(value));
76 const auto iterator = map.find(key, map.hash_function(), map.key_eq());
77 if (iterator != map.end()) {
78 iterator->second = std::forward<Value>(value);
81 map.emplace(
static_cast<ForwardedKey>(key), std::forward<Value>(value));